Product
Introducing SSO
Streamline your login process and enhance security by enabling Single Sign-On (SSO) on the Socket platform, now available for all customers on the Enterprise plan, supporting 20+ identity providers.
react-network-canvas
Advanced tools
Readme
This react component provides a visual canvas and api for creating, editing, importing and exporting directed network graphs.
Network diagrams are useful for modeling things such as audio synthesis, execution flow, render pipelines, scene graphs, data transformations, and many others.
This component aspires to be completely themeable and customizable in behavior and styles, but this is an ongoing effort.
Install with yarn
yarn add react-network-canvas
Install with NPM
npm install react-network-canvas
Render in application
import React from "react";
import { NetworkCanvas } from "react-network-canvas";
function MyApp() {
return (
<NetworkCanvas
nodes={nodes}
edges={edges}
theme={theme}
callbacks={callbacks}
options={options}
/>
);
}
export { MyApp };
import React from "react";
import ReactDOM from "react-dom";
import { createElement } from "react";
import { v1 as generateUuid } from "uuid";
import { NetworkCanvas } from "react-network-canvas";
import { nodes, edges } from "./graph.json";
function App() {
const callbacks = {
onClickCanvas(event, position, graphManager) {
// create node at click position
const node = graphManager.createNode({
position,
inputPorts: [{ id: generateUuid() }],
outputPorts: [{ id: generateUuid() }, { id: generateUuid() }],
});
// select the newly created node
graphManager.selectedNodeIds = [node.id];
},
onClickPort(event, port, parentNode, graphManager) {
// create a connected node...
},
onKeyPress(event, key, graphManager) {
if (key === "Backspace" && graphManager.selectedNodeIds.length > 0) {
// delete selected nodes
graphManager.removeNodesByIds(graphManager.selectedNodeIds);
}
},
};
const options = {
gridSize: 20,
zoomWheelKey: "Shift",
selectBoxKey: "Shift",
isSnapToGridEnabled: true,
};
return (
<NetworkCanvas
nodes={nodes}
edges={edges}
callbacks={callbacks}
options={options}
/>
);
}
ReactDOM.render(createElement(App), document.getElementById("app"));
{
"nodes": [
{
"id": "504f852d-5b78-4f64-bd71-ab7f7f5dfb03",
"data": {
"foo": "bar"
},
"position": {
"x": 100,
"y": 100
},
"inputPorts": [
{
"id": "02fa1df9-7187-4b85-ad00-6b14a1317cda"
}
],
"outputPorts": [
{
"id": "b09c894d-332f-4f16-843c-4bc42681972b"
},
{
"id": "37a08870-8f72-4724-b8d2-206c211a2787"
}
]
},
{
"id": "b832f63f-0c6a-4977-8bb1-581f1c6cc1cb",
"data": {
"foo": "bar"
},
"position": {
"x": 300,
"y": 100
},
"inputPorts": [
{
"id": "63f48da0-6495-4268-a55f-03f83af70720"
}
],
"outputPorts": [
{
"id": "793bd3a5-5b7e-407c-afcd-758592c702c8"
},
{
"id": "12d89e19-dc5f-40af-a3e2-50637e2f9b62"
}
]
},
{
"id": "1c973de3-b2b8-49cc-843c-39a600843ec2",
"data": {
"foo": "bar"
},
"position": {
"x": 300,
"y": 200
},
"inputPorts": [
{
"id": "b2ab0321-00a9-4be8-b5d5-a51cce615b4f"
}
],
"outputPorts": [
{
"id": "7fe5c462-062f-4bfe-bd7b-f191d9ed5e57"
},
{
"id": "2e817c94-2fae-4ea6-bfb8-503c6825f3c9"
}
]
}
],
"edges": [
{
"id": "548633a2-47e8-4774-9031-3fcde1bba2be",
"from": {
"nodeId": "504f852d-5b78-4f64-bd71-ab7f7f5dfb03",
"portId": "b09c894d-332f-4f16-843c-4bc42681972b"
},
"to": {
"nodeId": "b832f63f-0c6a-4977-8bb1-581f1c6cc1cb",
"portId": "63f48da0-6495-4268-a55f-03f83af70720"
}
},
{
"id": "60122c7b-698c-443c-a29c-d80f5aba2837",
"from": {
"nodeId": "504f852d-5b78-4f64-bd71-ab7f7f5dfb03",
"portId": "37a08870-8f72-4724-b8d2-206c211a2787"
},
"to": {
"nodeId": "1c973de3-b2b8-49cc-843c-39a600843ec2",
"portId": "b2ab0321-00a9-4be8-b5d5-a51cce615b4f"
}
}
]
}
interface Props {
nodes: Types.Node[];
edges: Types.Edge[];
callbacks?: Types.Bridge;
options?: Types.Options;
theme?: any;
}
interface Options {
gridSize: number;
canvasSize: number;
isSnapToGridEnabled: boolean;
startAtCanvasCenter: boolean;
canvasMargin: number;
zoomSensitivity: number;
initialPanOffset: Types.Position;
selectBoxKey?: "Shift" | "Control" | "Alt" | "Meta";
zoomWheelKey?: "Shift" | "Control" | "Alt" | "Meta";
maxZoom: number;
minZoom: number;
NodeComponent: ReactComponent;
PortComponent: ReactComponent;
}
const DEFAULT_OPTIONS: Types.Options = {
gridSize: 10,
canvasSize: 2000,
isSnapToGridEnabled: false,
startAtCanvasCenter: true,
canvasMargin: 50,
initialPanOffset: { x: 50, y: 50 },
zoomSensitivity: 0.001,
zoomWheelKey: undefined,
selectBoxKey: "Shift",
maxZoom: Infinity,
minZoom: 0,
NodeComponent,
PortComponent,
};
const DEFAULT_THEME = {
workspace: {
backgroundSize: "",
backgroundImage: "",
backgroundColor: "#f6f6f6",
},
canvas: {
borderRadius: "5px",
boxShadow: "0 0 0 1px lightgrey",
backgroundColor: "white",
backgroundSize: "var(--NC-grid-size) var(--NC-grid-size)",
backgroundImage:
"radial-gradient(lightgray, lightgray 1px, transparent 1px)",
backgroundPosition: "50% 50%",
},
selectbox: {
backgroundColor: "rgba(100, 148, 237, 0.25)",
boxShadow: "0 0 0 1px cornflowerblue",
},
edge: {
stroke: "black",
strokeWidth: "3px",
hover: {
stroke: "red",
},
draft: {
stroke: "black",
},
},
};
interface Bridge {
connect(graphManager: Types.GraphManager): void;
onChangeZoom(zoom: number): void;
onMutateGraph(graphEvent: GraphEvent): void;
onClickCanvas(
event: React.SyntheticEvent,
position: Types.Position,
graphManager: Types.GraphManager
): void;
onClickNode(
event: React.SyntheticEvent,
node: Types.Node,
graphManager: Types.GraphManager
): void;
onClickPort(
event: React.SyntheticEvent,
port: Types.Port,
node: Types.Node,
graphManager: Types.GraphManager
): void;
onDropCanvas(
event: React.SyntheticEvent,
position: Types.Position,
graphManager: Types.GraphManager
): void;
onChangeSelectedNodeIds(
selectedNodesIds: string[],
graphManager: Types.GraphManager
): void;
onKeyPress(
event: React.SyntheticEvent,
key: string,
graphManager: Types.GraphManager
): void;
}
interface GraphManager {
nodes: Types.Node[];
edges: Types.Edge[];
callbacks: Types.Bridge;
workspace: Types.Workspace | undefined;
dragManager: Types.DragManager;
selectedNodeIds: string[];
getNodeById(id: string): Types.Node;
getNodesByEdgeId(id: string): { from?: Types.Node; to?: Types.Node };
createNode(nodeProps: Partial<Types.Node>): Types.Node | null;
removeNodeById(id: string): void;
removeNodesByIds(removedNodeIds: string[]): void;
subscribeToNodesChange(fn: () => void): void;
unsubscribeToNodesChange(fn: () => void): void;
handleDragMove(event, dragDelta: Types.Position, dragData: any): void;
handleDragEnd(event, dragDelta: Types.Position, dragData: any): void;
updateNodePositionById(id: string, dragDelta: Types.Position): void;
subscribeToDragDeltaById(id: string, fn: () => void): void;
unsubscribeToDragDeltaById(id: string, fn: () => void): void;
subscribeToNodePositionChangeById(id: string, fn: () => void): void;
unsubscribeToNodePositionChangeById(id: string, fn: () => void): void;
appendSelectedNodeId(id: string): void;
appendSelectedNodeIds(appendedNodeIds: string[]): void;
removeSelectedNodeId(id: string): void;
removeSelectedNodeIds(unselectedNodeIds: string[]): void;
subscribeToIsSelectedById(id: string, fn: () => void): void;
unsubscribeToIsSelectedById(id: string, fn: () => void): void;
getEdgeById(id: string): Types.Edge;
getEdgesByNodeId(id: string): Types.Edge[];
createEdge(edgeProps: Partial<Types.Edge>): Types.Edge | null;
removeEdgeById(id: string): void;
clearDraftEdgePath(): void;
updateDraftEdgePath(x1: number, y1: number, x2: number, y2: number): void;
subscribeToEdgesChange(id: string, fn: () => void): void;
unsubscribeToEdgesChange(id: string, fn: () => void): void;
import(graph: Types.Graph): void;
export(): Types.Graph;
}
interface Workspace {
setPan(position: Position | ((position: Position) => Position)): void;
setZoom(zoom: number | ((zoom: number) => number)): void;
container?: HTMLDivElement;
isSelectBoxKeyDown: boolean;
getElementDimensions(HTMLElement): { width: number; height: number };
getCanvasPosition(object: HTMLElement | DOMRect | MouseEvent): Position;
mountContextScreenOffset: Position;
panZoom: {
zoom: number;
} & Position;
}
FAQs
A themeable and customizable react component that provides a visual canvas and api for rendering, creating, editing, importing and exporting directed network graphs.
The npm package react-network-canvas receives a total of 17 weekly downloads. As such, react-network-canvas popularity was classified as not popular.
We found that react-network-canvas demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Streamline your login process and enhance security by enabling Single Sign-On (SSO) on the Socket platform, now available for all customers on the Enterprise plan, supporting 20+ identity providers.
Security News
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
Security News
As cyber threats become more autonomous, AI-powered defenses are crucial for businesses to stay ahead of attackers who can exploit software vulnerabilities at scale.