refactor(edges): only redraw moved edges

This commit is contained in:
moklick
2019-07-31 16:29:04 +02:00
parent ec7231e42d
commit 6e71591cb8
9 changed files with 433 additions and 400 deletions
+68 -63
View File
@@ -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 (!targetNode) {
throw new Error(`couldn't create edge for target id: ${e.target}`);
}
const EdgeComponent = this.props.edgeTypes[edgeType] || this.props.edgeTypes.default;
return (
<EdgeComponent
key={`${e.source}-${e.target}`}
sourceNode={sourceNode}
targetNode={targetNode}
onClick={onElementClick}
{...e}
/>
);
if (!sourceNode) {
throw new Error(`couldn't create edge for source id: ${e.source}`);
}
render() {
const {
width, height, onElementClick,
connectionLineStyle, connectionLineType
} = this.props;
if (!width) {
return null;
}
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>
)}
</Consumer>
);
if (!targetNode) {
throw new Error(`couldn't create edge for target id: ${e.target}`);
}
const EdgeComponent = props.edgeTypes[edgeType] || props.edgeTypes.default;
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}
/>
);
}
const EdgeRenderer = memo((props) => {
const graphContext = useContext(GraphContext);
const {
width, height, connectionLineStyle, connectionLineType
} = props;
if (!width) {
return null;
}
const { transform, edges, nodes, connectionSourceId, connectionPosition } = graphContext.state;
const transformStyle = `translate(${transform[0]},${transform[1]}) scale(${transform[2]})`;
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}
/>
)}
</g>
</svg>
);
});
export default EdgeRenderer;