refactor(contexts): create connection context

This commit is contained in:
moklick
2019-08-01 16:05:10 +02:00
parent c6c65669e9
commit 7fc2acf0fb
14 changed files with 272 additions and 249 deletions
+27
View File
@@ -0,0 +1,27 @@
import React, { createContext, useState, memo } from 'react';
export const ConnectionContext = createContext({});
export const Provider = memo(({ onConnect, children }) => {
const [sourceId, setSourceId] = useState(null);
const [position, setPosition] = useState({ x:0, y: 0 });
const connectionContext = {
sourceId,
setSourceId,
position,
setPosition,
onConnect
};
return (
<ConnectionContext.Provider value={connectionContext}>
{children}
</ConnectionContext.Provider>
);
});
Provider.displayName = 'ConnectionProvider';
Provider.whyDidYouRender = false;
export const { Consumer } = ConnectionContext;
+2 -3
View File
@@ -7,7 +7,6 @@ export default (props) => {
setSourceNode(props.nodes.find(n => n.id === props.connectionSourceId));
}, []);
if (!sourceNode) {
return null;
}
@@ -21,8 +20,8 @@ export default (props) => {
const sourceX = sourceNode.__rg.position.x + sourceHandleX;
const sourceY = sourceNode.__rg.position.y + sourceHandleY;
const targetX = (props.connectionPosition.x * (1 / props.transform[2])) - (props.transform[0] * (1 / props.transform[2]));
const targetY = (props.connectionPosition.y * (1 / props.transform[2])) - (props.transform[1] * (1 / props.transform[2]));
const targetX = (props.connectionPositionX * (1 / props.transform[2])) - (props.transform[0] * (1 / props.transform[2]));
const targetY = (props.connectionPositionY * (1 / props.transform[2])) - (props.transform[1] * (1 / props.transform[2]));
let dAttr = '';
+5 -3
View File
@@ -1,9 +1,9 @@
import React, { memo, useContext } from 'react';
import { GraphContext } from '../GraphContext';
import { ConnectionContext } from '../ConnectionContext';
import ConnectionLine from '../ConnectionLine';
function getEdgePositions(sourceNode, targetNode) {
const hasSourceHandle = !!sourceNode.__rg.handleBounds.source;
const hasTargetHandle = !!targetNode.__rg.handleBounds.target;
@@ -73,6 +73,7 @@ function renderEdge(e, props, graphContext) {
const EdgeRenderer = memo((props) => {
const graphContext = useContext(GraphContext);
const { position, sourceId : connectionSourceId } = useContext(ConnectionContext);
const {
width, height, connectionLineStyle, connectionLineType
} = props;
@@ -81,7 +82,7 @@ const EdgeRenderer = memo((props) => {
return null;
}
const { transform, edges, nodes, connectionSourceId, connectionPosition } = graphContext.state;
const { transform, edges, nodes } = graphContext.state;
const transformStyle = `translate(${transform[0]},${transform[1]}) scale(${transform[2]})`;
return (
@@ -96,7 +97,8 @@ const EdgeRenderer = memo((props) => {
<ConnectionLine
nodes={nodes}
connectionSourceId={connectionSourceId}
connectionPosition={connectionPosition}
connectionPositionX={position.x}
connectionPositionY={position.y}
transform={transform}
connectionLineStyle={connectionLineStyle}
connectionLineType={connectionLineType}
+17 -14
View File
@@ -3,6 +3,7 @@ import * as d3Zoom from 'd3-zoom';
import { select, event } from 'd3-selection';
import ReactSizeMe from 'react-sizeme';
import { Provider } from '../ConnectionContext';
import { GraphContext } from '../GraphContext';
import NodeRenderer from '../NodeRenderer';
import EdgeRenderer from '../EdgeRenderer';
@@ -10,7 +11,7 @@ import UserSelection from '../UserSelection';
import NodesSelection from '../NodesSelection';
import {
updateTransform, updateSize, initD3, fitView,
zoomIn, zoomOut, setNodesSelection, setConnectionPos
zoomIn, zoomOut, setNodesSelection
} from '../state/actions';
import { useKeyPress } from '../hooks';
@@ -79,19 +80,21 @@ const GraphView = memo((props) => {
return (
<div className="react-graph__renderer">
<NodeRenderer
nodeTypes={props.nodeTypes}
onElementClick={props.onElementClick}
onNodeDragStop={props.onNodeDragStop}
/>
<EdgeRenderer
width={state.width}
height={state.height}
edgeTypes={props.edgeTypes}
onElementClick={props.onElementClick}
connectionLineType={props.connectionLineType}
connectionLineStyle={props.connectionLineStyle}
/>
<Provider onConnect={props.onConnect}>
<NodeRenderer
nodeTypes={props.nodeTypes}
onElementClick={props.onElementClick}
onNodeDragStop={props.onNodeDragStop}
/>
<EdgeRenderer
width={state.width}
height={state.height}
edgeTypes={props.edgeTypes}
onElementClick={props.onElementClick}
connectionLineType={props.connectionLineType}
connectionLineStyle={props.connectionLineStyle}
/>
</Provider>
{shiftPressed && <UserSelection />}
{state.nodesSelectionActive && <NodesSelection />}
<div
+14 -9
View File
@@ -1,15 +1,20 @@
import React, { memo } from 'react';
import cx from 'classnames';
import { setConnecting, setConnectionPos } from '../../state/actions';
function onMouseDown(evt, { nodeId, dispatch, onConnect, isTarget }) {
function onMouseDown(evt, { nodeId, setSourceId, setPosition, onConnect, isTarget }) {
const containerBounds = document.querySelector('.react-graph').getBoundingClientRect();
const connectionPosition = { x: evt.clientX - containerBounds.x, y: evt.clientY - containerBounds.y };
dispatch(setConnecting({ connectionPosition, connectionSourceId: nodeId }))
setPosition({
x: evt.clientX - containerBounds.x,
y: evt.clientY - containerBounds.y,
});
setSourceId(nodeId);
function onMouseMove(evt) {
dispatch(setConnectionPos({ x: evt.clientX - containerBounds.x, y: evt.clientY - containerBounds.y }));
setPosition({
x: evt.clientX - containerBounds.x,
y: evt.clientY - containerBounds.y,
});
}
function onMouseUp(evt) {
@@ -25,7 +30,7 @@ function onMouseDown(evt, { nodeId, dispatch, onConnect, isTarget }) {
}
}
dispatch(setConnecting({ connectionSourceId: false }));
setSourceId(null);
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
}
@@ -34,7 +39,7 @@ function onMouseDown(evt, { nodeId, dispatch, onConnect, isTarget }) {
document.addEventListener('mouseup', onMouseUp)
}
const BaseHandle = memo(({ source, target, nodeId, onConnect, dispatch, className = null, ...rest }) => {
const BaseHandle = memo(({ source, target, nodeId, onConnect, setSourceId, setPosition, className = null, ...rest }) => {
const handleClasses = cx(
'react-graph__handle',
className,
@@ -45,7 +50,7 @@ const BaseHandle = memo(({ source, target, nodeId, onConnect, dispatch, classNam
<div
data-nodeid={nodeId}
className={handleClasses}
onMouseDown={evt => onMouseDown(evt, { nodeId, dispatch, onConnect, isTarget: target })}
onMouseDown={evt => onMouseDown(evt, { nodeId, setSourceId, setPosition, onConnect, isTarget: target })}
{...rest}
/>
);
+4 -3
View File
@@ -2,17 +2,18 @@ import React, { memo, useContext } from 'react';
import BaseHandle from './BaseHandle';
import NodeIdContext from '../NodeIdContext'
import { GraphContext } from '../../GraphContext';
import { ConnectionContext } from '../../ConnectionContext';
export default memo((props) => {
const nodeId = useContext(NodeIdContext);
const { dispatch, onConnect } = useContext(GraphContext);
const { setPosition, setSourceId, onConnect } = useContext(ConnectionContext);
return (
<BaseHandle
source
nodeId={nodeId}
dispatch={dispatch}
setPosition={setPosition}
setSourceId={setSourceId}
onConnect={onConnect}
{...props}
/>
+4 -4
View File
@@ -1,18 +1,19 @@
import React, { memo, useContext } from 'react';
import BaseHandle from './BaseHandle';
import { GraphContext } from '../../GraphContext';
import { ConnectionContext } from '../../ConnectionContext';
import NodeIdContext from '../NodeIdContext'
const TargetHandle = memo((props) => {
const nodeId = useContext(NodeIdContext);
const { dispatch, onConnect } = useContext(GraphContext);
const { setPosition, setSourceId, onConnect } = useContext(ConnectionContext);
return (
<BaseHandle
target
nodeId={nodeId}
dispatch={dispatch}
setPosition={setPosition}
setSourceId={setSourceId}
onConnect={onConnect}
{...props}
/>
@@ -23,4 +24,3 @@ TargetHandle.displayName = 'TargetHandle';
TargetHandle.whyDidYouRender = false;
export default TargetHandle;
+2 -1
View File
@@ -37,7 +37,7 @@ class ReactGraph extends PureComponent {
return (
<div style={style} className="react-graph">
<Provider elements={elements} onConnect={onConnect}>
<Provider elements={elements}>
<GraphView
onLoad={onLoad}
onMove={onMove}
@@ -48,6 +48,7 @@ class ReactGraph extends PureComponent {
edgeTypes={this.edgeTypes}
connectionLineType={connectionLineType}
connectionLineStyle={connectionLineStyle}
onConnect={onConnect}
/>
<GlobalKeyHandler
onElementsRemove={onElementsRemove}
+2 -14
View File
@@ -2,8 +2,7 @@ import {
UPDATE_TRANSFORM, UPDATE_SIZE, SET_NODES, SET_EDGES,
UPDATE_NODE_DATA, UPDATE_NODE_POS, INIT_D3, FIT_VIEW,
UPDATE_SELECTION, SET_SELECTION, SET_NODES_SELECTION,
SET_SELECTED_ELEMENTS, REMOVE_NODES, ZOOM_IN, ZOOM_OUT,
SET_CONNECTING, SET_CONNECTION_POS
SET_SELECTED_ELEMENTS, REMOVE_NODES, ZOOM_IN, ZOOM_OUT
} from './index';
export const updateTransform = (transform) => {
@@ -99,15 +98,4 @@ export const updateSelection = (selection) => {
selection
}
};
};
export const setConnecting = ({ connectionSourceId, connectionPosition = false}) => {
return { type: SET_CONNECTING, payload: { connectionSourceId, connectionPosition }};
};
export const setConnectionPos = ({ x, y }) => {
return {
type: SET_CONNECTION_POS,
payload: { connectionPosition: { x, y } }
};
};
};
+1 -14
View File
@@ -18,8 +18,6 @@ export const SET_SELECTION = 'SET_SELECTION';
export const SET_NODES_SELECTION = 'SET_NODES_SELECTION';
export const SET_SELECTED_ELEMENTS = 'SET_SELECTED_ELEMENTS';
export const REMOVE_NODES = 'REMOVE_NODES';
export const SET_CONNECTING = 'SET_CONNECTING';
export const SET_CONNECTION_POS = 'SET_CONNECTION_POS';
export const initialState = {
width: 0,
@@ -36,10 +34,7 @@ export const initialState = {
nodesSelectionActive: false,
selectionActive: false,
selection: {},
connectionSourceId: null,
connectionPosition: { x: 0, y: 0 }
selection: {}
};
export const reducer = (state, action) => {
@@ -134,20 +129,12 @@ export const reducer = (state, action) => {
return { ...state, nodes: nextNodes, edges: nextEdges };
}
case SET_CONNECTING: {
if (!action.payload.connectionPosition) {
return { ...state, connectionSourceId: action.payload.connectionSourceId };
}
return { ...state, ...action.payload };
}
case SET_NODES:
case SET_EDGES:
case UPDATE_TRANSFORM:
case INIT_D3:
case UPDATE_SIZE:
case SET_SELECTION:
case SET_CONNECTION_POS:
return { ...state, ...action.payload };
default:
return state;