Simple flow library.
Drawflow allows you to create data flows easily and quickly.
Installing only a javascript library and with four lines of code.
- Features
- Installation
- Mouse and Keys
- Editor
- Modules
- Nodes
- Methods
- Events
- Export / Import
- Example
- License
- Drag Nodes
- Multiple Inputs / Outputs
- Multiple connections
- Delete Nodes and Connections
- Add/Delete inputs/outputs
- Reroute connections
- Data sync on Nodes
- Zoom in / out
- Clear data module
- Support modules
- Editor mode edit,fixedorview
- Import / Export data
- Events
- Mobile support
- Vanilla javascript (No dependencies)
- NPM
- Vue Support component nodes && Nuxt
Download or clone repository and copy the dist folder, CDN option Or npm.
git clone https://github.com/jerosoler/Drawflow.git
# Last
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.css">
<script src="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.js"></script>
# or version view releases https://github.com/jerosoler/Drawflow/releases
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/drawflow.min.css" />
<script src="https://unpkg.com/[email protected]/dist/drawflow.min.js"></script>npm i drawflowExternal package. More info #119
npm install -D @types/drawflowimport Drawflow from 'drawflow'
import styleDrawflow from 'drawflow/dist/drawflow.min.css'var Drawflow = require('drawflow')
var styleDrawflow = require('drawflow/dist/drawflow.min.css')Create the parent element of drawflow.
<div id="drawflow"></div>Start drawflow.
var id = document.getElementById("drawflow");
const editor = new Drawflow(id);
editor.start();| Parameter | Type | Description | 
|---|---|---|
| id | Object | Name of module | 
| render | Object | It's for Vue. | 
| parent | Object | It's for Vue. The parent Instance | 
import Vue from 'vue'
// Pass render Vue
this.editor = new Drawflow(id, Vue, this);import { h, getCurrentInstance, render } from 'vue'
const Vue = { version: 3, h, render };
this.editor = new Drawflow(id, Vue);
// Pass render Vue 3 Instance
const internalInstance = getCurrentInstance()
editor.value = new Drawflow(id, Vue, internalInstance.appContext.app._context);Add to nuxt.config.js file
build: {
    transpile: ['drawflow'],
    ...
  }- del keyto remove element.
