import { ForceDirectedGraph } from "semiotic"
ForceDirectedGraph visualizes network relationships by simulating physical forces that push and pull connected nodes into a stable layout. Pass your nodes and edges, optionally map color and size to data fields, and get an interactive network diagram with hover annotations and legends — all with sensible defaults.
Quick Start
The simplest force-directed graph requires just nodes and edges.
import { ForceDirectedGraph } from "semiotic" const frameProps = { /* --- Data --- */ nodes: [ { id: "Alice", group: "Engineering" }, { id: "Bob", group: "Engineering" }, { id: "Carol", group: "Design" }, // ...more nodes ], edges: [ { source: "Alice", target: "Bob" }, { source: "Alice", target: "Carol" }, // ...more edges ] } export default () => { return <ForceDirectedGraph {...frameProps} /> }
Examples
Colored by Group
Use colorBy to color nodes by a categorical field. A legend is displayed automatically when colorBy is set.
import { ForceDirectedGraph } from "semiotic" const frameProps = { /* --- Data --- */ nodes: nodeData, edges: edgeData, /* --- Customize --- */ colorBy: "group" } export default () => { return <ForceDirectedGraph {...frameProps} /> }
Dynamic Node Sizing
Map nodeSize to a data field and control the range with nodeSizeRange. Combined with colorBy and showLabels, this creates a rich overview of your network.
import { ForceDirectedGraph } from "semiotic" const frameProps = { /* --- Data --- */ nodes: [ { id: "Alice", group: "Engineering", connections: 3 }, { id: "Bob", group: "Engineering", connections: 3 }, // ...nodes with connections field ], edges: edgeData, /* --- Customize --- */ colorBy: "group", nodeSize: "connections", nodeSizeRange: [5, 20], showLabels: true, nodeLabel: "id" } export default () => { return <ForceDirectedGraph {...frameProps} /> }
Custom Force Strength
Adjust iterations and forceStrength to control the layout density. Lower force strength produces a looser, more spread-out graph.
import { ForceDirectedGraph } from "semiotic" const frameProps = { /* --- Data --- */ nodes: nodeData, edges: edgeData, /* --- Layout --- */ iterations: 500, forceStrength: 0.02, /* --- Customize --- */ colorBy: "group", edgeColor: "#ccc", edgeOpacity: 0.4 } export default () => { return <ForceDirectedGraph {...frameProps} /> }
Props
| Prop | Type | Required | Default | Description |
|---|
nodes | array | Yes | — | Array of node objects. Each node should have an id property. |
edges | array | Yes | — | Array of edge objects connecting nodes via source and target properties. |
nodeIDAccessor | string | function | — | "id" | Field name or function to access node IDs. |
sourceAccessor | string | function | — | "source" | Field name or function to access edge source IDs. |
targetAccessor | string | function | — | "target" | Field name or function to access edge target IDs. |
nodeLabel | string | function | — | — | Field name or function to determine node labels. |
colorBy | string | function | — | — | Field name or function to determine node color. |
colorScheme | string | array | — | "category10" | Color scheme name or custom colors array. |
nodeSize | number | string | function | — | 8 | Fixed size, field name, or function to determine node radius. |
nodeSizeRange | [number, number] | — | [5, 20] | Min and max radius for nodes when using dynamic sizing. |
edgeWidth | number | string | function | — | 1 | Fixed width, field name, or function to determine edge stroke width. |
edgeColor | string | — | "#999" | Stroke color applied to edges. |
edgeOpacity | number | — | 0.6 | Opacity applied to edges. |
iterations | number | — | 300 | Number of force simulation iterations. Higher values produce more stable layouts. |
forceStrength | number | — | 0.1 | Strength of the force simulation. Lower values create looser layouts. |
showLabels | boolean | — | false | Show text labels on each node. |
enableHover | boolean | — | true | Enable hover annotations on nodes. |
showLegend | boolean | — | true (when colorBy set) | Show a legend. Defaults to true when colorBy is specified. |
tooltip | object | function | — | — | Tooltip configuration or render function. |
width | number | — | 600 | Chart width in pixels. |
height | number | — | 600 | Chart height in pixels. |
margin | object | — | { top: 20, bottom: 20, left: 20, right: 20 } | Margin around the chart area. |
title | string | — | — | Chart title displayed at the top. |
frameProps | object | — | — | Additional StreamNetworkFrame props for advanced customization. Escape hatch to the full Frame API. |
Graduating to the Frame
When you need more control — custom node icons, complex interactions, or advanced force parameters — graduate to StreamNetworkFrame directly. Every ForceDirectedGraph is just a configured StreamNetworkFrame under the hood.
Chart (simple)
JSX
import { ForceDirectedGraph } from "semiotic" <ForceDirectedGraph nodes={networkNodes} edges={networkEdges} colorBy="group" nodeSize="connections" showLabels={true} nodeLabel="id" />
Frame (full control)
JSX
import { StreamNetworkFrame } from "semiotic" <StreamNetworkFrame nodes={networkNodes} edges={networkEdges} nodeIDAccessor="id" sourceAccessor="source" targetAccessor="target" networkType={{ type: "force", iterations: 300, edgeStrength: 0.1 }} nodeStyle={d => ({ fill: colorScale(d.group), r: sizeScale(d.connections) })} edgeStyle={{ stroke: "#999", opacity: 0.6 }} nodeLabels={d => d.id} hoverAnnotation={true} size={[600, 600]} />
The frameProps prop on ForceDirectedGraph lets you pass any StreamNetworkFrame prop without fully graduating:
JSX
// Use frameProps as an escape hatch <ForceDirectedGraph nodes={nodes} edges={edges} colorBy="group" frameProps={{ customNodeIcon: ({ d }) => ( <circle r={10} fill="gold" stroke="black" /> ), annotations: [ { type: "node", id: "Alice", label: "Key Person" } ] }} />
- ChordDiagram — circular layout for showing flow between entities
- SankeyDiagram — flow diagram showing magnitude of movement between nodes
- TreeDiagram — hierarchical layouts for tree-structured data
- StreamNetworkFrame — the underlying Frame with full control over every rendering detail
- Tooltips — custom tooltip content and positioning