Skip to content

Commit

Permalink
feat(renderer): move interactions into seperate wrapper component
Browse files Browse the repository at this point in the history
  • Loading branch information
chrtze committed Oct 5, 2020
1 parent f27634e commit 4f757b8
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 69 deletions.
113 changes: 113 additions & 0 deletions src/container/FlowRenderer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import React, { useCallback, useRef, memo, ReactNode, WheelEvent, MouseEvent } from 'react';
import { useStoreActions, useStoreState } from '../../store/hooks';

import useResizeHandler from '../../hooks/useResizeHandler';
import useGlobalKeyHandler from '../../hooks/useGlobalKeyHandler';
import useD3Zoom from '../../hooks/useD3Zoom';
import useKeyPress from '../../hooks/useKeyPress';

import { GraphViewProps } from '../GraphView';
import UserSelection from '../../components/UserSelection';
import NodesSelection from '../../components/NodesSelection';

interface FlowRendererProps
extends Omit<
GraphViewProps,
| 'elements'
| 'snapToGrid'
| 'nodeTypes'
| 'edgeTypes'
| 'snapGrid'
| 'connectionLineType'
| 'arrowHeadColor'
| 'onlyRenderVisibleNodes'
> {
children: ReactNode;
}

const FlowRenderer = ({
children,
onPaneClick,
onPaneContextMenu,
onPaneScroll,
onElementsRemove,
deleteKeyCode,
onMove,
onMoveStart,
onMoveEnd,
selectionKeyCode,
zoomOnScroll,
zoomOnDoubleClick,
paneMoveable,
defaultPosition,
defaultZoom,
translateExtent,
onSelectionDragStart,
onSelectionDrag,
onSelectionDragStop,
onSelectionContextMenu,
}: FlowRendererProps) => {
const zoomPane = useRef<HTMLDivElement>(null);
const unsetNodesSelection = useStoreActions((actions) => actions.unsetNodesSelection);
const nodesSelectionActive = useStoreState((state) => state.nodesSelectionActive);
const selectionKeyPressed = useKeyPress(selectionKeyCode);

useResizeHandler(zoomPane);
useGlobalKeyHandler({ onElementsRemove, deleteKeyCode });

useD3Zoom({
zoomPane,
onMove,
onMoveStart,
onMoveEnd,
selectionKeyPressed,
zoomOnScroll,
zoomOnDoubleClick,
paneMoveable,
defaultPosition,
defaultZoom,
translateExtent,
});

const onClick = useCallback(
(event: MouseEvent) => {
onPaneClick?.(event);
unsetNodesSelection();
},
[onPaneClick]
);

const onContextMenu = useCallback(
(event: MouseEvent) => {
onPaneContextMenu?.(event);
},
[onPaneContextMenu]
);

const onWheel = useCallback(
(event: WheelEvent) => {
onPaneScroll?.(event);
},
[onPaneScroll]
);

return (
<div className="react-flow__renderer" ref={zoomPane}>
{children}
<UserSelection selectionKeyPressed={selectionKeyPressed} />
{nodesSelectionActive && (
<NodesSelection
onSelectionDragStart={onSelectionDragStart}
onSelectionDrag={onSelectionDrag}
onSelectionDragStop={onSelectionDragStop}
onSelectionContextMenu={onSelectionContextMenu}
/>
)}
<div className="react-flow__zoompane" onClick={onClick} onContextMenu={onContextMenu} onWheel={onWheel} />
</div>
);
};

FlowRenderer.displayName = 'FlowRenderer';

export default memo(FlowRenderer);
93 changes: 24 additions & 69 deletions src/container/GraphView/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import React, { useEffect, useRef, useCallback, memo, CSSProperties, MouseEvent, WheelEvent } from 'react';
import React, { useEffect, useRef, memo, CSSProperties, MouseEvent, WheelEvent } from 'react';

