chore(examples): add layouting
This commit is contained in:
Generated
+55
-21
@@ -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": {
|
||||
|
||||
@@ -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:..",
|
||||
|
||||
@@ -40,10 +40,6 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.dndflow .selectall {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.dndflow {
|
||||
flex-direction: row;
|
||||
|
||||
@@ -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;
|
||||
@@ -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' },
|
||||
];
|
||||
@@ -0,0 +1,11 @@
|
||||
.layoutflow {
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.layoutflow .controls {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
z-index: 10;
|
||||
}
|
||||
@@ -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 }) => {
|
||||
|
||||
Reference in New Issue
Block a user