Skip to content

High-Density Canvas Grid Layout Visualizers for Multi-Node Network Operators #19

Description

@JamesEjembi

Problem Statement

System managers overseeing thousands of active validator nodes need a unified, comprehensive fleet overview. The current dashboard lists nodes in a paginated table (50 per page), requiring operators to click through 20+ pages to assess fleet health. This paginated approach makes it impossible to spot spatial patterns (e.g., a regional outage affecting a contiguous block of nodes) or to compare performance metrics across the fleet at a glance. A high-density canvas grid visualization is needed that renders all nodes as color-coded cells in a single view.

Technical Bounds & Invariants

  • Maximum fleet size: 10,000 nodes rendered simultaneously
  • Cell size: 12px x 12px with 2px gap (14px per cell pitch) — ~1,400 cells visible per viewport at 1920x1080
  • Color coding: 5 status levels (Active=green, Warning=yellow, Critical=red, Slashed=purple, Offline=gray)
  • Interaction: hover shows tooltip with node name + key metrics, click opens detail panel
  • Frame rate: 60 FPS during hover/scroll, 30 FPS during animated transitions (status change pulses)

Codebase Navigation Guide

  • Primary target: /src/components/dashboard/FleetCanvasGrid.tsx
  • Node data hook: /src/hooks/useFleetData.ts — returns FleetNode[] with id, status, metrics
  • Current (slow) table: /src/components/dashboard/NodeTable.tsx
  • Tooltip component: /src/components/shared/Tooltip.tsx

Step-by-Step Resolution Blueprint

  1. Build a <canvas>-based grid component using useRef for the canvas element and requestAnimationFrame for the render loop; initial render draws all 10,000 cells as filled rectangles using ctx.fillRect(x, y, 12, 12) with color determined by node status via a lookup map
  2. Implement an onMouseMove handler that: (a) converts mouse coordinates to cell indices via col = floor(mouseX / 14), row = floor(mouseY / 14), index = row * cols + col, (b) highlights the hovered cell by drawing a 2px white border around it (without clearing the full canvas — use ctx.clearRect only on the affected cell area), (c) shows a tooltip positioned near the cursor with the node's display name, status, and 3 key metrics (uptime %, stake, last attestation)
  3. Add a color legend below the grid showing the 5 status colors with labels and a count of nodes in each status; clicking a legend label filters the grid to show only nodes with that status
  4. Implement sort and group modes via a dropdown: (a) Sort by stake — lay out cells left-to-right, top-to-bottom sorted by stake amount (highest at top-left), (b) Group by data center — cells are arranged in horizontal bands separated by a 4px gap, each band labeled with the data center name, (c) Group by status — cells grouped by status, showing clusters of red/green/gray
  5. Add a requestAnimationFrame delta-time throttle: on each frame, check performance.now() - lastDraw > 16 (60 FPS target); if the JS thread is busy and frames are being skipped, reduce cell resolution by rendering every other cell (skip pattern) to maintain responsiveness
  6. Add a search input that filters nodes by name or ID; as the user types, animate non-matching cells with a fade-to-30%-opacity transition over 200ms using ctx.globalAlpha interpolation across frames
  7. Write a performance test using page.evaluate to: (a) render 10,000 nodes, (b) measure frame time via requestAnimationFrame callback timestamps for 100 frames, (c) assert p95 frame time < 16ms (60 FPS), (d) measure hover tooltip latency — assert < 5ms from mousemove to tooltip visible

Metadata

Metadata

Assignees

Labels

Complexity: HardcoreExtremely difficult, high-complexity engineering taskGrantFox OSSIssue tracked in GrantFox OSSLayer: UI-CoreCore UI layer architectural concernMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official CampaignType: Web3-IntegrationWeb3 wallet and blockchain integration issue

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions