react-digraph vs reactflow
React Diagram Libraries
react-digraphreactflowSimilar Packages:

React Diagram Libraries

React diagram libraries are specialized tools designed to facilitate the creation and manipulation of graphical representations of data structures, workflows, or processes within React applications. These libraries provide components and utilities that enable developers to build interactive and visually appealing diagrams, flowcharts, or graphs, enhancing the user experience and making complex information more digestible. They often come with features such as drag-and-drop functionality, customizable nodes and edges, and support for various layouts, making them ideal for applications that require visual data representation.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
react-digraph3,1972,6472.22 MB913 years agoMIT
reactflow035,500184 kB1202 years agoMIT

Feature Comparison: react-digraph vs reactflow

Graph Representation

  • react-digraph:

    react-digraph is specifically designed for directed graphs, allowing developers to easily create and manipulate nodes and edges. It provides a clear structure for representing relationships, making it ideal for scenarios where the direction of connections is important, such as flowcharts or dependency graphs.

  • reactflow:

    reactflow supports a wider variety of graph types, including directed and undirected graphs, and allows for complex node structures. It provides flexibility in representing various data relationships and workflows, making it suitable for applications that require intricate visualizations.

Interactivity

  • react-digraph:

    react-digraph offers basic interactivity features such as node selection and edge creation. However, it may require additional customization for more advanced interactions, making it less suitable for highly interactive applications without extra development effort.

  • reactflow:

    reactflow excels in interactivity, providing built-in support for drag-and-drop functionality, node resizing, and customizable interactions. It allows users to manipulate the diagram directly, enhancing user engagement and providing a more dynamic experience.

Customization

  • react-digraph:

    react-digraph allows for some level of customization, including styling nodes and edges, but it may be limited compared to more robust libraries. Developers can modify basic styles, but complex customizations may require additional effort.

  • reactflow:

    reactflow offers extensive customization options, allowing developers to define custom node types, styles, and behaviors. This flexibility enables the creation of tailored diagrams that fit specific application needs, making it a powerful choice for developers looking to create unique visual representations.

Performance

  • react-digraph:

    react-digraph is lightweight and performs well for smaller graphs, but may face performance issues with larger datasets due to its simpler architecture. It is best suited for applications that do not require handling a large number of nodes and edges.

  • reactflow:

    reactflow is optimized for performance, capable of handling larger graphs efficiently. It includes features like virtualization and memoization to ensure smooth interactions even with complex diagrams, making it a better choice for applications with extensive data.

Learning Curve

  • react-digraph:

    react-digraph has a relatively gentle learning curve, making it accessible for developers who are new to diagramming libraries. Its straightforward API allows for quick implementation, but may lack advanced features for more complex use cases.

  • reactflow:

    reactflow has a steeper learning curve due to its extensive features and customization options. While it offers powerful capabilities, developers may need to invest more time in understanding its API and functionalities to fully leverage its potential.

How to Choose: react-digraph vs reactflow

  • react-digraph:

    Choose react-digraph if you need a library that focuses on directed graphs and offers a straightforward API for creating and managing graph structures. It is particularly useful for applications that require a clear representation of relationships and flows between entities, such as organizational charts or dependency graphs.

  • reactflow:

    Choose reactflow if you are looking for a more comprehensive solution that supports complex workflows and allows for extensive customization. It excels in scenarios where you need to create interactive flow diagrams with features like zooming, panning, and node manipulation, making it suitable for applications like process modeling or visual programming.

README for react-digraph

react-digraph

Demo

Overview

A React component which makes it easy to create a directed graph editor without implementing any of the SVG drawing or event handling logic.

Important v8.0.0 Information

Version 8.0.0 introduces multi-select nodes and edges using Ctrl-Shift-Mouse events (Cmd-Shift-mouse for Mac). This requires a breaking change. Instead of onSelectNode/Edge, you'll only provide one onSelect function callback and a selected object with { nodes: Map, and edges: Map } as the parameter format. The typings folder has the exact type definition for these attributes. When either edges or nodes are selected the onSelect function will fire with the object. You will have to handle all nodes and edges selected, or if there is only one then you will have to determine if it's a node or edge within the onSelect function.

To disable multi-select you can set allowMultiselect to false, which disables the Ctrl-Shift-mouse event, but we will still use the onSelect function. Both onSelectNode and onSelectEdge are deprecated.

Breaking changes:

  • onPasteSelected now accepts a SelectionT object for the first parameter
  • onPasteSelected now accepts an IPoint instead of a XYCoords array for the second parameter.
  • onDeleteSelected is added which takes a SelectionT parameter.
  • onSelect is added, which accepts SelectionT and Event parameters.
  • onUpdateNode accepts a Map of updated nodes in the second parameter (for example, if multiple nodes are moved).
  • selected is a new property to track selected nodes and edges. It is a SelectionT type.
  • canDeleteSelected takes the place of canDeleteNode and canDeleteEdge. It accepts a SelectionT type as a parameter.
  • onDeleteNode is removed
  • onDeleteEdge is removed
  • selectedNode is removed
  • selectedEdge is removed
  • canDeleteNode is removed
  • canDeleteEdge is removed
  • selectedNodes is removed
  • selectedEdges is removed

Installation

npm install --save react-digraph

If you don't have the following peerDependenies, make sure to install them:

npm install --save react react-dom

Usage

The default export is a component called GraphView; it provides a multitude of hooks for various graph editing operations and a set of controls for zooming. Typically, it should be wrapped in a higher order component that supplies various callbacks (onCreateNode, onCreateEdge etc...).

GraphView expects several properties to exist on your nodes and edges. If these types conflict with existing properties on your data, you must transform your data to re-key these properties under different names and to add the expected properties. All nodes and edges can have a type attribute set - nodes also support a subtype attribute. For a full description of node and edge properties, see the sections for INode and IEdge below.

Configuration for nodes and edges can be passed to GraphView via the nodeTypes, nodeSubtypes, and edgeTypes props. Custom SVG elements can be defined here for the node's type/subtype and the edge's type.

It is often convenient to combine these types into a configuration object that can be referred to elsewhere in the application and used to associate events fired from nodes/edges in the GraphView with other actions in the application. Here is an abbreviated example:

import {
  GraphView, // required
  Edge, // optional
  type IEdge, // optional
  Node, // optional
  type INode, // optional
  type LayoutEngineType, // required to change the layoutEngineType, otherwise optional
  BwdlTransformer, // optional, Example JSON transformer
  GraphUtils // optional, useful utility functions
} from 'react-digraph';

const GraphConfig =  {
  NodeTypes: {
    empty: { // required to show empty nodes
      typeText: "None",
      shapeId: "#empty", // relates to the type property of a node
      shape: (
        <symbol viewBox="0 0 100 100" id="empty" key="0">
          <circle cx="50" cy="50" r="45"></circle>
        </symbol>
      )
    },
    custom: { // required to show empty nodes
      typeText: "Custom",
      shapeId: "#custom", // relates to the type property of a node
      shape: (
        <symbol viewBox="0 0 50 25" id="custom" key="0">
          <ellipse cx="50" cy="25" rx="50" ry="25"></ellipse>
        </symbol>
      )
    }
  },
  NodeSubtypes: {},
  EdgeTypes: {
    emptyEdge: {  // required to show empty edges
      shapeId: "#emptyEdge",
      shape: (
        <symbol viewBox="0 0 50 50" id="emptyEdge" key="0">
          <circle cx="25" cy="25" r="8" fill="currentColor"> </circle>
        </symbol>
      )
    }
  }
}

const NODE_KEY = "id"       // Allows D3 to correctly update DOM

class Graph extends Component {

  constructor(props) {
    super(props);

    this.state = {
      graph: sample,
      selected: {}
    }
  }

  /* Define custom graph editing methods here */

