Skip to content

filipTurk/NRG-Graphs

Repository files navigation

NRG Graphs

A WebGPU-based 2D graph rendering framework with a React/TypeScript demo UI.

The project renders large node-edge graphs in the browser and supports visual customization, interaction, filtering, layouts, clustering, and comparison with D3/Sigma.js.

Run

npm install
npm run dev

Renderer Usage

The renderer is exposed through the React wrapper:

import WebGPURenderer from "./components/renderer";

<WebGPURenderer
  graph={graph}
  options={options}
  onSelectionChange={setSelectedNodes}
  onEdgeSelectionChange={setSelectedEdges}
  onStats={setStats}
/>

The graph data is stored in Graphology. Nodes and edges can define attributes such as:

graph.addNode("apple", {
  x: 0,
  y: 0,
  label: "Apple",
  color: [1, 0.2, 0.2],
  size: 1.4,
  borderWidth: 0.15,
});

graph.addEdge("apple", "banana", {
  label: "related",
  color: [1, 1, 1],
  thickness: 0.08,
  style: "solid",
});

Renderer Options

Main renderer customization is controlled by GraphRendererOptions.

Appearance

{
  showEdges: true,
  showEdgeArrows: true,
  edgeStyle: "solid", // solid | dashed | dotted | curved

  nodeScale: 1,
  nodeOpacity: 1,
  edgeOpacity: 1,

  defaultNodeSize: 1,
  minNodeSize: 0.4,
  maxNodeSize: 3,
  defaultBorderWidth: 0.08,
  defaultBorderColor: [1, 1, 1],

  defaultEdgeColor: [1, 1, 1],
  defaultEdgeThickness: 0.04,

  antialias: true,
  alphaCoverage: true,
}

Interaction

{
  hoverEffects: true,
  clickSelects: true,
  edgeClickSelects: true,
  multiSelect: true,

  highlightConnectionsOnSelect: true,
  includeSecondNeighbors: false,

  dragToPan: true,
  dragToMoveNodes: true,

  zoomSpeed: 1.1,
  minZoom: 0.05,
  maxZoom: 40,
  hitTestRadius: 12,

  stateScales: {
    hovered: 1.25,
    selected: 1.4,
    dimmed: 0.85,
  },
  stateOpacity: {
    default: 1,
    selected: 1,
    dimmed: 0.18,
    hidden: 0,
  },
}

edgeClickSelects enables click selection for edges (including multi-select with Ctrl/Cmd).

Labels

{
  showLabels: true,
  showNodeLabels: true,
  showEdgeLabels: false,
}

Labels are drawn as a canvas overlay and are limited by zoom and graph size to avoid clutter.

Performance

{
  maxNodes: 100000,
  maxEdges: 100000,

  dynamicNodeSizing: true,
  dynamicNodeBasePx: 14,

  viewportCulling: true,
  edgeLODThreshold: 50000,
  edgeLODZoomFactor: 0.8,

  depthTest: false,
  batchSize: 50000,
  powerPreference: "high-performance",
}

Dynamic node sizing keeps nodes readable while zooming. Edge limits and edge LOD are important for very dense graphs because edges are usually the main rendering bottleneck.

Clustering

{
  autoGroupingOnZoomOut: false,

  clusterEnabled: true,
  clusterZoomThreshold: 1.25,
  clusterCellPx: 42,
  clusterMinNodes: 6,

  communityEnabled: true,
  communityZoomThreshold: 0.7,
  communityMinNodes: 20,
  communityShowInterEdges: true,
}

Spatial clustering groups nearby nodes. Community clustering groups connected nodes using graph structure.

Layouts

{
  layoutMode: "force", // none | grid | circular | community | force
  layoutAutoTune: true,

  layoutPadding: 1,
  layoutGridJitter: 0.08,

  layoutIterations: 250,
  layoutRepulsion: 0.03,
  layoutLinkDistance: 1.2,
  layoutLinkStrength: 0.02,
  layoutDamping: 0.86,
  layoutGravity: 0.002,
}

Layouts are currently CPU-computed. The force layout runs in a Web Worker so the UI stays responsive.

Demo UI

The UI wraps the renderer and makes the framework easier to test.

It provides:

  • Dataset selection: fruit graph, Reddit graph, generated graphs.
  • Layout controls: none, grid, circular, community, force.
  • Appearance controls: node size, node opacity, edge opacity, borders, labels, arrows, edge style, antialiasing.
  • Interaction controls: hover, selection, multi-select, neighbor highlighting, second-neighbor toggle, drag node, zoom speed, hit radius.
  • Edge selection controls: edge click selection toggle and selected edge count.
  • Performance controls: node/edge limits, edge LOD, dynamic sizing, clustering, culling, GPU preference.
  • Fit-to-view and graph stats.
  • Comparison mode for D3 SVG and Sigma.js WebGL.

Current Limits

The renderer handles around 100k nodes and 100k edges interactively on the tested machine. Larger graphs are possible, but dense edge rendering and CPU layout become the main bottlenecks.

For very large graphs, the most useful options are:

  • hide or limit edges,
  • enable edge LOD,
  • use clustering,
  • use a good layout before rendering,
  • keep dynamic node sizing enabled.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors