Package Exports
- react-flow-renderer
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-flow-renderer) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
π React Flow
React Flow is a library for building node-based graphs. You can easily implement custom node types and it comes with plugins like a mini-map and graph controls. Feel free to check out the examples or read the blog post to get started.
- Key Features
- Installation
- Usage
- ReactFlow Component Props
- Styling
- Nodes
- Handle Component
- Edges
- Helper Functions
- Plugins
- Examples
- Development
- Testing
Key Features
- Easy to use: Seamless zooming & panning behaviour and single and multi-selections of elements
- Customizable: Different node and edge types and support for custom nodes with multiple handles and edges
- Fast rendering: Only nodes that have changed are re-rendered and only those that are in the viewport are displayed
- Utils: Snap-to-grid, background styles and graph helper functions
- Plugin system: Mini map and graph controls
- Reliable: Written in Typescript and tested with cypress
In order to make this library as flexible as possible we donβt do any state updates besides the positions. This means that you need to pass the functions to remove an element or connect nodes by yourself. You can implement your own ones or use the helper functions that come with the library.
Installation
npm install react-flow-renderer
Usage
This is a very basic example of how to use react-flow. There are more advanced examples in the example folder.
import React from 'react';
import ReactFlow from 'react-flow-renderer';
const elements = [
{ id: '1', data: { label: 'Node 1' }, position: { x: 250, y: 5 } },
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 } },
{ id: 'e1-2', source: '1', target: '2', animated: true },
];
const graphStyles = { width: '100%', height: '100%' };
const BasicFlow = () => (
<ReactFlow elements={elements} style={graphStyles} />
);
ReactFlow Component Props
elements
: array of nodes and edges (required)onElementClick
: element click handleronElementsRemove
: element remove handleronNodeDragStop
: node drag stop handleronConnect
: connect handleronLoad
: editor load handleronMove
: move handlernodeTypes
: object with node typesedgeTypes
: object with edge typesstyle
: css style passed to the wrapperconnectionLineType
: connection line type =straight
orbezier
connectionLineStyle
: connection style as svg attributesdeleteKeyCode
: default:8
(delete)selectionKeyCode
: default:16
(shift)showBackground
: default:true
backgroundGap
: gap size - default:16
backgroundColor
: color of dots or lines - default:#eee
backgroundType
: background type =dots
orlines
- default:dots
snapToGrid
: default:false
snapGrid
: [x, y] array - default:[16, 16]
onlyRenderVisibleNodes
: default:true
isInteractive
: default:true
. If the graph is not interactive you can't drag any nodes
Styling
There are two ways how you can style the graph and the elements. You can create your own CSS rules or pass style properties to the components.
Using Class Names
Since we are using DOM nodes for rendering the graph you can simply overwrite the styles with your own CSS rules.
The React Flow wrapper has the className react-flow
. If you want to change the graph background for example you can do:
.react-flow {
background: red;
}
The same applies to the nodes (className: react-flow__node
), edges (className: react-flow__edge
), controls (react-flow__controls
) or the mini map plugin (react-flow__minimap
).
Using Properties
You could achieve the same effect by passing a style prop to the React Flow component:
const FlowWithRedBg = (
<ReactFlow
elements={elements}
style={{ background: 'red', width: '100%' height: '300px' }}
/>
);
Nodes
There are three different node types (default
, input
, output
) you can use. The node types differ in the number and types of handles. An input node has only a source handle, a default node has a source and a target and an output node has only a target handle. You create nodes by adding them to the elements
array of the React Flow component.
Node example: { id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } }
Options
id
: string (required)position
: { x: number, y: number } (required)data
: {} (required if you are using a standard type, otherwise depends on your implementation)type
: 'input' | 'output' | 'default' or a custom one you implementedstyle
: css propertiestargetPosition
: 'left' | 'right' | 'top' | 'bottom' handle position - default: 'top'sourcePosition
: 'left' | 'right' | 'top' | 'bottom' handle position - default: 'bottom'
Node Types / Custom Nodes
The standard node types are input
, default
and output
. The default node types object looks like this:
{
input: InputNode,
default: DefaultNode,
output: OutputNode
}
The keys represent the type names and the values are the components that get rendered.
If you want to introduce a new type you can pass a nodeTypes
object to the React Flow component:
nodeTypes={{
special: MyCustomNode
}}
You could now use the type special
for a node.
The default
, input
and output
types would be still available except you overwrote one of them.
There is an example of a custom node implementation in the custom node example.
Handle Component
We export a Handle
component as a helper for your custom nodes:
import { Handle } from 'react-flow-renderer';
const targetHandleWithValidation = (
<Handle
type="target"
position="left"
isValidConnection={(connection) => connection.source === 'some-id'}
onConnect={params => console.log('handle onConnect', params)}
style={{ background: '#fff' }}
/>
);
Prop Types
type
: 'source' | 'target'id
: string - you only need this when you have multiple source or target handles otherwise the node id is usedposition
: 'left' | 'right' | 'top' | 'bottom' handle position - default: 'top' for type target, 'bottom' for type sourceonConnect
: function that gets triggered on connectisValidConnection
: function receives a connection{ target: 'some-id', source: 'another-id' }
as param, returns a boolean - true by defaultstyle
: css properties
Multiple Handles
If you need multiple source or target handles you can achieve this by creating a custom node. Normally you just use the id of a node for the source
or target
of an edge. If you have multiple source or target handles you need to pass an id to these handles. These ids get then added to the node id, so that you can connect a specific handle. If you have a node with an id = 1
and a handle with an id = a
you can connect this handle by using the id = 1__a
.
You can find an example of how to implement a custom node with multiple handles in the custom node example.
Edges
React Flow comes with three edge types (straight
, default
, step
). As the names indicate, the edges differ in the representation. The default type is default
which is a bezier edge. You create edges by adding them to your elements
array of the React Flow component.
Edge example: { id: 'e1-2', type: 'straight', source: '1', target: '2', animated: true, label: 'edge label' }
If you wanted to display this edge, you would need a node with id = 1 (source node) and one with id = 2 (target node).
Options
id
: string (required)source
: string (an id of a node) (required)target
: string (an id of a node) (required)type
: 'input' | 'output' | 'default' or a custom one you implementedanimated
: booleanstyle
: css properties for the edge line pathlabel
: stringlabelStyle
: css properties for the textlabelShowBg
: boolean - default:true
labelBgStyle
: css properties for the text background
You can find an example with lots of different edges in the edges example.
Edge Types / Custom Edges
The basic edge types are straight
, default
and step
. The default edgeTypes
object looks like this:
{
default: BezierEdge,
straight: StraightEdge,
step: StepEdge
}
The keys represents the type names and the values are the edge components.
If you want to introduce a new edge type you can pass an edgeTypes
object to the React Flow component:
edgeTypes={{
special: MyCustomEdge
}}
Now you could use the new type special
for an edge.
The straight
, default
and step
types would still be available unless you overwrote one of them.
There is an implementation of a custom edge in the edges example.
Helper Functions
If you want to remove a node or connect two nodes with each other you need to pass a function to onElementsRemove
and onConnect
. In order to simplify this process we export some helper functions so that you don't need to implement them:
import ReactFlow, { isNode, isEdge, removeElements, addEdge } from 'react-flow-renderer';
isEdge
isEdge = (element: Node | Edge): boolean
isNode
isNode = (element: Node | Edge): boolean
removeElements
removeElements = (elementsToRemove: Elements, elements: Elements): Elements
addEdge
addEdge = (edgeParams: Edge, elements: Elements): Elements
You can use these function as seen in this example or use your own ones.
Plugins
MiniMap
You can use the mini map plugin by passing it as a children to the React Flow component:
import ReactFlow, { MiniMap } from 'react-flow-renderer';
const GraphWithMiniMap = () => (
<ReactFlow elements={elements}>
<MiniMap
nodeColor={(node) => {
switch (node.type) {
case 'input': return 'red';
case 'default': return '#00ff00';
case 'output': return 'rgb(0,0,255)';
default: return '#eee';
}
}}
/>
</ReactFlow>
);
Prop Types
nodeColor
: string | function - if you pass a color as a string all nodes will get that color. If you pass a function you can return a color depending on the passed node.nodeBorderRadius
: numbermaskColor
: stringstyle
: css propertiesclassName
: class name
Controls
The control panel contains a zoom-in, zoom-out, fit-view and a lock/unlock button. You can use it by passing it as a children to the React Flow component:
import ReactFlow, { Controls } from 'react-flow-renderer';
const FlowWithControls = () => (
<ReactFlow elements={elements}>
<Controls />
</ReactFlow>
);
Prop Types
style
: css propertiesclassName
: class nameshowZoom
: boolean - default: trueshowFitView
: boolean - default: trueshowInteractive
: boolean - default: true
Examples
You can find all examples in the example folder or check out the live versions:
Development
First of all you need to install the React Flow dependencies npm install
and the ones of the examples cd example && npm install
.
If you want to contribute or develop some custom features the easiest way is to start the dev server:
npm run dev
This serves the content of the example
folder and watches changes inside the src
folder. The examples are using the source of the src
folder.
Testing
Testing is done with cypress. You can find all test in the integration/flow
folder. In order to run the test do:
npm run test
Thanks!
Special thanks to Andy Lindemann for a lot of helpful contributions!
React Flow was initially developed by webkid, a data visualization company from Berlin. If you need help or want to develop react-based tools or data visualizations, get in touch!