.editorconfig (240, 2023-07-19)
.npmignore (53, 2023-07-19)
.prettierrc.json (68, 2023-07-19)
LICENSE (1081, 2023-07-19)
examples (0, 2023-07-19)
examples\color-schemes (0, 2023-07-19)
examples\color-schemes\demo.html (2551, 2023-07-19)
examples\custom-node (0, 2023-07-19)
examples\custom-node\demo.html (1605, 2023-07-19)
examples\custom-node\info.js (1504, 2023-07-19)
examples\full-page (0, 2023-07-19)
examples\full-page\demo.html (572, 2023-07-19)
examples\programmatic (0, 2023-07-19)
examples\programmatic\demo.html (3196, 2023-07-19)
flow-view.d.ts (5654, 2023-07-19)
index.html (5817, 2023-07-19)
index.js (250, 2023-07-19)
package.json (944, 2023-07-19)
screenshot.png (51066, 2023-07-19)
src (0, 2023-07-19)
src\base.js (1976, 2023-07-19)
src\edge.js (4528, 2023-07-19)
src\element.js (13976, 2023-07-19)
src\errors.js (137, 2023-07-19)
src\flow-view.js (3819, 2023-07-19)
src\input.js (1142, 2023-07-19)
src\node.js (4599, 2023-07-19)
src\output.js (632, 2023-07-19)
src\pin.js (2063, 2023-07-19)
src\selector.js (9121, 2023-07-19)
src\theme.js (1961, 2023-07-19)
style.css (1651, 2023-07-19)
# flow-view
> is a visual editor for [Dataflow programming][dataflow_wikipedia]
Demo
## Installation
### Using npm
With [npm](https://npmjs.org/) do
```bash
npm install flow-view
```
### Using a CDN
Try this in your HTML page
```html
```
## Usage
### GUI
Try [demo here](http://fibo.github.io/flow-view/)
- Drag on canvas to translate all items.
- Click on item to select it.
- Click while pressing SHIFT to enable multi selection.
- Drag selected items to translate them.
- Drag from a node output to a node input to create an edge.
- Press BACKSPACE to delete selected items.
- Double click on edge to delete it.
- Double click on canvas to open the selector.
- Type into the selector then press ENTER to create a new node.
### 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.
```html
```
If some `flow-view` custom element is already in the page, it can be passed to the `FlowView` constructor. argument.
```html
```
### Color schemes
Optionally set _color scheme_. If not provided it defaults to both light and dark according to system preferences.
Light scheme.
```html
```
Dark scheme.
```html
```
See also [color schemes example](http://fibo.github.io/flow-view/examples/color-schemes/demo.html).
### `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.
```javascript
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.
```javascript
const node = flowView.node("abc");
```
### `edge(id)`
Get _flow-view_ edge by id.
```javascript
const edge = flowView.edge("abc");
```
### `graph`
Access current _flow-view_ graph.
```javascript
console.log(flowView.graph);
```
### `loadGraph({ nodes = [], edges = [] })`
Load a _flow-view_ graph.
```javascript
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.
```javascript
flowView.clearGraph();
```
### `destroy()`
Delete `flow-view` custom element.
```javascript
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.
```typescript
import type { FlowView } from "flow-view";
import { FC, useEffect, useRef } from "react";
const MyComponent: FC = () => {
const flowViewContainerRef = useRef
(null);
const flowViewRef = useRef(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 ;
};
```
### `newNode()` and `newEdge()`
Create nodes and edges programmatically. See
[programmatically example here](http://fibo.github.io/flow-view/examples/programmatic/demo.html).
```javascript
// 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.
```javascript
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](http://fibo.github.io/flow-view/examples/custom-node/demo.html).
### `onChange(callback)`
Set callback to be invoked on every view change. See
[demo code here](https://github.com/fibo/flow-view/blob/main/index.html).
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
[MIT](http://fibo.github.io/mit-license)
[dataflow_wikipedia]: https://en.wikipedia.org/wiki/Dataflow_programming "Dataflow programming"