flow-view v6.0.1
flow-view
is a visual editor for Dataflow programming
Installation
Using npm
With npm do
npm install flow-view
Using a CDN
Try this in your HTML page
<script type="module">
import { FlowView } from 'https://unpkg.com/flow-view';
const flowView = new FlowView(document.body);
</script>
Usage
GUI
Try demo here
Constructor
Create a FlowView
instance and pass it a container. It will create a flow-view
custom element and attach it to the
container. Be aware that the flow-view
custom element will fit the whole height of its container, so make sure to
style properly to avoid a zero height container.
<!DOCTYPE html>
<html>
<body>
<script type="module">
import { FlowView } from 'https://unpkg.com/flow-view';
const flowView = new FlowView(document.body);
</script>
</body>
</html>
If some flow-view
custom element is already in the page, it can be passed to the FlowView
constructor. argument.
<!DOCTYPE html>
<html>
<body>
<flow-view id="my-view"></flow-view>
<script type="module">
import { FlowView } from 'https://unpkg.com/flow-view';
const flowView = new FlowView(document.getElementById('my-view'));
</script>
</body>
</html>
Color schemes
Optionally set color scheme. If not provided it defaults to both light and dark according to system preferences.
Light scheme.
<flow-view light></flow-view>
Dark scheme.
<flow-view dark></flow-view>
addNodeDefinitions({ nodes?, types? })
Add a list to define which nodes are available. It is not required but it makes sense to be provided in the majority of use cases.
flowView.addNodeDefinitions({
nodes: [
{ name: "Marge", type: "parent" },
{ name: "Homer", type: "parent" },
{ name: "Bart", type: "child" },
{ name: "Lisa", type: "child" },
{ name: "Mr. Burns" },
],
types: {
"parent": {
inputs: [],
outputs: [
{ name: "out" },
],
},
"child": {
inputs: [
{ name: "in1" },
{ name: "in2" },
],
outputs: [],
},
},
});
node(id)
Get flow-view node by id.
const node = flowView.node("abc");
See also color schemes example.
edge(id)
Get flow-view edge by id.
const edge = flowView.edge("abc");
graph
Access current flow-view graph.
console.log(flowView.graph);
loadGraph({ nodes = [], edges = [] })
Load a flow-view graph.
flowView.loadGraph({
nodes: [
{
id: "dad",
text: "Homer",
x: 60,
y: 70,
outs: [{ id: "children" }],
},
{
id: "mom",
text: "Marge",
x: 160,
y: 70,
outs: [{ id: "children" }],
},
{
id: "son",
text: "Bart",
x: 60,
y: 240,
ins: [{ id: "father" }, { id: "mother" }],
},
{
id: "daughter",
text: "Lisa",
x: 220,
y: 220,
ins: [{ id: "father" }, { id: "mother" }],
},
],
edges: [
{ from: ["dad", "children"], to: ["son", "father"] },
{ from: ["dad", "children"], to: ["daughter", "father"] },
{ from: ["mom", "children"], to: ["son", "mother"] },
{ from: ["mom", "children"], to: ["daughter", "mother"] },
],
});
clearGraph()
Empty current graph.
flowView.clearGraph();
destroy()
Delete flow-view
custom element.
flowView.destroy();
An use case for destroy()
is the following. Suppose you are using Next.js, you need to load flow-view
with an async
import into a useEffect
which needs to return a callback to be called when component is unmounted.
This is a sample code.
import type { FlowView } from "flow-view";
import { FC, useEffect, useRef } from "react";
const MyComponent: FC = () => {
const flowViewContainerRef = useRef<HTMLDivElement | null>(null);
const flowViewRef = useRef<FlowView | null>(null);
useEffect(() => {
let unmounted = false;
const importFlowView = async () => {
if (unmounted) return;
if (flowViewContainerRef.current === null) return;
if (flowViewRef.current !== null) return;
const { FlowView } = await import("flow-view");
const flowView = new FlowView({
container: flowViewContainerRef.current,
});
flowViewRef.current = flowView;
};
importFlowView();
return () => {
unmounted = true;
if (flowViewRef.current !== null) flowViewRef.current.destroy();
};
}, [flowViewRef, flowViewContainerRef]);
return <div ref={flowViewContainerRef}></div>;
};
newNode()
and newEdge()
Create nodes and edges programmatically. See programmatically example here.
// Create two nodes.
const node1 = flowView.newNode({
text: "Hello",
ins: [{}, {}],
outs: [{ id: "output1" }],
x: 100,
y: 100,
width: 80,
});
const node2 = flowView.newNode({
text: "World",
ins: [{ id: "input1" }],
width: 100,
x: 250,
y: 400,
});
// Connect nodes with an edge.
flowView.newEdge({
from: [node1.id, "output1"],
to: [node2.id, "input1"],
});
deleteNode()
and deleteEdge()
Delete nodes and edges programmatically. Notice that when a node is deleted, all its connected edges are deleted too.
const nodeId = "abc";
const edgeId = "123";
flowView.deleteNode(nodeId);
flowView.deleteEdge(edgeId);
addNodeClass(nodeType, NodeClass)
Can add custom node class. See custom node example here.
onChange(callback)
Set callback to be invoked on every view change. See demo code here.
Callback signature is ({ action, data }, info) => void
, where
- action can be
CREATE_NODE
,DELETE_NODE
, etc. - data change based on action
- info can contain
{ isLoadGraph: true }
or other optional information.
nodeTextToType(func)
Set a function that will be invoked on node creation to resolve node type from node text.
License
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago