Improved the Transfer Graph demo in the brownie-viz webapp with node selection/pinning, edge highlighting, visibility filtering, and various rendering fixes.
- Pin/unpin nodes: Clicking a node "pins" it — hides all other nodes and edges except the pinned node and its direct neighbors. Clicking the same node or empty space unpins.
- Gold highlight for active nodes: Hovered or pinned nodes turn yellow/gold
(
1.0, 0.7, 0.15) to match the orange-gold edge highlight color. - Edge hiding on pin: When a node is pinned, non-connected edges are set to black (invisible with additive blending). Connected edges stay orange-gold.
- Hidden node offscreen trick: Hidden nodes are moved to
(1e7, 1e7, 1e7)in addition to being scaled to 0, to prevent bloom post-processing artifacts. - Stars color changed: Background star particles shifted from blue
(
#334466) to warm red (#664444) so they aren't confused with graph nodes.
- Nodes not restoring after unpin: Instance matrices were only updated when
visibleSetwas truthy. After unpin (visibleSetbecomes null), matrices stayed at scale 0. Fix: always update matrices regardless ofvisibleSet. computeBoundingSphere(): Called after every matrix update to keep the raycaster's bounding sphere current.
apps/brownie-viz/frontend/src/components/GraphView.tsx— All changes are in this file:GlowNodes(visibility, gold highlight, matrix restore),EdgeLines(pin-aware edge hiding),GraphScene(visibleSet computation, prop passing),Stars(color change).
125fb27brownie-viz: pin/unpin visibility, gold highlight for active nodes
Branch: eth-optimization (pushed to origin).
The user reported "isolated nodes" that couldn't be hovered. After debugging
(10x size + red color for isolated nodes, green for stars), these turned out to
be background Stars particles, not graph nodes. Stars are <points> with
<pointsMaterial> and have no pointer event handlers. Fix was cosmetic: changed
star color hue to red-ish so they're visually distinct from blue graph nodes.
The user explicitly rejected filtering out edgeless nodes (nodes in top-N by
volume but with no edges within the top-N set). These represent high-volume
wallets whose counterparties are all outside the top-N. The user wants them
visible and interactive. A change to graph.go that filtered them was reverted.
Hidden nodes use color (0,0,0) which adds nothing with AdditiveBlending,
plus scale 0 and position (1e7,1e7,1e7) for belt-and-suspenders invisibility.
This prevents bloom from picking up residual fragments.
Current: 2.0 + Math.pow(t, 0.5) * 10.0 where t is 0..1 on log(volume).
Was briefly changed to 4.0 + 8.0 for debugging but reverted since the
"unhittable nodes" were actually Stars particles, not small graph nodes.
- Backend: Go server reads brownie store, serves JSON APIs. Graph data is
lazily cached per token mint in
Server.graphCache.sliceGraph()cheaply extracts top-N from the precomputedrawGraph. - Frontend: React + Vite + Three.js via @react-three/fiber. InstancedMesh for nodes (additive-blended sprites), LineSegments for edges.
All callbacks passed into the R3F <Canvas> use useRef to avoid stale
closures (R3F uses a separate React reconciler). The pattern:
const hoverRef = useRef((idx, e) => {})
hoverRef.current = (idx, e) => { /* uses current state */ }
// Pass hoverRef into Canvas, call hoverRef.current insideHot module reload with React Three Fiber frequently breaks pointer events and scene state. Full page refresh is needed after code changes. This is a known limitation, not a bug in our code.
The GlowNodes component updates instance matrices and colors during React's
render phase (not in useEffect). This is technically not React-idiomatic but
works because R3F applies changes to Three.js objects. The matrices are
rewritten every render when visibleSet/activeNodeId/pinnedNodeId change.
eth-optimizationis current, pushed to origin, no pending uncommitted changes (aside from the stars color change andcomputeBoundingSpherefix which haven't been committed yet).