  render() {
    const nodes = this.state.graph.nodes;
    const edges = this.state.graph.edges;
    const selected = this.state.selected;

    const NodeTypes = GraphConfig.NodeTypes;
    const NodeSubtypes = GraphConfig.NodeSubtypes;
    const EdgeTypes = GraphConfig.EdgeTypes;

    return (
      <div id='graph' style={styles.graph}>

        <GraphView  ref='GraphView'
                    nodeKey={NODE_KEY}
                    nodes={nodes}
                    edges={edges}
                    selected={selected}
                    nodeTypes={NodeTypes}
                    nodeSubtypes={NodeSubtypes}
                    edgeTypes={EdgeTypes}
                    allowMultiselect={true} // true by default, set to false to disable multi select.
                    onSelect={this.onSelect}
                    onCreateNode={this.onCreateNode}
                    onUpdateNode={this.onUpdateNode}
                    onDeleteNode={this.onDeleteNode}
                    onCreateEdge={this.onCreateEdge}
                    onSwapEdge={this.onSwapEdge}
                    onDeleteEdge={this.onDeleteEdge}/>
      </div>
    );
  }

}

A typical graph that would be stored in the Graph component's state looks something like this:

{
  "nodes": [
    {
      "id": 1,
      "title": "Node A",
      "x": 258.3976135253906,
      "y": 331.9783248901367,
      "type": "empty"
    },
    {
      "id": 2,
      "title": "Node B",
      "x": 593.9393920898438,
      "y": 260.6060791015625,
      "type": "empty"
    },
    {
      "id": 3,
      "title": "Node C",
      "x": 237.5757598876953,
      "y": 61.81818389892578,
      "type": "custom"
    },
    {
      "id": 4,
      "title": "Node C",
      "x": 600.5757598876953,
      "y": 600.81818389892578,
      "type": "custom"
    }
  ],
  "edges": [
    {
      "source": 1,
      "target": 2,
      "type": "emptyEdge"
    },
    {
      "source": 2,
      "target": 4,
      "type": "emptyEdge"
    }
  ]
}

For a detailed example, check out src/examples/graph.js. To run the example:

npm install
npm run example

A webpage will open in your default browser automatically.

  • To add nodes, hold shift and click on the grid.
  • To add edges, hold shift and click/drag to between nodes.
  • To delete a node or edge, click on it and press delete.
  • Click and drag nodes to change their position.
  • To select multiple nodes, press Ctrl+Shift then click and drag the mouse.
  • You may copy and paste selected nodes and edges with Ctrl+C and Ctrl+V
  • Note: On Mac computers, use Cmd instead of Ctrl.

All props are detailed below.

Props

