refactor(nodeRenderer): dont use Context in nodes
This commit is contained in:
@@ -3,13 +3,13 @@ import React, { PureComponent } from 'react';
|
|||||||
import Graph, { isEdge, removeElements, getOutgoers, SourceHandle, TargetHandle } from '../src';
|
import Graph, { isEdge, removeElements, getOutgoers, SourceHandle, TargetHandle } from '../src';
|
||||||
// import Graph from '../dist/ReactGraph';
|
// import Graph from '../dist/ReactGraph';
|
||||||
|
|
||||||
const SpecialNode = ({ data, onChange, styles }) => (
|
const SpecialNode = ({ data, styles }) => (
|
||||||
<div
|
<div
|
||||||
style={{ background: '#FFCC00', padding: 10, borderRadius: 2, ...styles }}
|
style={{ background: '#FFCC00', padding: 10, borderRadius: 2, ...styles }}
|
||||||
>
|
>
|
||||||
<TargetHandle style={{ left: 10, background: '#999' }} />
|
<TargetHandle style={{ left: 10, background: '#999' }} />
|
||||||
<div>I am <strong>special</strong>!<br />{data.label}</div>
|
<div>I am <strong>special</strong>!<br />{data.label}</div>
|
||||||
<select onChange={(e) => onChange(e.target.value, data)}>
|
<select onChange={(e) => data.onChange(e.target.value, data)}>
|
||||||
<option value="1">1</option>
|
<option value="1">1</option>
|
||||||
<option value="2">2</option>
|
<option value="2">2</option>
|
||||||
<option value="3">3</option>
|
<option value="3">3</option>
|
||||||
@@ -48,7 +48,7 @@ class App extends PureComponent {
|
|||||||
{ id: '3', data: { label: '3 I bring my own style' }, position: { x: 100, y: 200 }, style: { background: '#eee', color: '#222', border: '1px solid #bbb' } },
|
{ id: '3', data: { label: '3 I bring my own style' }, position: { x: 100, y: 200 }, style: { background: '#eee', color: '#222', border: '1px solid #bbb' } },
|
||||||
{ id: '4', type: 'output', data: { label: '4 nody nodes' }, position: { x: 50, y: 300 } },
|
{ id: '4', type: 'output', data: { label: '4 nody nodes' }, position: { x: 50, y: 300 } },
|
||||||
{ id: '5', type: 'default', data: { label: '5 Another node'}, position: { x: 400, y: 300 } },
|
{ id: '5', type: 'default', data: { label: '5 Another node'}, position: { x: 400, y: 300 } },
|
||||||
{ id: '6', type: 'special', onChange, data: { label: '6 no option selected' }, position: { x: 425, y: 375 } },
|
{ id: '6', type: 'special', data: { onChange, label: '6 no option selected' }, position: { x: 425, y: 375 } },
|
||||||
{ id: '7', type: 'output', data: { label: '7 output' }, position: { x: 250, y: 500 } },
|
{ id: '7', type: 'output', data: { label: '7 output' }, position: { x: 250, y: 500 } },
|
||||||
{ source: '1', target: '2', animated: true },
|
{ source: '1', target: '2', animated: true },
|
||||||
{ source: '2', target: '3' },
|
{ source: '2', target: '3' },
|
||||||
|
|||||||
+102
-112
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -212,7 +212,7 @@ var parent = module.bundle.parent;
|
|||||||
if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== 'undefined') {
|
if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== 'undefined') {
|
||||||
var hostname = "" || location.hostname;
|
var hostname = "" || location.hostname;
|
||||||
var protocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
var protocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
||||||
var ws = new WebSocket(protocol + '://' + hostname + ':' + "51139" + '/');
|
var ws = new WebSocket(protocol + '://' + hostname + ':' + "58449" + '/');
|
||||||
|
|
||||||
ws.onmessage = function (event) {
|
ws.onmessage = function (event) {
|
||||||
checkedAssets = {};
|
checkedAssets = {};
|
||||||
|
|||||||
Generated
+9
-2
@@ -2146,6 +2146,14 @@
|
|||||||
"@xtuc/long": "4.2.2"
|
"@xtuc/long": "4.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@welldone-software/why-did-you-render": {
|
||||||
|
"version": "3.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@welldone-software/why-did-you-render/-/why-did-you-render-3.2.3.tgz",
|
||||||
|
"integrity": "sha512-dUMkjsVsCfIo+IEmiMyb/FGKVbXrzbGqLvDTCn0ad5drNmD+BGoU/7Z+Nc7ckkV0F1G4vzs1XQrAcIxyPa8Ssw==",
|
||||||
|
"requires": {
|
||||||
|
"lodash": "^4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@xtuc/ieee754": {
|
"@xtuc/ieee754": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
|
||||||
@@ -8442,8 +8450,7 @@
|
|||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.14",
|
"version": "4.17.14",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.14.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.14.tgz",
|
||||||
"integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==",
|
"integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"lodash-es": {
|
"lodash-es": {
|
||||||
"version": "4.17.15",
|
"version": "4.17.15",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
"main": "dist/ReactGraph.js",
|
"main": "dist/ReactGraph.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@welldone-software/why-did-you-render": "^3.2.3",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"d3-selection": "^1.4.0",
|
"d3-selection": "^1.4.0",
|
||||||
"d3-zoom": "^1.7.3",
|
"d3-zoom": "^1.7.3",
|
||||||
|
|||||||
@@ -41,10 +41,11 @@ export const Provider = (props) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const graphContext = {
|
const graphContext = {
|
||||||
state,
|
state,
|
||||||
|
dispatch,
|
||||||
onConnect,
|
onConnect,
|
||||||
dispatch
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import React, { useEffect, useRef, useContext, useState, memo } from 'react';
|
import React, { useEffect, useRef, useState, memo } from 'react';
|
||||||
import ReactDraggable from 'react-draggable';
|
import ReactDraggable from 'react-draggable';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
|
|
||||||
import { GraphContext } from '../../GraphContext';
|
|
||||||
import { updateNodeData, updateNodePos, setSelectedElements } from '../../state/actions';
|
import { updateNodeData, updateNodePos, setSelectedElements } from '../../state/actions';
|
||||||
import { isNode } from '../../graph-utils';
|
import { isNode } from '../../graph-utils';
|
||||||
import { Provider } from '../NodeIdContext';
|
import { Provider } from '../NodeIdContext';
|
||||||
@@ -60,36 +59,38 @@ const onDrag = (evt, { dispatch, id, offset, transform }) => {
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const onNodeClick = (evt, { onClick, dispatch, data, id, type, position }) => {
|
const onNodeClick = (evt, { onClick, dispatch, id, type, position, data }) => {
|
||||||
if (isInput(evt)) {
|
if (isInput(evt)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(setSelectedElements({ data, id }));
|
const node = { id, type, position, data }
|
||||||
onClick({ id, type, data, position });
|
|
||||||
|
dispatch(setSelectedElements(node));
|
||||||
|
onClick(node);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onStop = ({ onNodeDragStop, id, type, data, position }) => {
|
const onStop = ({ onNodeDragStop, id, type, position, data }) => {
|
||||||
onNodeDragStop({
|
onNodeDragStop({
|
||||||
id,
|
id, type, position, data
|
||||||
type,
|
|
||||||
data,
|
|
||||||
position
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NodeComponent => memo((props) => {
|
export default NodeComponent => memo((props) => {
|
||||||
const nodeElement = useRef(null);
|
const nodeElement = useRef(null);
|
||||||
const { state, dispatch } = useContext(GraphContext);
|
|
||||||
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
||||||
const {
|
const {
|
||||||
data, onClick, type, id, __rg, onNodeDragStop
|
id, type, data, transform, xPos, yPos, selectedElements,
|
||||||
|
dispatch, getNodeById, onClick, onNodeDragStop
|
||||||
} = props;
|
} = props;
|
||||||
const { position } = __rg;
|
|
||||||
const [ x, y, k ] = state.transform;
|
console.log('render node', id);
|
||||||
const selected = state.selectedElements.filter(isNode).map(e => e.id).includes(id);
|
|
||||||
|
const position = { x: xPos, y: yPos };
|
||||||
|
const [ x, y, k ] = transform;
|
||||||
|
const selected = selectedElements.filter(isNode).map(e => e.id).includes(id);
|
||||||
const nodeClasses = cx('react-graph__node', { selected });
|
const nodeClasses = cx('react-graph__node', { selected });
|
||||||
const nodeStyle = { zIndex: selected ? 10 : 3, transform: `translate(${position.x}px,${position.y}px)` };
|
const nodeStyle = { zIndex: selected ? 10 : 3, transform: `translate(${xPos}px,${yPos}px)` };
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const bounds = nodeElement.current.getBoundingClientRect();
|
const bounds = nodeElement.current.getBoundingClientRect();
|
||||||
@@ -105,16 +106,16 @@ export default NodeComponent => memo((props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ReactDraggable.DraggableCore
|
<ReactDraggable.DraggableCore
|
||||||
onStart={evt => onStart(evt, { setOffset, transform: state.transform, position })}
|
onStart={evt => onStart(evt, { setOffset, transform, position })}
|
||||||
onDrag={evt => onDrag(evt, { dispatch, id, offset, transform: state.transform })}
|
onDrag={evt => onDrag(evt, { dispatch, id, offset, transform })}
|
||||||
onStop={() => onStop({ onNodeDragStop, id, type, data, position })}
|
onStop={() => onStop({ onNodeDragStop, id, type, position, data })}
|
||||||
scale={state.transform[2]}
|
scale={transform[2]}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={nodeClasses}
|
className={nodeClasses}
|
||||||
ref={nodeElement}
|
ref={nodeElement}
|
||||||
style={nodeStyle}
|
style={nodeStyle}
|
||||||
onClick={evt => onNodeClick(evt, { onClick, dispatch, data, id, type, position })}
|
onClick={evt => onNodeClick(evt, { getNodeById, onClick, dispatch, id, type, position, data })}
|
||||||
>
|
>
|
||||||
<Provider value={id}>
|
<Provider value={id}>
|
||||||
<NodeComponent {...props} selected={selected} />
|
<NodeComponent {...props} selected={selected} />
|
||||||
@@ -122,4 +123,5 @@ export default NodeComponent => memo((props) => {
|
|||||||
</div>
|
</div>
|
||||||
</ReactDraggable.DraggableCore>
|
</ReactDraggable.DraggableCore>
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|||||||
+43
-36
@@ -1,44 +1,51 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { memo, useContext } from 'react';
|
||||||
|
|
||||||
import { Consumer } from '../GraphContext';
|
import { GraphContext } from '../GraphContext';
|
||||||
|
|
||||||
class NodeRenderer extends PureComponent {
|
function renderNode(d, props, graphContext) {
|
||||||
|
const nodeType = d.type || 'default';
|
||||||
|
|
||||||
renderNode(d) {
|
if (!props.nodeTypes[nodeType]) {
|
||||||
const nodeType = d.type || 'default';
|
console.warn(`No node type found for type "${nodeType}". Using fallback type "default".`);
|
||||||
if (!this.props.nodeTypes[nodeType]) {
|
|
||||||
console.warn(`No node type found for type "${nodeType}". Using fallback type "default".`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const NodeComponent = this.props.nodeTypes[nodeType] || this.props.nodeTypes.default;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<NodeComponent
|
|
||||||
key={d.id}
|
|
||||||
onClick={this.props.onElementClick}
|
|
||||||
onNodeDragStop={this.props.onNodeDragStop}
|
|
||||||
onConnect={this.props.onConnect}
|
|
||||||
{...d}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
const NodeComponent = props.nodeTypes[nodeType] || props.nodeTypes.default;
|
||||||
return (
|
|
||||||
<Consumer>
|
return (
|
||||||
{({ state }) => (
|
<NodeComponent
|
||||||
<div
|
key={d.id}
|
||||||
className="react-graph__nodes"
|
id={d.id}
|
||||||
style={{
|
type={d.type}
|
||||||
transform: `translate(${state.transform[0]}px,${state.transform[1]}px) scale(${state.transform[2]})`
|
data={d.data}
|
||||||
}}
|
xPos={d.__rg.position.x}
|
||||||
>
|
yPos={d.__rg.position.y}
|
||||||
{state.nodes.map(d => this.renderNode(d))}
|
onClick={props.onElementClick}
|
||||||
</div>
|
onNodeDragStop={props.onNodeDragStop}
|
||||||
)}
|
dispatch={graphContext.dispatch}
|
||||||
</Consumer>
|
transform={graphContext.state.transform}
|
||||||
);
|
getNodeById={graphContext.getNodeById}
|
||||||
}
|
selectedElements={graphContext.state.selectedElements}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const NodeRenderer = memo((props) => {
|
||||||
|
const graphContext = useContext(GraphContext);
|
||||||
|
const { transform, nodes } = graphContext.state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="react-graph__nodes"
|
||||||
|
style={{
|
||||||
|
transform: `translate(${transform[0]}px,${transform[1]}px) scale(${transform[2]})`
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{nodes.map(d => renderNode(d, props, graphContext))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
NodeRenderer.displayName = 'NodeRenderer';
|
||||||
|
NodeRenderer.whyDidYouRender = false;
|
||||||
|
|
||||||
export default NodeRenderer;
|
export default NodeRenderer;
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
const whyDidYouRender = require('@welldone-software/why-did-you-render');
|
||||||
|
whyDidYouRender(React);
|
||||||
|
}
|
||||||
|
|
||||||
import { parseElements, separateElements } from '../graph-utils';
|
import { parseElements, separateElements } from '../graph-utils';
|
||||||
import GraphView from '../GraphView';
|
import GraphView from '../GraphView';
|
||||||
import GlobalKeyHandler from '../GlobalKeyHandler';
|
import GlobalKeyHandler from '../GlobalKeyHandler';
|
||||||
|
|||||||
Reference in New Issue
Block a user