refactor(edges): optimize edge zIndex calculation

This commit is contained in:
moklick
2023-12-17 11:56:21 +01:00
parent c3834208d2
commit 2bc02547f6
6 changed files with 58 additions and 45 deletions
@@ -8,13 +8,14 @@ import {
type Connection,
getEdgePosition,
errorMessages,
getEdgeZIndex,
} from '@xyflow/system';
import { useStoreApi, useStore } from '../../hooks/useStore';
import { ARIA_EDGE_DESC_KEY } from '../A11yDescriptions';
import { EdgeAnchor } from '../Edges/EdgeAnchor';
import { getMouseHandler } from '../Edges/utils';
import type { EdgeWrapperProps } from '../../types';
import type { EdgeWrapperProps, Node } from '../../types';
import { builtinEdgeTypes } from './utils';
function EdgeWrapper({
@@ -56,7 +57,8 @@ function EdgeWrapper({
pathOptions,
interactionWidth,
edgeTypes,
zIndex,
zIndex: edgeZIndex,
elevateEdgesOnSelect,
onError,
}: EdgeWrapperProps): JSX.Element | null {
let edgeType = type || 'default';
@@ -72,27 +74,45 @@ function EdgeWrapper({
const [updateHover, setUpdateHover] = useState<boolean>(false);
const [updating, setUpdating] = useState<boolean>(false);
const store = useStoreApi();
const edgePosition = useStore(
const prevSourceNode = useRef<Node | undefined>();
const prevTargetNode = useRef<Node | undefined>();
const prevZIndex = useRef<number | undefined>(edgeZIndex);
const prevEdgePosition = useRef<ReturnType<typeof getEdgePosition> | null>(null);
const { edgePosition, zIndex } = useStore(
useCallback(
(state) => {
const sourceNode = state.nodeLookup.get(source);
const targetNode = state.nodeLookup.get(target);
if (!sourceNode || !targetNode) {
return null;
return { edgePosition: null, zIndex: edgeZIndex };
}
return getEdgePosition({
id,
sourceNode,
targetNode,
sourceHandle: sourceHandleId || null,
targetHandle: targetHandleId || null,
connectionMode: state.connectionMode,
onError: state.onError,
});
const nodesChanged = prevSourceNode.current !== sourceNode || prevTargetNode.current !== targetNode;
prevSourceNode.current = sourceNode;
prevTargetNode.current = targetNode;
prevEdgePosition.current = nodesChanged
? getEdgePosition({
id,
sourceNode,
targetNode,
sourceHandle: sourceHandleId || null,
targetHandle: targetHandleId || null,
connectionMode: state.connectionMode,
onError: state.onError,
})
: prevEdgePosition.current;
prevZIndex.current = getEdgeZIndex(selected, edgeZIndex, sourceNode, targetNode, elevateEdgesOnSelect);
return {
edgePosition: prevEdgePosition.current,
zIndex: prevZIndex.current,
};
},
[source, target]
[source, target, selected, edgeZIndex]
),
shallow
);
@@ -63,7 +63,7 @@ const EdgeRenderer = ({
children,
}: EdgeRendererProps) => {
const { edgesFocusable, edgesUpdatable, elementsSelectable, onError } = useStore(selector, shallow);
const edges = useVisibleEdges(onlyRenderVisibleElements, elevateEdgesOnSelect);
const edges = useVisibleEdges(onlyRenderVisibleElements);
return (
<div className="react-flow__edges">
@@ -121,6 +121,7 @@ const EdgeRenderer = ({
interactionWidth={edge.interactionWidth}
onError={onError}
edgeTypes={edgeTypes}
elevateEdgesOnSelect={elevateEdgesOnSelect}
/>
);
})}
+4 -4
View File
@@ -1,11 +1,11 @@
import { useCallback } from 'react';
import { shallow } from 'zustand/shallow';
import { adjustEdgeZIndex, isEdgeVisible } from '@xyflow/system';
import { isEdgeVisible } from '@xyflow/system';
import { useStore } from '../hooks/useStore';
import { type Edge, type ReactFlowState } from '../types';
function useVisibleEdges(onlyRenderVisible: boolean, elevateEdgesOnSelect: boolean): Edge[] {
function useVisibleEdges(onlyRenderVisible: boolean): Edge[] {
const edges = useStore(
useCallback(
(s: ReactFlowState) => {
@@ -29,9 +29,9 @@ function useVisibleEdges(onlyRenderVisible: boolean, elevateEdgesOnSelect: boole
})
: s.edges;
return visibleEdges.map((edge) => adjustEdgeZIndex(edge, s.nodeLookup, elevateEdgesOnSelect));
return visibleEdges;
},
[onlyRenderVisible, elevateEdgesOnSelect]
[onlyRenderVisible]
),
shallow
);
+1
View File
@@ -78,6 +78,7 @@ export type EdgeWrapperProps<T = any> = Omit<Edge<T>, 'sourceHandle' | 'targetHa
pathOptions?: BezierPathOptions | SmoothStepPathOptions;
edgeTypes?: EdgeTypes;
onError?: OnError;
elevateEdgesOnSelect?: boolean;
};
export type DefaultEdgeOptions = DefaultEdgeOptionsBase<Edge>;