import { useStoreState, useStoreActions, useStore } from '../../store/hooks';
import FlowRenderer from '../FlowRenderer';
import NodeRenderer from '../NodeRenderer';
import EdgeRenderer from '../EdgeRenderer';
import UserSelection from '../../components/UserSelection';
import NodesSelection from '../../components/NodesSelection';
import useKeyPress from '../../hooks/useKeyPress';
import useD3Zoom from '../../hooks/useD3Zoom';
import useGlobalKeyHandler from '../../hooks/useGlobalKeyHandler';
import useElementUpdater from '../../hooks/useElementUpdater';
import useResizeHandler from '../../hooks/useResizeHandler';
import { onLoadProject, onLoadGetElements } from '../../utils/graph';
import {
Elements,
Expand Down Expand Up @@ -130,11 +125,7 @@ const GraphView = ({
onPaneContextMenu,
}: GraphViewProps) => {
const isInitialised = useRef<boolean>(false);
const zoomPane = useRef<HTMLDivElement>(null);
const rendererNode = useRef<HTMLDivElement>(null);
const d3Initialised = useStoreState((state) => state.d3Initialised);
const nodesSelectionActive = useStoreState((state) => state.nodesSelectionActive);
const unsetNodesSelection = useStoreActions((actions) => actions.unsetNodesSelection);
const setOnConnect = useStoreActions((actions) => actions.setOnConnect);
const setOnConnectStart = useStoreActions((actions) => actions.setOnConnectStart);
const setOnConnectStop = useStoreActions((actions) => actions.setOnConnectStop);
Expand All @@ -153,26 +144,8 @@ const GraphView = ({
const zoomTo = useStoreActions((actions) => actions.zoomTo);
const currentStore = useStore();

useResizeHandler(rendererNode);
useGlobalKeyHandler({ onElementsRemove, deleteKeyCode });
useElementUpdater(elements);

const selectionKeyPressed = useKeyPress(selectionKeyCode);

useD3Zoom({
zoomPane,
onMove,
onMoveStart,
onMoveEnd,
selectionKeyPressed,
zoomOnScroll,
zoomOnDoubleClick,
paneMoveable,
defaultPosition,
defaultZoom,
translateExtent,
});

useEffect(() => {
if (!isInitialised.current && d3Initialised) {
if (onLoad) {
Expand All @@ -192,28 +165,6 @@ const GraphView = ({
}
}, [d3Initialised, onLoad]);

const onZoomPaneClick = useCallback(
(event: React.MouseEvent) => {
onPaneClick?.(event);
unsetNodesSelection();
},
[onPaneClick]
);

const onZoomPaneContextMenu = useCallback(
(event: React.MouseEvent) => {
onPaneContextMenu?.(event);
},
[onPaneContextMenu]
);

const onZoomPaneScroll = useCallback(
(event: WheelEvent) => {
onPaneScroll?.(event);
},
[onPaneScroll]
);

useEffect(() => {
if (onConnect) {
setOnConnect(onConnect);
Expand Down Expand Up @@ -287,7 +238,27 @@ const GraphView = ({
}, [translateExtent]);

return (
<div className="react-flow__renderer" ref={rendererNode}>
<FlowRenderer
onPaneClick={onPaneClick}
onPaneContextMenu={onPaneContextMenu}
onPaneScroll={onPaneScroll}
onElementsRemove={onElementsRemove}
deleteKeyCode={deleteKeyCode}
selectionKeyCode={selectionKeyCode}
onMove={onMove}
onMoveStart={onMoveStart}
onMoveEnd={onMoveEnd}
zoomOnScroll={zoomOnScroll}
zoomOnDoubleClick={zoomOnDoubleClick}
paneMoveable={paneMoveable}
defaultPosition={defaultPosition}
defaultZoom={defaultZoom}
translateExtent={translateExtent}
onSelectionDragStart={onSelectionDragStart}
onSelectionDrag={onSelectionDrag}
onSelectionDragStop={onSelectionDragStop}
onSelectionContextMenu={onSelectionContextMenu}
>
<NodeRenderer
nodeTypes={nodeTypes}
onElementClick={onElementClick}
Expand All @@ -311,23 +282,7 @@ const GraphView = ({
markerEndId={markerEndId}
connectionLineComponent={connectionLineComponent}
/>
<UserSelection selectionKeyPressed={selectionKeyPressed} />
{nodesSelectionActive && (
<NodesSelection
onSelectionDragStart={onSelectionDragStart}
onSelectionDrag={onSelectionDrag}
onSelectionDragStop={onSelectionDragStop}
onSelectionContextMenu={onSelectionContextMenu}
/>
)}
<div
className="react-flow__zoompane"
onClick={onZoomPaneClick}
onContextMenu={onZoomPaneContextMenu}
onWheel={onZoomPaneScroll}
ref={zoomPane}
/>
</div>
</FlowRenderer>
);
};

Expand Down
2 changes: 2 additions & 0 deletions src/hooks/useD3Zoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ export default ({
useEffect(() => {
if (d3Zoom) {
d3Zoom.filter((event: any) => {
console.log(event);

if (!paneMoveable) {
return false;
}
Expand Down

0 comments on commit 4f757b8

Please sign in to comment.