Skip to content

Commit

Permalink
refactor(edges): only redraw moved edges
Browse files Browse the repository at this point in the history
  • Loading branch information
moklick committed Jul 31, 2019
1 parent ec7231e commit 6e71591
Show file tree
Hide file tree
Showing 9 changed files with 436 additions and 403 deletions.
369 changes: 189 additions & 180 deletions dist/ReactGraph.js

Large diffs are not rendered by default.

281 changes: 137 additions & 144 deletions example/build/example.e31bb0bc.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion example/build/example.e31bb0bc.js.map

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions src/EdgeRenderer/EdgeTypes/wrapEdge.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import React, { useContext, memo } from 'react';
import React, { memo } from 'react';
import cx from 'classnames';

import { GraphContext } from '../../GraphContext';
import { setSelectedElements } from '../../state/actions';
import { isEdge } from '../../graph-utils';

const isInput = e => ['INPUT', 'SELECT', 'TEXTAREA'].includes(e.target.nodeName);

export default EdgeComponent => memo((props) => {
const { state, dispatch } = useContext(GraphContext);
const { source, target, animated, type, onClick } = props;
const selected = state.selectedElements
const {
source, target, animated, type,
dispatch, selectedElements, onClick
} = props;
const selected = selectedElements
.filter(e => isEdge(e))
.find(e => e.source === source && e.target === target);
const edgeClasses = cx('react-graph__edge', { selected, animated: animated });
Expand Down
125 changes: 65 additions & 60 deletions src/EdgeRenderer/index.js
Original file line number Diff line number Diff line change
@@ -1,73 +1,78 @@
import React, { PureComponent } from 'react';
import React, { memo, useContext } from 'react';

import { Consumer } from '../GraphContext';
import { GraphContext } from '../GraphContext';
import ConnectionLine from '../ConnectionLine';

class EdgeRenderer extends PureComponent {
renderEdge(e, nodes, onElementClick) {
const edgeType = e.type || 'default';
const sourceNode = nodes.find(n => n.id === e.source);
const targetNode = nodes.find(n => n.id === e.target);
function renderEdge(e, props, graphContext) {
const edgeType = e.type || 'default';
const sourceNode = graphContext.state.nodes.find(n => n.id === e.source);
const targetNode = graphContext.state.nodes.find(n => n.id === e.target);

if (!sourceNode) {
throw new Error(`couldn't create edge for source id: ${e.source}`);
}
if (!sourceNode) {
throw new Error(`couldn't create edge for source id: ${e.source}`);
}

if (!targetNode) {
throw new Error(`couldn't create edge for target id: ${e.target}`);
}
if (!targetNode) {
throw new Error(`couldn't create edge for target id: ${e.target}`);
}

const EdgeComponent = this.props.edgeTypes[edgeType] || this.props.edgeTypes.default;
const EdgeComponent = props.edgeTypes[edgeType] || props.edgeTypes.default;

return (
<EdgeComponent
key={`${e.source}-${e.target}`}
sourceNode={sourceNode}
targetNode={targetNode}
onClick={onElementClick}
{...e}
/>
);
}
return (
<EdgeComponent
key={`${e.source}-${e.target}`}
type={e.type}
sourceNode={sourceNode}
targetNode={targetNode}
onClick={props.onElementClick}
selectedElements={graphContext.state.selectedElements}
dispatch={graphContext.dispatch}
animated={e.animated}
style={e.style}
source={e.source}
target={e.target}
sourceNodeX={sourceNode.__rg.position.x}
sourceNodeY={sourceNode.__rg.position.y}
targetNodeX={targetNode.__rg.position.x}
targeteNodeY={targetNode.__rg.position.y}
/>
);
}

render() {
const {
width, height, onElementClick,
connectionLineStyle, connectionLineType
} = this.props;
const EdgeRenderer = memo((props) => {
const graphContext = useContext(GraphContext);
const {
width, height, connectionLineStyle, connectionLineType
} = props;

if (!width) {
return null;
}
if (!width) {
return null;
}

const { transform, edges, nodes, connectionSourceId, connectionPosition } = graphContext.state;
const transformStyle = `translate(${transform[0]},${transform[1]}) scale(${transform[2]})`;

return (
<Consumer>
{({ state }) => (
<svg
width={width}
height={height}
className="react-graph__edges"
>
<g
transform={`translate(${state.transform[0]},${state.transform[1]}) scale(${state.transform[2]})`}
>
{state.edges.map(e => this.renderEdge(e, state.nodes, onElementClick))}
{state.connectionSourceId && (
<ConnectionLine
nodes={state.nodes}
connectionSourceId={state.connectionSourceId}
connectionPosition={state.connectionPosition}
transform={state.transform}
connectionLineStyle={connectionLineStyle}
connectionLineType={connectionLineType}
/>
)}
</g>
</svg>
return (
<svg
width={width}
height={height}
className="react-graph__edges"
>
<g transform={transformStyle}>
{edges.map(e => renderEdge(e, props, graphContext))}
{connectionSourceId && (
<ConnectionLine
nodes={nodes}
connectionSourceId={connectionSourceId}
connectionPosition={connectionPosition}
transform={transform}
connectionLineStyle={connectionLineStyle}
connectionLineType={connectionLineType}
/>
)}
</Consumer>
);
}
}
</g>
</svg>
);
});

export default EdgeRenderer;
8 changes: 2 additions & 6 deletions src/NodeRenderer/HandleTypes/BaseHandle.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React, { memo, useContext } from 'react';
import React, { memo } from 'react';
import cx from 'classnames';

import NodeIdContext from '../NodeIdContext'
import { GraphContext } from '../../GraphContext';
import { setConnecting, setConnectionPos } from '../../state/actions';

function onMouseDown(evt, { nodeId, dispatch, onConnect, isTarget }) {
Expand Down Expand Up @@ -37,9 +35,7 @@ function onMouseDown(evt, { nodeId, dispatch, onConnect, isTarget }) {
document.addEventListener('mouseup', onMouseUp)
}

export default memo(({ source, target, className = null, ...rest }) => {
const nodeId = useContext(NodeIdContext);
const { dispatch, onConnect } = useContext(GraphContext);
export default memo(({ source, target, nodeId, onConnect, dispatch, className = null, ...rest }) => {
const handleClasses = cx(
'react-graph__handle',
className,
Expand Down
19 changes: 17 additions & 2 deletions src/NodeRenderer/HandleTypes/SourceHandle.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
import React from 'react';
import React, { memo, useContext } from 'react';

import BaseHandle from './BaseHandle';
import NodeIdContext from '../NodeIdContext'
import { GraphContext } from '../../GraphContext';

export default props => <BaseHandle source {...props} />;
export default memo((props) => {
const nodeId = useContext(NodeIdContext);
const { dispatch, onConnect } = useContext(GraphContext);

return (
<BaseHandle
source
nodeId={nodeId}
dispatch={dispatch}
onConnect={onConnect}
{...props}
/>
);
});
19 changes: 17 additions & 2 deletions src/NodeRenderer/HandleTypes/TargetHandle.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
import React from 'react';
import React, { memo, useContext } from 'react';

import BaseHandle from './BaseHandle';
import { GraphContext } from '../../GraphContext';
import NodeIdContext from '../NodeIdContext'

export default props => <BaseHandle target {...props} />;
export default memo((props) => {
const nodeId = useContext(NodeIdContext);
const { dispatch, onConnect } = useContext(GraphContext);

return (
<BaseHandle
target
nodeId={nodeId}
dispatch={dispatch}
onConnect={onConnect}
{...props}
/>
);
});

5 changes: 2 additions & 3 deletions src/NodeRenderer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,12 @@ function renderNode(d, props, graphContext) {
const NodeRenderer = memo((props) => {
const graphContext = useContext(GraphContext);
const { transform, nodes } = graphContext.state;
const transformStyle = { transform : `translate(${transform[0]}px,${transform[1]}px) scale(${transform[2]})` };

return (
<div
className="react-graph__nodes"
style={{
transform: `translate(${transform[0]}px,${transform[1]}px) scale(${transform[2]})`
}}
style={transformStyle}
>
{nodes.map(d => renderNode(d, props, graphContext))}
</div>
Expand Down

0 comments on commit 6e71591

Please sign in to comment.