chore(examples): add layouting

This commit is contained in:
moklick
2020-12-20 13:33:18 +01:00
parent 7c08a38b7c
commit 35b423aacb
7 changed files with 207 additions and 25 deletions
+55 -21
View File
@@ -9,6 +9,7 @@
"version": "0.1.0",
"dependencies": {
"@craco/craco": "^5.7.0",
"dagre": "^0.8.5",
"localforage": "^1.9.0",
"react-dom": "^17.0.1",
"react-flow-renderer": "file:..",
@@ -18,7 +19,7 @@
},
"..": {
"name": "react-flow-renderer",
"version": "8.2.1",
"version": "8.2.2",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.12.5",
@@ -30,10 +31,10 @@
"react-draggable": "^4.4.3"
},
"devDependencies": {
"@babel/core": "^7.12.9",
"@babel/plugin-transform-runtime": "^7.12.1",
"@babel/preset-env": "^7.12.7",
"@babel/preset-react": "^7.12.7",
"@babel/core": "^7.12.10",
"@babel/plugin-transform-runtime": "^7.12.10",
"@babel/preset-env": "^7.12.10",
"@babel/preset-react": "^7.12.10",
"@rollup/plugin-babel": "^5.2.2",
"@rollup/plugin-commonjs": "^17.0.0",
"@rollup/plugin-node-resolve": "^11.0.0",
@@ -44,11 +45,11 @@
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/resize-observer-browser": "^0.1.4",
"autoprefixer": "^10.0.4",
"autoprefixer": "^10.1.0",
"babel-preset-react-app": "^10.0.0",
"cypress": "^6.0.1",
"postcss": "^8.1.14",
"postcss-nested": "^5.0.2",
"cypress": "^6.1.0",
"postcss": "^8.2.1",
"postcss-nested": "^5.0.3",
"prettier": "2.2.1",
"prop-types": "^15.7.2",
"react": "^17.0.1",
@@ -58,7 +59,7 @@
"rollup-plugin-postcss": "^4.0.0",
"rollup-plugin-typescript2": "^0.29.0",
"start-server-and-test": "^1.11.6",
"typescript": "^4.1.2"
"typescript": "^4.1.3"
},
"peerDependencies": {
"react": "16 || 17"
@@ -4562,6 +4563,15 @@
"type": "^1.0.1"
}
},
"node_modules/dagre": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz",
"integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==",
"dependencies": {
"graphlib": "^2.1.8",
"lodash": "^4.17.15"
}
},
"node_modules/damerau-levenshtein": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz",
@@ -6852,6 +6862,14 @@
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
},
"node_modules/graphlib": {
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz",
"integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
"dependencies": {
"lodash": "^4.17.15"
}
},
"node_modules/growly": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
@@ -20298,6 +20316,15 @@
"type": "^1.0.1"
}
},
"dagre": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz",
"integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==",
"requires": {
"graphlib": "^2.1.8",
"lodash": "^4.17.15"
}
},
"damerau-levenshtein": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz",
@@ -22226,6 +22253,14 @@
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
},
"graphlib": {
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz",
"integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
"requires": {
"lodash": "^4.17.15"
}
},
"growly": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
@@ -26789,10 +26824,10 @@
"react-flow-renderer": {
"version": "file:..",
"requires": {
"@babel/core": "^7.12.9",
"@babel/plugin-transform-runtime": "^7.12.1",
"@babel/preset-env": "^7.12.7",
"@babel/preset-react": "^7.12.7",
"@babel/core": "^7.12.10",
"@babel/plugin-transform-runtime": "^7.12.10",
"@babel/preset-env": "^7.12.10",
"@babel/preset-react": "^7.12.10",
"@babel/runtime": "^7.12.5",
"@rollup/plugin-babel": "^5.2.2",
"@rollup/plugin-commonjs": "^17.0.0",
@@ -26804,16 +26839,16 @@
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/resize-observer-browser": "^0.1.4",
"autoprefixer": "^10.0.4",
"autoprefixer": "^10.1.0",
"babel-preset-react-app": "^10.0.0",
"classcat": "^4.1.0",
"cypress": "^6.0.1",
"cypress": "^6.1.0",
"d3-selection": "^2.0.0",
"d3-zoom": "^2.0.0",
"easy-peasy": "^4.0.1",
"fast-deep-equal": "^3.1.3",
"postcss": "^8.1.14",
"postcss-nested": "^5.0.2",
"postcss": "^8.2.1",
"postcss-nested": "^5.0.3",
"prettier": "2.2.1",
"prop-types": "^15.7.2",
"react": "^17.0.1",
@@ -26824,7 +26859,7 @@
"rollup-plugin-postcss": "^4.0.0",
"rollup-plugin-typescript2": "^0.29.0",
"start-server-and-test": "^1.11.6",
"typescript": "^4.1.2"
"typescript": "^4.1.3"
},
"dependencies": {
"@babel/core": {
@@ -26851,8 +26886,7 @@
}
},
"@babel/plugin-transform-runtime": {
"version": "7.12.1",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.1.tgz",
"version": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.1.tgz",
"integrity": "sha512-Ac/H6G9FEIkS2tXsZjL4RAdS3L3WHxci0usAnz7laPWUmFiGtj7tIASChqKZMHTSQTQY6xDbOq+V1/vIq3QrWg==",
"dev": true,
"requires": {
+1
View File
@@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"@craco/craco": "^5.7.0",
"dagre": "^0.8.5",
"localforage": "^1.9.0",
"react-dom": "^17.0.1",
"react-flow-renderer": "file:..",
-4
View File
@@ -40,10 +40,6 @@
height: 100%;
}
.dndflow .selectall {
margin-top: 10px;
}
@media screen and (min-width: 768px) {
.dndflow {
flex-direction: row;
+68
View File
@@ -0,0 +1,68 @@
import React, { useEffect, useState } from 'react';
import ReactFlow, { ReactFlowProvider, addEdge, removeElements, Controls, isNode } from 'react-flow-renderer';
import dagre from 'dagre';
import initialElements from './initial-elements';
import './layouting.css';
const dagreGraph = new dagre.graphlib.Graph();
dagreGraph.setDefaultEdgeLabel(() => ({}));
const LayoutFlow = () => {
const [elements, setElements] = useState(initialElements);
const onConnect = (params) => setElements((els) => addEdge(params, els));
const onElementsRemove = (elementsToRemove) => setElements((els) => removeElements(elementsToRemove, els));
const onLayout = (direction) => {
const isHorizontal = direction === 'LR';
dagreGraph.setGraph({ rankdir: direction });
elements.forEach((el) => {
if (isNode(el)) {
dagreGraph.setNode(el.id, { width: 150, height: 50 });
} else {
dagreGraph.setEdge(el.source, el.target);
}
});
dagre.layout(dagreGraph);
const layoutedElements = elements.map((el) => {
if (isNode(el)) {
const nodeWithPosition = dagreGraph.node(el.id);
el.targetPosition = isHorizontal ? 'left' : 'top';
el.sourcePosition = isHorizontal ? 'right' : 'bottom';
// we need to pass a slighltiy different position in order to notify react flow about the change
// @TODO how can we change the position handling so that we dont need this hack?
el.position = { x: nodeWithPosition.x + Math.random() / 1000, y: nodeWithPosition.y };
}
return el;
});
setElements(layoutedElements);
};
useEffect(() => {
onLayout('TB');
}, []);
return (
<div className="layoutflow">
<ReactFlowProvider>
<ReactFlow elements={elements} onConnect={onConnect} onElementsRemove={onElementsRemove}>
<Controls />
</ReactFlow>
<div className="controls">
<button onClick={() => onLayout('TB')} style={{ marginRight: 10 }}>
vertical layout
</button>
<button onClick={() => onLayout('LR')}>horizontal layout</button>
</div>
</ReactFlowProvider>
</div>
);
};
export default LayoutFlow;
+67
View File
@@ -0,0 +1,67 @@
const position = { x: 0, y: 0 };
export default [
{
id: '1',
type: 'input',
data: { label: 'input' },
position,
},
{
id: '2',
data: { label: 'node 2' },
position,
},
{
id: '2a',
data: { label: 'node 2a' },
position,
},
{
id: '2b',
data: { label: 'node 2b' },
position,
},
{
id: '2c',
data: { label: 'node 2c' },
position,
},
{
id: '2d',
data: { label: 'node 2d' },
position,
},
{
id: '3',
data: { label: 'node 3' },
position,
},
{
id: '4',
data: { label: 'node 4' },
position,
},
{
id: '5',
data: { label: 'node 5' },
position,
},
{
id: '6',
type: 'output',
data: { label: 'output' },
position,
},
{ id: '7', type: 'output', data: { label: 'output' }, position: { x: 400, y: 450 } },
{ id: 'e12', source: '1', target: '2', type: 'smoothstep' },
{ id: 'e13', source: '1', target: '3', type: 'smoothstep' },
{ id: 'e22a', source: '2', target: '2a', type: 'smoothstep' },
{ id: 'e22b', source: '2', target: '2b', type: 'smoothstep' },
{ id: 'e22c', source: '2', target: '2c', type: 'smoothstep' },
{ id: 'e2c2d', source: '2c', target: '2d', type: 'smoothstep' },
{ id: 'e45', source: '4', target: '5', type: 'smoothstep' },
{ id: 'e56', source: '5', target: '6', type: 'smoothstep' },
{ id: 'e57', source: '5', target: '7', type: 'smoothstep' },
];
+11
View File
@@ -0,0 +1,11 @@
.layoutflow {
flex-grow: 1;
position: relative;
}
.layoutflow .controls {
position: absolute;
right: 10px;
top: 10px;
z-index: 10;
}
+5
View File
@@ -19,6 +19,7 @@ import UpdatableEdge from './UpdatableEdge';
import UpdateNode from './UpdateNode';
import SaveRestore from './SaveRestore';
import DragNDrop from './DragNDrop';
import Layout from './Layouting';
import './index.css';
@@ -91,6 +92,10 @@ const routes = [
path: '/drag-and-drop',
component: DragNDrop,
},
{
path: '/layouting',
component: Layout,
},
];
const Header = withRouter(({ history, location }) => {