Merge pull request #221 from wbkd/develop
Apply position and style changes to nodes
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
import Graph, { removeElements, addEdge } from 'react-flow-renderer';
|
import ReactFlow, { removeElements, addEdge, isNode } from 'react-flow-renderer';
|
||||||
|
|
||||||
const onNodeDragStop = node => console.log('drag stop', node);
|
const onNodeDragStop = node => console.log('drag stop', node);
|
||||||
const onLoad = graphInstance => console.log('graph loaded:', graphInstance);
|
const onLoad = graphInstance => console.log('graph loaded:', graphInstance);
|
||||||
@@ -15,14 +15,32 @@ const initialElements = [
|
|||||||
{ id: 'e1-3', source: '1', target: '3' },
|
{ id: 'e1-3', source: '1', target: '3' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const BasicGraph = () => {
|
const BasicFlow = () => {
|
||||||
const [elements, setElements] = useState(initialElements);
|
const [elements, setElements] = useState(initialElements);
|
||||||
const onElementsRemove = (elementsToRemove) =>
|
const onElementsRemove = (elementsToRemove) =>
|
||||||
setElements(els => removeElements(elementsToRemove, els));
|
setElements(els => removeElements(elementsToRemove, els));
|
||||||
const onConnect = (params) => setElements(els => addEdge(params, els));
|
const onConnect = (params) => setElements(els => addEdge(params, els));
|
||||||
|
|
||||||
|
const updatePos = () => {
|
||||||
|
setElements(elms => {
|
||||||
|
return elms.map(el => {
|
||||||
|
if (isNode(el)) {
|
||||||
|
return {
|
||||||
|
...el,
|
||||||
|
position: {
|
||||||
|
x: Math.random() * 400,
|
||||||
|
y: Math.random() * 400
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return el;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Graph
|
<ReactFlow
|
||||||
elements={elements}
|
elements={elements}
|
||||||
onLoad={onLoad}
|
onLoad={onLoad}
|
||||||
onElementClick={onElementClick}
|
onElementClick={onElementClick}
|
||||||
@@ -31,8 +49,15 @@ const BasicGraph = () => {
|
|||||||
onNodeDragStop={onNodeDragStop}
|
onNodeDragStop={onNodeDragStop}
|
||||||
style={{ width: '100%', height: '100%' }}
|
style={{ width: '100%', height: '100%' }}
|
||||||
backgroundType="lines"
|
backgroundType="lines"
|
||||||
/>
|
>
|
||||||
|
<button
|
||||||
|
onClick={updatePos}
|
||||||
|
style={{ position: 'absolute', right: 10, top: 30, zIndex: 4 }}
|
||||||
|
>
|
||||||
|
change pos
|
||||||
|
</button>
|
||||||
|
</ReactFlow>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default BasicGraph;
|
export default BasicFlow;
|
||||||
|
|||||||
@@ -6,13 +6,11 @@ import ColorSelectorNode from './ColorSelectorNode';
|
|||||||
|
|
||||||
const onNodeDragStop = node => console.log('drag stop', node);
|
const onNodeDragStop = node => console.log('drag stop', node);
|
||||||
const onElementClick = element => console.log('click', element);
|
const onElementClick = element => console.log('click', element);
|
||||||
const onLoad = (graph) => {
|
const onLoad = (graph) => console.log('graph loaded:', graph);
|
||||||
console.log('graph loaded:', graph);
|
|
||||||
};
|
|
||||||
|
|
||||||
const initBgColor = '#f0e742';
|
const initBgColor = '#f0e742';
|
||||||
|
|
||||||
const CustomNodeGraph = () => {
|
const CustomNodeFlow = () => {
|
||||||
const [elements, setElements] = useState([]);
|
const [elements, setElements] = useState([]);
|
||||||
const [bgColor, setBgColor] = useState(initBgColor);
|
const [bgColor, setBgColor] = useState(initBgColor);
|
||||||
|
|
||||||
@@ -83,4 +81,4 @@ const CustomNodeGraph = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CustomNodeGraph;
|
export default CustomNodeFlow;
|
||||||
@@ -6,9 +6,7 @@ import CustomEdge from './CustomEdge';
|
|||||||
|
|
||||||
const onNodeDragStop = node => console.log('drag stop', node);
|
const onNodeDragStop = node => console.log('drag stop', node);
|
||||||
const onElementClick = element => console.log('click', element);
|
const onElementClick = element => console.log('click', element);
|
||||||
const onLoad = (graph) => {
|
const onLoad = (graph) => graph.fitView();
|
||||||
graph.fitView();
|
|
||||||
};
|
|
||||||
|
|
||||||
const initialElements = [
|
const initialElements = [
|
||||||
{ id: '1', type: 'input', data: { label: 'Input 1' }, position: { x: 250, y: 0 } },
|
{ id: '1', type: 'input', data: { label: 'Input 1' }, position: { x: 250, y: 0 } },
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const onNodeDragStop = node => console.log('drag stop', node);
|
|||||||
const onLoad = graphInstance => console.log('graph loaded:', graphInstance);
|
const onLoad = graphInstance => console.log('graph loaded:', graphInstance);
|
||||||
const onElementClick = element => console.log('click', element);
|
const onElementClick = element => console.log('click', element);
|
||||||
|
|
||||||
const EmptyGraph = () => {
|
const EmptyFlow = () => {
|
||||||
const [elements, setElements] = useState([]);
|
const [elements, setElements] = useState([]);
|
||||||
const onElementsRemove = (elementsToRemove) =>
|
const onElementsRemove = (elementsToRemove) =>
|
||||||
setElements(els => removeElements(elementsToRemove, els));
|
setElements(els => removeElements(elementsToRemove, els));
|
||||||
@@ -45,4 +45,4 @@ const EmptyGraph = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default EmptyGraph;
|
export default EmptyFlow;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const initialElements = [
|
|||||||
{ id: 'e1-3', source: '1', target: '3' },
|
{ id: 'e1-3', source: '1', target: '3' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const EmptyGraph = () => {
|
const InactiveFlow = () => {
|
||||||
const [isInteractive, setIsInteractive] = useState(false);
|
const [isInteractive, setIsInteractive] = useState(false);
|
||||||
const onToggleInteractive = (evt) => {
|
const onToggleInteractive = (evt) => {
|
||||||
setIsInteractive(evt.target.checked);
|
setIsInteractive(evt.target.checked);
|
||||||
@@ -43,4 +43,4 @@ const EmptyGraph = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default EmptyGraph;
|
export default InactiveFlow;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const initialElements = [
|
|||||||
{ id: 'e5-7', source: '5', target: '7', type: 'step', label: 'a step edge', labelStyle: { fill: 'red', fontWeight: 700 } },
|
{ id: 'e5-7', source: '5', target: '7', type: 'step', label: 'a step edge', labelStyle: { fill: 'red', fontWeight: 700 } },
|
||||||
];
|
];
|
||||||
|
|
||||||
const RichGraph = () => {
|
const OverviewFlow = () => {
|
||||||
const [elements, setElements] = useState(initialElements);
|
const [elements, setElements] = useState(initialElements);
|
||||||
|
|
||||||
const addRandomNode = () => {
|
const addRandomNode = () => {
|
||||||
@@ -82,4 +82,4 @@ const RichGraph = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default RichGraph;
|
export default OverviewFlow;
|
||||||
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
|
|||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { BrowserRouter as Router, Route, Switch, NavLink, withRouter } from 'react-router-dom';
|
import { BrowserRouter as Router, Route, Switch, NavLink, withRouter } from 'react-router-dom';
|
||||||
|
|
||||||
import Rich from './Rich';
|
import Overview from './Overview';
|
||||||
import Basic from './Basic';
|
import Basic from './Basic';
|
||||||
import CustomNode from './CustomNode';
|
import CustomNode from './CustomNode';
|
||||||
import Stress from './Stress';
|
import Stress from './Stress';
|
||||||
@@ -15,7 +15,7 @@ import './index.css';
|
|||||||
|
|
||||||
const routes = [{
|
const routes = [{
|
||||||
path: '/',
|
path: '/',
|
||||||
component: Rich,
|
component: Overview,
|
||||||
label: 'Overview'
|
label: 'Overview'
|
||||||
}, {
|
}, {
|
||||||
path: '/basic',
|
path: '/basic',
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { parseElement, isNode, isEdge } from '../utils/graph';
|
|||||||
import { Elements, Node, Edge } from '../types';
|
import { Elements, Node, Edge } from '../types';
|
||||||
|
|
||||||
const useElementUpdater = (elements: Elements): void => {
|
const useElementUpdater = (elements: Elements): void => {
|
||||||
const state = useStoreState(s => ({
|
const state = useStoreState((s) => ({
|
||||||
nodes: s.nodes,
|
nodes: s.nodes,
|
||||||
edges: s.edges,
|
edges: s.edges,
|
||||||
transform: s.transform,
|
transform: s.transform,
|
||||||
@@ -14,37 +14,51 @@ const useElementUpdater = (elements: Elements): void => {
|
|||||||
snapGrid: s.snapGrid,
|
snapGrid: s.snapGrid,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const setNodes = useStoreActions(a => a.setNodes);
|
const setNodes = useStoreActions((a) => a.setNodes);
|
||||||
const setEdges = useStoreActions(a => a.setEdges);
|
const setEdges = useStoreActions((a) => a.setEdges);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const nodes = elements.filter(isNode) as Node[];
|
const nodes = elements.filter(isNode) as Node[];
|
||||||
const edges = elements
|
const edges = elements
|
||||||
.filter(isEdge)
|
.filter(isEdge)
|
||||||
.map(e =>
|
.map((e) => parseElement(e, state.transform, state.snapToGrid, state.snapGrid)) as Edge[];
|
||||||
parseElement(e, state.transform, state.snapToGrid, state.snapGrid)
|
|
||||||
) as Edge[];
|
|
||||||
|
|
||||||
const nextNodes = nodes.map(propNode => {
|
const nextNodes = nodes.map((propNode) => {
|
||||||
const existingNode = state.nodes.find(n => n.id === propNode.id);
|
const existingNode = state.nodes.find((n) => n.id === propNode.id);
|
||||||
|
|
||||||
if (existingNode) {
|
if (existingNode) {
|
||||||
const data = !isEqual(existingNode.data, propNode.data)
|
const data = !isEqual(existingNode.data, propNode.data)
|
||||||
? { ...existingNode.data, ...propNode.data }
|
? { ...existingNode.data, ...propNode.data }
|
||||||
: existingNode.data;
|
: existingNode.data;
|
||||||
|
|
||||||
|
const style = !isEqual(existingNode.style, propNode.style)
|
||||||
|
? { ...existingNode.style, ...propNode.style }
|
||||||
|
: existingNode.style;
|
||||||
|
|
||||||
|
const positionChanged =
|
||||||
|
existingNode.position.x !== propNode.position.x || existingNode.position.y !== propNode.position.y;
|
||||||
|
|
||||||
|
if (positionChanged) {
|
||||||
|
return {
|
||||||
|
...existingNode,
|
||||||
|
__rg: {
|
||||||
|
...existingNode.__rg,
|
||||||
|
position: propNode.position,
|
||||||
|
},
|
||||||
|
position: propNode.position,
|
||||||
|
data,
|
||||||
|
style,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...existingNode,
|
...existingNode,
|
||||||
data,
|
data,
|
||||||
|
style,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseElement(
|
return parseElement(propNode, state.transform, state.snapToGrid, state.snapGrid);
|
||||||
propNode,
|
|
||||||
state.transform,
|
|
||||||
state.snapToGrid,
|
|
||||||
state.snapGrid
|
|
||||||
);
|
|
||||||
}) as Node[];
|
}) as Node[];
|
||||||
|
|
||||||
const nodesChanged: boolean = !isEqual(state.nodes, nextNodes);
|
const nodesChanged: boolean = !isEqual(state.nodes, nextNodes);
|
||||||
@@ -57,7 +71,7 @@ const useElementUpdater = (elements: Elements): void => {
|
|||||||
if (edgesChanged) {
|
if (edgesChanged) {
|
||||||
setEdges(edges);
|
setEdges(edges);
|
||||||
}
|
}
|
||||||
});
|
}, [elements, state.nodes, state.edges]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useElementUpdater;
|
export default useElementUpdater;
|
||||||
|
|||||||
Reference in New Issue
Block a user