From 1dbeebfb27a49ade75c6426d3573e6d66a8ecb6a Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 17 Jul 2019 17:34:42 +0200 Subject: [PATCH] fix(elements): change data from outside --- example/SimpleGraph.js | 1 - src/EdgeRenderer/Edge.js | 8 ++--- src/GraphContext/index.js | 5 +++- src/NodeRenderer/NodeTypes/wrapNode.js | 18 ++++++----- src/NodeRenderer/index.js | 4 +-- src/graph-utils.js | 41 +++++++++++++++++++------- src/index.js | 6 ++-- src/state/index.js | 9 ++++-- 8 files changed, 59 insertions(+), 33 deletions(-) diff --git a/example/SimpleGraph.js b/example/SimpleGraph.js index 16635420..d958764b 100644 --- a/example/SimpleGraph.js +++ b/example/SimpleGraph.js @@ -82,7 +82,6 @@ class App extends PureComponent { } render() { - console.log(this.state.elements); return ( { const { targetNode, sourceNode } = props; - const sourceX = sourceNode.position.x + (sourceNode.data.__width / 2); - const sourceY = sourceNode.position.y + sourceNode.data.__height; + const sourceX = sourceNode.__rg.position.x + (sourceNode.__rg.width / 2); + const sourceY = sourceNode.__rg.position.y + sourceNode.__rg.height; - const targetX = targetNode.position.x + (targetNode.data.__width / 2); - const targetY = targetNode.position.y; + const targetX = targetNode.__rg.position.x + (targetNode.__rg.width / 2); + const targetY = targetNode.__rg.position.y; return ( { const existingNode = state.nodes.find(n => n.data.id === propNode.data.id); if (existingNode) { - return Object.assign(propNode, existingNode); + return { + ...existingNode, + data: { ...existingNode.data, ...propNode.data } + }; } return propNode; diff --git a/src/NodeRenderer/NodeTypes/wrapNode.js b/src/NodeRenderer/NodeTypes/wrapNode.js index c65cfadb..70b2d503 100644 --- a/src/NodeRenderer/NodeTypes/wrapNode.js +++ b/src/NodeRenderer/NodeTypes/wrapNode.js @@ -1,4 +1,4 @@ -import React, { useEffect, useRef, useContext } from 'react'; +import React, { useEffect, useRef, useContext, useState } from 'react'; import ReactDraggable from 'react-draggable'; import cx from 'classnames'; @@ -8,10 +8,13 @@ import { updateNodeData, updateNodePos } from '../../state/actions'; const isInputTarget = (e) => ['INPUT', 'SELECT', 'TEXTAREA'].includes(e.target.nodeName); export default NodeComponent => (props) => { - const { position, data, onNodeClick } = props; - const { id } = data; const nodeElement = useRef(null); const graphContext = useContext(GraphContext); + const [offset, setOffset] = useState({ x: 0, y: 0 }); + + const { data, onNodeClick, __rg } = props; + const { position } = __rg; + const { id } = data; const [ x, y, k ] = graphContext.state.transform; const selected = graphContext.state.selectedNodes.includes(id); const nodeClasses = cx('react-graph__node', { selected }); @@ -21,7 +24,7 @@ export default NodeComponent => (props) => { const unscaledWith = Math.round(bounds.width * (1 / k)); const unscaledHeight = Math.round(bounds.height * (1 / k)); - graphContext.dispatch(updateNodeData(id, { __width: unscaledWith, __height: unscaledHeight })); + graphContext.dispatch(updateNodeData(id, { width: unscaledWith, height: unscaledHeight })); }, []); return ( @@ -39,18 +42,17 @@ export default NodeComponent => (props) => { const offsetX = unscaledPos.x - position.x - x; const offsetY = unscaledPos.y - position.y - y; - graphContext.dispatch(updateNodeData(id, { __offsetX: offsetX, __offsetY: offsetY })); + setOffset({ x: offsetX, y: offsetY }); }} onDrag={(e, d) => { - const { __offsetX = 0, __offsetY = 0 } = data; const unscaledPos = { x: e.clientX * (1 / k), y: e.clientY * (1 / k) } graphContext.dispatch(updateNodePos(id, { - x: unscaledPos.x - x - __offsetX, - y: unscaledPos.y - y - __offsetY + x: unscaledPos.x - x - offset.x, + y: unscaledPos.y - y - offset.y })); }} scale={k} diff --git a/src/NodeRenderer/index.js b/src/NodeRenderer/index.js index c70820d8..cbd501f2 100644 --- a/src/NodeRenderer/index.js +++ b/src/NodeRenderer/index.js @@ -15,10 +15,8 @@ class NodeRenderer extends PureComponent { return ( ); } diff --git a/src/graph-utils.js b/src/graph-utils.js index 516d3e19..4b871b2e 100644 --- a/src/graph-utils.js +++ b/src/graph-utils.js @@ -1,25 +1,43 @@ export const isEdge = element => element.data.source && element.data.target; -export const separateElements = elements => ({ - nodes: elements.filter(e => !isEdge(e)), - edges: elements.filter(e => isEdge(e)) +export const parseElements = e => ({ + ...e, + __rg: { + position: e.position, + width: null, + height: null + } }); +export const separateElements = (res, element) => { + res.edges = res.edges ? res.edges : []; + res.nodes = res.nodes ? res.nodes : []; + + if (isEdge(element)) { + res.edges.push(element); + } else { + res.nodes.push(element); + } + + return res; +}; + export const getBoundingBox = (nodes) => { const bbox = nodes.reduce((res, node) => { - const x2 = node.position.x + node.data.__width; - const y2 = node.position.y + node.data.__height; + const { position } = node.__rg; + const x2 = position.x + node.__rg.width; + const y2 = position.y + node.__rg.height; - if (node.position.x < res.minX) { - res.minX = node.position.x; + if (position.x < res.minX) { + res.minX = position.x; } if (x2 > res.maxX) { res.maxX = x2; } - if (node.position.y < res.minY) { - res.minY = node.position.y; + if (position.y < res.minY) { + res.minY = position.y; } if (y2 > res.maxY) { @@ -58,10 +76,11 @@ export const getNodesInside = (nodes, bbox, transform = [0, 0, 1]) => { }; const bboxWidth = bbox.width * (1 / transform[2]); const bboxHeight = bbox.height * (1 / transform[2]); + const { position, width, height } = n.__rg; return ( - (n.position.x > bboxPos.x && (n.position.x + n.data.__width) < (bboxPos.x + bboxWidth)) && - (n.position.y > bboxPos.y && (n.position.y + n.data.__height) < (bboxPos.y + bboxHeight)) + (position.x > bboxPos.x && (position.x + width) < (bboxPos.x + bboxWidth)) && + (position.y > bboxPos.y && (position.y + height) < (bboxPos.y + bboxHeight)) ); }); }; diff --git a/src/index.js b/src/index.js index d0c51691..4228302a 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,6 @@ import React, { PureComponent } from 'react'; -import { separateElements } from './graph-utils'; +import { parseElements, separateElements } from './graph-utils'; import GraphView from './GraphView'; import { Provider } from './GraphContext'; import { createNodeTypes } from './NodeRenderer/utils'; @@ -23,7 +23,9 @@ class ReactGraph extends PureComponent { style, onNodeClick, children, onLoad, onMove, onChange, elements } = this.props; - const { nodes, edges } = separateElements(elements); + const { nodes, edges } = elements + .map(parseElements) + .reduce(separateElements, {}); return (
diff --git a/src/state/index.js b/src/state/index.js index ba0b0bf7..854e1fa9 100644 --- a/src/state/index.js +++ b/src/state/index.js @@ -36,8 +36,8 @@ export const reducer = (state, action) => { ...state, nodes: state.nodes.map((n) => { if (n.data.id === action.payload.id) { - n.data = { - ...n.data, + n.__rg = { + ...n.__rg, ...action.payload.data }; } @@ -50,7 +50,10 @@ export const reducer = (state, action) => { ...state, nodes: state.nodes.map((n) => { if (n.data.id === action.payload.id) { - n.position = action.payload.pos; + n.__rg = { + ...n.__rg, + position: action.payload.pos + }; } return n;