diff --git a/src/container/EdgeRenderer/index.tsx b/src/container/EdgeRenderer/index.tsx
index 6e913f72..e7383e6b 100644
--- a/src/container/EdgeRenderer/index.tsx
+++ b/src/container/EdgeRenderer/index.tsx
@@ -4,17 +4,8 @@ import { useStoreState } from '../../store/hooks';
import ConnectionLine from '../../components/ConnectionLine/index';
import { isEdge } from '../../utils/graph';
import MarkerDefinitions from './MarkerDefinitions';
-import { getHandlePosition, getHandle, isEdgeVisible } from './utils';
-import {
- Position,
- Edge,
- Node,
- HandleElement,
- Elements,
- ConnectionLineType,
- ConnectionLineComponent,
- Transform,
-} from '../../types';
+import { getEdgePositions, getHandle, isEdgeVisible, getSourceTargetNode } from './utils';
+import { Position, Edge, Node, Elements, ConnectionLineType, ConnectionLineComponent, Transform } from '../../types';
interface EdgeRendererProps {
edgeTypes: any;
@@ -24,46 +15,9 @@ interface EdgeRendererProps {
arrowHeadColor: string;
markerEndId?: string;
connectionLineComponent?: ConnectionLineComponent;
+ onlyRenderVisibleElements: boolean;
}
-interface EdgePositions {
- sourceX: number;
- sourceY: number;
- targetX: number;
- targetY: number;
-}
-
-function getEdgePositions(
- sourceNode: Node,
- sourceHandle: HandleElement | unknown,
- sourcePosition: Position,
- targetNode: Node,
- targetHandle: HandleElement | unknown,
- targetPosition: Position
-): EdgePositions {
- const sourceHandlePos = getHandlePosition(sourcePosition, sourceNode, sourceHandle);
- const sourceX = sourceNode.__rf.position.x + sourceHandlePos.x;
- const sourceY = sourceNode.__rf.position.y + sourceHandlePos.y;
-
- const targetHandlePos = getHandlePosition(targetPosition, targetNode, targetHandle);
- const targetX = targetNode.__rf.position.x + targetHandlePos.x;
- const targetY = targetNode.__rf.position.y + targetHandlePos.y;
-
- return {
- sourceX,
- sourceY,
- targetX,
- targetY,
- };
-}
-
-type SourceTargetNode = {
- sourceNode: Node | null;
- targetNode: Node | null;
-};
-
-const initialSourceTarget: SourceTargetNode = { sourceNode: null, targetNode: null };
-
function renderEdge(
edge: Edge,
props: EdgeRendererProps,
@@ -72,18 +26,12 @@ function renderEdge(
elementsSelectable: boolean,
transform: Transform,
width: number,
- height: number
+ height: number,
+ onlyRenderVisibleElements: boolean
) {
const sourceHandleId = edge.sourceHandle || null;
const targetHandleId = edge.targetHandle || null;
- const { sourceNode, targetNode } = nodes.reduce((res, node) => {
- if (node.id === edge.source) {
- res.sourceNode = node;
- } else if (node.id === edge.target) {
- res.targetNode = node;
- }
- return res;
- }, initialSourceTarget);
+ const { sourceNode, targetNode } = getSourceTargetNode(edge, nodes);
if (!sourceNode) {
console.warn(`couldn't create edge for source id: ${edge.source}`);
@@ -99,15 +47,17 @@ function renderEdge(
return null;
}
- const renderEdge = isEdgeVisible({
- sourcePos: sourceNode.__rf.position,
- targetPos: targetNode.__rf.position,
- width,
- height,
- transform,
- });
+ const isVisible = onlyRenderVisibleElements
+ ? isEdgeVisible({
+ sourcePos: sourceNode.__rf.position,
+ targetPos: targetNode.__rf.position,
+ width,
+ height,
+ transform,
+ })
+ : true;
- if (!renderEdge) {
+ if (!isVisible) {
return null;
}
@@ -192,7 +142,13 @@ const EdgeRenderer = (props: EdgeRendererProps) => {
return null;
}
- const { connectionLineType, arrowHeadColor, connectionLineStyle, connectionLineComponent } = props;
+ const {
+ connectionLineType,
+ arrowHeadColor,
+ connectionLineStyle,
+ connectionLineComponent,
+ onlyRenderVisibleElements,
+ } = props;
const transformStyle = `translate(${transform[0]},${transform[1]}) scale(${transform[2]})`;
const renderConnectionLine = connectionNodeId && connectionHandleType;
@@ -201,7 +157,17 @@ const EdgeRenderer = (props: EdgeRendererProps) => {
{edges.map((edge: Edge) =>
- renderEdge(edge, props, nodes, selectedElements, elementsSelectable, transform, width, height)
+ renderEdge(
+ edge,
+ props,
+ nodes,
+ selectedElements,
+ elementsSelectable,
+ transform,
+ width,
+ height,
+ onlyRenderVisibleElements
+ )
)}
{renderConnectionLine && (
{
+ const sourceHandlePos = getHandlePosition(sourcePosition, sourceNode, sourceHandle);
+ const sourceX = sourceNode.__rf.position.x + sourceHandlePos.x;
+ const sourceY = sourceNode.__rf.position.y + sourceHandlePos.y;
+
+ const targetHandlePos = getHandlePosition(targetPosition, targetNode, targetHandle);
+ const targetX = targetNode.__rf.position.x + targetHandlePos.x;
+ const targetY = targetNode.__rf.position.y + targetHandlePos.y;
+
+ return {
+ sourceX,
+ sourceY,
+ targetX,
+ targetY,
+ };
+};
+
interface IsEdgeVisibleParams {
sourcePos: XYPosition;
targetPos: XYPosition;
@@ -118,3 +159,22 @@ export function isEdgeVisible({ sourcePos, targetPos, width, height, transform }
return overlappingArea > 0;
}
+
+type SourceTargetNode = {
+ sourceNode: Node | null;
+ targetNode: Node | null;
+};
+
+export const getSourceTargetNode = (edge: Edge, nodes: Node[]): SourceTargetNode => {
+ return nodes.reduce(
+ (res, node) => {
+ if (node.id === edge.source) {
+ res.sourceNode = node;
+ } else if (node.id === edge.target) {
+ res.targetNode = node;
+ }
+ return res;
+ },
+ { sourceNode: null, targetNode: null } as SourceTargetNode
+ );
+};
diff --git a/src/container/GraphView/index.tsx b/src/container/GraphView/index.tsx
index 2e25c628..ee67ae0f 100644
--- a/src/container/GraphView/index.tsx
+++ b/src/container/GraphView/index.tsx
@@ -93,7 +93,6 @@ const GraphView = ({
const setMinZoom = useStoreActions((actions) => actions.setMinZoom);
const setMaxZoom = useStoreActions((actions) => actions.setMaxZoom);
const setTranslateExtent = useStoreActions((actions) => actions.setTranslateExtent);
- const setOnlyRenderVisibleElements = useStoreActions((actions) => actions.setOnlyRenderVisibleElements);
const currentStore = useStore();
const { zoomIn, zoomOut, zoomTo, transform, fitView, initialized } = useZoomPanHelper();
@@ -188,12 +187,6 @@ const GraphView = ({
}
}, [translateExtent]);
- useEffect(() => {
- if (typeof onlyRenderVisibleElements !== 'undefined') {
- setOnlyRenderVisibleElements(onlyRenderVisibleElements);
- }
- }, [translateExtent]);
-
return (
);
diff --git a/src/container/NodeRenderer/index.tsx b/src/container/NodeRenderer/index.tsx
index f44bcd52..42219b99 100644
--- a/src/container/NodeRenderer/index.tsx
+++ b/src/container/NodeRenderer/index.tsx
@@ -1,5 +1,6 @@
import React, { memo, useMemo, ComponentType, MouseEvent } from 'react';
+import { getNodesInside } from '../../utils/graph';
import { useStoreState } from '../../store/hooks';
import { Node, NodeTypesType, WrapNodeProps, Edge } from '../../types';
@@ -15,6 +16,7 @@ interface NodeRendererProps {
onNodeDragStop?: (event: MouseEvent, node: Node) => void;
snapToGrid: boolean;
snapGrid: [number, number];
+ onlyRenderVisibleElements: boolean;
}
const NodeRenderer = (props: NodeRendererProps) => {
@@ -23,7 +25,10 @@ const NodeRenderer = (props: NodeRendererProps) => {
const nodesDraggable = useStoreState((state) => state.nodesDraggable);
const nodesConnectable = useStoreState((state) => state.nodesConnectable);
const elementsSelectable = useStoreState((state) => state.elementsSelectable);
- const visibleNodes = useStoreState((state) => state.visibleNodes);
+ const viewportBox = useStoreState((state) => state.viewportBox);
+ const nodes = useStoreState((state) => state.nodes);
+
+ const visibleNodes = props.onlyRenderVisibleElements ? getNodesInside(nodes, viewportBox, transform, true) : nodes;
const transformStyle = useMemo(
() => ({
diff --git a/src/store/index.ts b/src/store/index.ts
index 1e6a86bc..89280ade 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -44,12 +44,11 @@ export interface StoreModel {
height: number;
transform: Transform;
elements: Elements;
- visibleNodes: Computed;
nodes: Computed;
edges: Computed;
selectedElements: Elements | null;
selectedNodesBbox: Rect;
- onlyRenderVisibleElements: boolean;
+ viewportBox: Computed;
d3Zoom: ZoomBehavior | null;
d3Selection: D3Selection | null;
@@ -132,8 +131,6 @@ export interface StoreModel {
unsetUserSelection: Action;
setMultiSelectionActive: Action;
-
- setOnlyRenderVisibleElements: Action;
}
export const storeModel: StoreModel = {
@@ -142,19 +139,10 @@ export const storeModel: StoreModel = {
transform: [0, 0, 1],
elements: [],
nodes: computed((state) => state.elements.filter(isNode)),
- visibleNodes: computed((state) => {
- if (!state.onlyRenderVisibleElements) {
- return state.nodes;
- }
-
- const viewportBox = { x: 0, y: 0, width: state.width, height: state.height };
-
- return getNodesInside(state.nodes, viewportBox, state.transform, true);
- }),
+ viewportBox: computed((state) => ({ x: 0, y: 0, width: state.width, height: state.height })),
edges: computed((state) => state.elements.filter(isEdge)),
selectedElements: null,
selectedNodesBbox: { x: 0, y: 0, width: 0, height: 0 },
- onlyRenderVisibleElements: true,
d3Zoom: null,
d3Selection: null,
@@ -452,10 +440,6 @@ export const storeModel: StoreModel = {
setMultiSelectionActive: action((state, isActive) => {
state.multiSelectionActive = isActive;
}),
-
- setOnlyRenderVisibleElements: action((state, onlyRenderVisible) => {
- state.onlyRenderVisibleElements = onlyRenderVisible;
- }),
};
const nodeEnv: string = (typeof __ENV__ !== 'undefined' && __ENV__) as string;