PropTypeRequiredNotes
nodeKeystringtrueKey for D3 to update nodes(typ. UUID).
nodesArray<INode>trueArray of graph nodes.
edgesArray<IEdge>trueArray of graph edges.
allowCopyEdgesbooleanfalse(default false) Allow onCopySelected to be called when an edge is selected without any nodes.
allowMultiselectbooleanfalse(default true) Use Ctrl-Shift-LeftMouse to draw a multiple selection box.
selectedobjecttrueThe currently selected graph entity.
nodeTypesobjecttrueConfig object of available node types.
nodeSubtypesobjecttrueConfig object of available node subtypes.
edgeTypesobjecttrueConfig object of available edge types.
onSelectfuncfalseCalled when nodes are selected when allowMultiselect is true. Is passed an object with nodes and edges included.
onCreateNodefunctrueCalled when a node is created.
onContextMenufunctrueCalled when contextmenu event triggered.
onUpdateNodefunctrueCalled when a node is moved.
onCreateEdgefunctrueCalled when an edge is created.
onSwapEdgefunctrueCalled when an edge 'target' is swapped.
onBackgroundClickfuncfalseCalled when the background is clicked.
onArrowClickedfuncfalseCalled when the arrow head is clicked.
onUndofuncfalseA function called when Ctrl-Z is activated. React-digraph does not keep track of actions, this must be implemented in the client website.
onCopySelectedfuncfalseA function called when Ctrl-C is activated. React-digraph does not keep track of copied nodes or edges, the this must be implemented in the client website.
onPasteSelectedfuncfalseA function called when Ctrl-V is activated. React-digraph does not keep track of copied nodes or edges, the this must be implemented in the client website.
canDeleteSelectedfuncfalsetakes the place of canDeleteNode and canDeleteEdge. It accepts a SelectionT type as a parameter. It is called before a node or edge is deleted. The function should return a boolean.
canCreateEdgefuncfalseCalled before an edge is created.
canSwapEdgefuncfalseCalled before an edge 'target' is swapped.
afterRenderEdgefuncfalseCalled after an edge is rendered.
renderNodefuncfalseCalled to render node geometry.
renderNodeTextfuncfalseCalled to render the node text
renderDefsfuncfalseCalled to render SVG definitions.
renderBackgroundfuncfalseCalled to render SVG background.
readOnlyboolfalseDisables all graph editing interactions.
disableBackspaceboolfalseDisables using backspace to delete the selected node.
maxTitleCharsnumberfalseTruncates node title characters.
gridSizenumberfalseOverall grid size.
gridSpacingnumberfalseGrid spacing.
gridDotSizenumberfalseGrid dot size.
minZoomnumberfalseMinimum zoom percentage.
maxZoomnumberfalseMaximum zoom percentage.
nodeSizenumberfalseNode bbox size.
edgeHandleSizenumberfalseEdge handle size.
edgeArrowSizenumberfalseEdge arrow size in pixels. Default 8. Set to 0 to hide arrow.
zoomDelaynumberfalseDelay before zoom occurs.
zoomDurnumberfalseDuration of zoom transition.
showGraphControlsbooleanfalseWhether to show zoom controls.
layoutEngineTypetypeof LayoutEngineTypefalseUses a pre-programmed layout engine, such as 'SnapToGrid'
rotateEdgeHandlebooleanfalseWhether to rotate edge handle with edge when a node is moved
centerNodeOnMovebooleanfalseWhether the node should be centered on cursor when moving a node
initialBBoxtypeof IBBoxfalseIf specified, initial render graph using the given bounding box
graphConfigobjectfalsedagre graph setting configuration, which will override layout engine graph configuration - only apply to 'HorizontalTree'
nodeSizeOverridesAllowedbooleanfalseFlag to toggle sizeOverride in nodes - only apply to 'HorizontalTree'
nodeLocationOverridesobjectfalseNodes location overrides object - only apply to 'HorizontalTree'

onCreateNode

You have access to d3 mouse event in onCreateNode function.

  onCreateNode = (x, y, mouseEvent) => {
    // we can get the exact mouse position when click happens with this line
    const {pageX, pageY} = mouseEvent;
    // rest of the code for adding a new node ...
  };

Prop Types:

See prop types in the typings folder.

INode

PropTypeRequiredNotes
anyIDKeystringtrueAn id or key for nodes, same as the nodeKey prop
titlestringtrueUsed in edges and to render the node text.
xnumberfalseX coordinate of the node.
ynumberfalseY coordinate of the node.
typestringfalseNode type, for displaying a custom SVG shape.
subtypestringfalseNode subtype, for displaying a custom SVG shape.

title

The title attribute is used for the IDs in the SVG nodes in the graph.

IEdge

PropTypeRequiredNotes
sourcestringtrueThe title of the parent node.
targetstringtrueThe title of the child node.
typestringfalseEdge type, for displaying a custom SVG shape.
handleTextstringfalseText to render on the edge.
handleTooltipTextstringfalseUsed to render the SVG title element.
label_fromstringfalseText to render along the edge with label_to.
label_tostringfalseText to render along the edge with label_from.

Imperative API

You can call these methods on the GraphView class using a ref.

MethodTypeNotes
panToNode(id: string, zoom?: boolean) => voidCenter the node given by id within the viewport, optionally zoom in to fit it.
panToEdge(source: string, target: string, zoom?: boolean) => voidCenter the edge between source and target node IDs within the viewport, optionally zoom in to fit it.

Deprecation Notes

PropTypeRequiredNotes
emptyTypestringtrue'Default' node type.
getViewNodefunctrueNode getter.
renderEdgefuncfalseCalled to render edge geometry.
enableFocusboolfalseAdds a 'focus' toggle state to GraphView.
transitionTimenumberfalseFade-in/Fade-out time.
primarystringfalsePrimary color.
lightstringfalseLight color.
darkstringfalseDark color.
styleobjectfalseStyle prop for wrapper.
gridDotnumberfalseGrid dot size.
graphControlsbooleantrueWhether to show zoom controls.