- Right clickto show remove options (Mobile long press).
- Left click pressto move editor or node selected.
- Ctrl + Mouse WheelZoom in/out (Mobile pinch).
You can change the editor to fixed type to block. Only editor can be moved. You can put it before start.
editor.editor_mode = 'edit'; // Default
editor.editor_mode = 'fixed'; // Only scrollYou can also adjust the zoom values.
editor.zoom_max = 1.6;
editor.zoom_min = 0.5;
editor.zoom_value = 0.1;| Parameter | Type | Default | Description | 
|---|---|---|---|
| reroute | Boolean | false | Active reroute | 
| reroute_fix_curvature | Boolean | false | Fix adding points | 
| curvature | Number | 0.5 | Curvature | 
| reroute_curvature_start_end | Number | 0.5 | Curvature reroute first point and las point | 
| reroute_curvature | Number | 0.5 | Curvature reroute | 
| reroute_width | Number | 6 | Width of reroute | 
| line_path | Number | 5 | Width of line | 
| force_first_input | Boolean | false | Force the first input to drop the connection on top of the node | 
| editor_mode | Text | edit | editfor edit,fixedfor nodes fixed but their input fields available,viewfor view only | 
| zoom | Number | 1 | Default zoom | 
| zoom_max | Number | 1.6 | Default zoom max | 
| zoom_min | Number | 0.5 | Default zoom min | 
| zoom_value | Number | 0.1 | Default zoom value update | 
| zoom_last_value | Number | 1 | Default zoom last value | 
| draggable_inputs | Boolean | true | Drag nodes on click inputs | 
| useuuid | Boolean | false | Use UUID as node ID instead of integer index. Only affect newly created nodes, do not affect imported nodes | 
Active reroute connections. Use before start or import.
editor.reroute = true;Create point with double click on line connection. Double click on point for remove.
Separate your flows in different editors.
editor.addModule('nameNewModule');
editor.changeModule('nameNewModule');
editor.removeModule('nameModule');
// Default Module is Home
editor.changeModule('Home');RemovedModule if it is in the same module redirects to the Home module
Adding a node is simple.
editor.addNode(name, inputs, outputs, posx, posy, class, data, html);| Parameter | Type | Description | 
|---|---|---|
| name | text | Name of module | 
| inputs | number | Number of de inputs | 
| outputs | number | Number of de outputs | 
| pos_x | number | Position on start node left | 
| pos_y | number | Position on start node top | 
| class | text | Added classname to de node. Multiple classnames separated by space | 
| data | json | Data passed to node | 
| html | text | HTML drawn on node or nameof register node. | 
| typenode | boolean & text | Default false,truefor Object HTML,vuefor vue | 
You can use the attribute df-* in inputs, textarea or select to synchronize with the node data and contenteditable.
Atrributs multiples parents support df-*-*...
var html = `
<div><input type="text" df-name></div>
`;
var data = { "name": '' };
editor.addNode('github', 0, 1, 150, 300, 'github', data, html);it's possible register nodes for reuse.
var html = document.createElement("div");
html.innerHTML =  "Hello Drawflow!!";
editor.registerNode('test', html);
// Use
editor.addNode('github', 0, 1, 150, 300, 'github', data, 'test', true);
// For vue
import component from '~/components/testcomponent.vue'
editor.registerNode('name', component, props, options);
// Use for vue
editor.addNode('github', 0, 1, 150, 300, 'github', data, 'name', 'vue');| Parameter | Type | Description | 
|---|---|---|
| name | text | Name of module registered. | 
| html | text | HTML to drawn or vuecomponent. | 
| props | json | Only for vue. Props of component.Not Required | 
| options | json | Only for vue. Options of component.Not Required | 
Other available functions.
| Mehtod | Description | 
|---|---|
| zoom_in() | Increment zoom +0.1 | 
| zoom_out() | Decrement zoom -0.1 | 
| getNodeFromId(id) | Get Info of node. Ex: id: 5 | 
| getNodesFromName(name) | Return Array of nodes id. Ex: name: telegram | 
| removeNodeId(id) | Remove node. Ex id: node-x | 
| updateNodeDataFromId | Update data element. Ex: 5, { name: 'Drawflow' } | 
| addNodeInput(id) | Add input to node. Ex id: 5 | 
| addNodeOutput(id) | Add output to node. Ex id: 5 | 
| removeNodeInput(id, input_class) | Remove input to node. Ex id: 5,input_2 | 
| removeNodeOutput(id, output_class) | Remove output to node. Ex id: 5,output_2 | 
| addConnection(id_output, id_input, output_class, input_class) | Add connection. Ex: 15,16,'output_1','input_1' | 
| removeSingleConnection(id_output, id_input, output_class, input_class) | Remove connection. Ex: 15,16,'output_1','input_1' | 
| updateConnectionNodes(id) | Update connections position from Node Ex id: node-x | 
| removeConnectionNodeId(id) | Remove node connections. Ex id: node-x | 
| getModuleFromNodeId(id) | Get name of module where is the id. Ex id: 5 | 
| clearModuleSelected() | Clear data of module selected | 
| clear() | Clear all data of all modules and modules remove. | 
editor.removeNodeId('node-4');You can detect events that are happening.
List of available events:
| Event | Return | Description | 
|---|---|---|
| nodeCreated | id | idof Node | 
| nodeRemoved | id | idof Node | 
| nodeDataChanged | id | idof Node df-* attributes changed. | 
| nodeSelected | id | idof Node | 
| nodeUnselected | true | Unselect node | 
| nodeMoved | id | idof Node | 
| connectionStart | { output_id, output_class } | idof nodes and output selected | 
| connectionCancel | true | Connection Cancel | 
| connectionCreated | { output_id, input_id, output_class, input_class } | id's of nodes and output/input selected | 
| connectionRemoved | { output_id, input_id, output_class, input_class } | id's of nodes and output/input selected | 
| connectionSelected | { output_id, input_id, output_class, input_class } | id's of nodes and output/input selected | 
| connectionUnselected | true | Unselect connection | 
| addReroute | id | idof Node output | 
| removeReroute | id | idof Node output | 
| rerouteMoved | id | idof Node output | 
| moduleCreated | name | nameof Module | 
| moduleChanged | name | nameof Module | 
| moduleRemoved | name | nameof Module | 
| click | event | Click event | 
| clickEnd | event | Once the click changes have been made | 
| contextmenu | event | Click second button mouse event | 
| mouseMove | { x, y } | Position | 
| mouseUp | event | MouseUp Event | 
| keydown | event | Keydown event | 
| zoom | zoom_level | Level of zoom | 
| translate | { x, y } | Position translate editor | 
| import | import | Finish import | 
| export | data | Data export | 
editor.on('nodeCreated', function(id) {
  console.log("Node created " + id);
})You can export and import your data.
var exportdata = editor.export();
editor.import(exportdata);Example of exported data:
{
    "drawflow": {
        "Home": {
            "data": {}
        },
        "Other": {
            "data": {
                "16": {
                    "id": 16,
                    "name": "facebook",
                    "data": {},
                    "class": "facebook",
                    "html": "\n        
\n          
 Facebook Message
\n        
\n        ",
                    "inputs": {},
                    "outputs": {
                        "output_1": {
                            "connections": [
                                {
                                    "node": "17",
                                    "output": "input_1"
                                }
                            ]
                        }
                    },
                    "pos_x": 226,
                    "pos_y": 138
                },
                "17": {
                    "id": 17,
                    "name": "log",
                    "data": {},
                    "class": "log",
                    "html": "\n            
\n              
 Save log file
\n            
\n            ",
                    "inputs": {
                        "input_1": {
                            "connections": [
                                {
                                    "node": "16",
                                    "input": "output_1"
                                }
                            ]
                        }
                    },
                    "outputs": {},
                    "pos_x": 690,
                    "pos_y": 129
                }
            }
        }
    }
}
View the complete example in folder docs.
There is also an example how to use Drawflow in a custom element. (based on LitElement).
MIT License
