Warren UI

Graph

Rotating 3D shell cluster network (deterministic layout).

SUPPLY CHAIN · 30INDEX EXPOSURE · 30REGULATORY · 30MARKETS · 30
Source
"use client"

import { GraphView } from "@/registry/warren/graph/graph"
import { GRAPH_CLUSTERS, GRAPH_EDGES, GRAPH_NODES } from "@/apps/docs/demo/data"

export default function GraphDemo() {
  return (
    <GraphView
      nodes={GRAPH_NODES}
      edges={GRAPH_EDGES}
      clusters={GRAPH_CLUSTERS}
      width={640}
      height={420}
    />
  )
}

Installation

npx shadcn@latest add https://warren.eduard3v.com/r/graph.json

Usage

import { GraphView } from "@/registry/warren/graph/graph"
<GraphView
  nodes={GRAPH_NODES}
  edges={GRAPH_EDGES}
  clusters={GRAPH_CLUSTERS}
  spinDurationS={24}
/>

GraphView places nodes on a spherical shell and draws edges between them. The clusters map assigns each cluster a tone; the turntable spins the sphere once per spinDurationS seconds when that prop is passed — omit it for a static render (the example above shows the static pose).

Deterministic layout

Placement is pure geometry, not force simulation: every cluster center is a fibonacci-sphere point, its members sit on the shell within ~0.55 rad of that center, and unclustered nodes interleave on the remaining fibonacci points. The same input always produces the same network — nothing jitters or reflows between renders.

Cluster pills

When showLabels is true (the default), node labels are replaced by one pill per cluster at its projected centroid: a 1px tone-stroked rect with a mono uppercase <CLUSTER NAME> · <count> label in the tone's text-grade token. Same-cluster edges render in the cluster tone; cross-cluster edges stay as hairlines. Pass highlightCluster to draw every touching edge at full tone.

Interaction

selectedNodeId draws a solid 2px success ring around the node. Passing onNodeClick makes nodes interactive — the SVG becomes keyboard-focusable with roving focus (arrow keys, Home/End, Enter/Space to select). Each node's focus target is a transparent <rect> hit target over the node (not the <g>), which keeps keyboard focus working in Safari and other engines that mishandle tabindex on SVG groups. draggable lets the pointer rotate the sphere, and selectionPopup renders a floating node-info popup next to the selection.

Drag & Selection

  • draggable — pointer-drag on the sphere background rotates it (horizontal = yaw, vertical = pitch, additive over any turntable spin).
  • onNodeClick — makes nodes interactive: click, or keyboard arrows + Enter when the SVG is focused.
  • selectedNodeId — marks a node with the pulsing green ring.
  • selectionPopup — floats a node-info card next to the selected node.
SUPPLY CHAIN · 30INDEX EXPOSURE · 30REGULATORY · 30MARKETS · 30
Source
"use client"

import { useState } from "react"
import { GRAPH_CLUSTERS, GRAPH_EDGES, GRAPH_NODES } from "@/apps/docs/demo/data"
import { GraphView } from "@/registry/warren/graph/graph"

export default function GraphDrag() {
  const [selected, setSelected] = useState<string | null>(null)
  return (
    <GraphView
      nodes={GRAPH_NODES}
      edges={GRAPH_EDGES}
      clusters={GRAPH_CLUSTERS}
      width={640}
      height={420}
      draggable
      selectionPopup
      selectedNodeId={selected ?? undefined}
      onNodeClick={setSelected}
    />
  )
}

API Reference

Prop

Type

GraphNode

Prop

Type

On this page