add only render visible nodes & edges
This commit is contained in:
@@ -50,7 +50,7 @@
|
|||||||
let edges = $state.raw(edgeItems);
|
let edges = $state.raw(edgeItems);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<SvelteFlow bind:nodes bind:edges fitView minZoom={0.2}>
|
<SvelteFlow bind:nodes bind:edges fitView minZoom={0.2} onlyRenderVisibleElements>
|
||||||
<Controls />
|
<Controls />
|
||||||
<Background variant={BackgroundVariant.Lines} />
|
<Background variant={BackgroundVariant.Lines} />
|
||||||
<MiniMap />
|
<MiniMap />
|
||||||
|
|||||||
@@ -79,8 +79,6 @@
|
|||||||
callback({ event, edge });
|
callback({ event, edge });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$inspect(selected);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
onnodecontextmenu
|
onnodecontextmenu
|
||||||
}: NodeWrapperProps & NodeEvents = $props();
|
}: NodeWrapperProps & NodeEvents = $props();
|
||||||
|
|
||||||
|
// $inspect(node);
|
||||||
|
|
||||||
let {
|
let {
|
||||||
data = {},
|
data = {},
|
||||||
selected = false,
|
selected = false,
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
import { EdgeWrapper } from '$lib/components/EdgeWrapper';
|
import { EdgeWrapper } from '$lib/components/EdgeWrapper';
|
||||||
import { CallOnMount } from '$lib/components/CallOnMount';
|
import { CallOnMount } from '$lib/components/CallOnMount';
|
||||||
import { MarkerDefinition } from '$lib/container/EdgeRenderer/MarkerDefinition';
|
import { MarkerDefinition } from '$lib/container/EdgeRenderer/MarkerDefinition';
|
||||||
import type { EdgeEvents, EdgeLayouted } from '$lib/types';
|
import type { EdgeEvents } from '$lib/types';
|
||||||
import { getEdgePosition, getElevatedEdgeZIndex } from '@xyflow/system';
|
|
||||||
import type { SvelteFlowStore } from '$lib/store/types';
|
import type { SvelteFlowStore } from '$lib/store/types';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -13,68 +12,6 @@
|
|||||||
onedgemouseenter,
|
onedgemouseenter,
|
||||||
onedgemouseleave
|
onedgemouseleave
|
||||||
}: { store: SvelteFlowStore } & EdgeEvents = $props();
|
}: { store: SvelteFlowStore } & EdgeEvents = $props();
|
||||||
|
|
||||||
let previousLayoutedEdges = new Map<string, EdgeLayouted>();
|
|
||||||
let layoutedEdges = $derived.by(() => {
|
|
||||||
// here for update reference
|
|
||||||
store.nodes;
|
|
||||||
|
|
||||||
const layoutedEdges = new Map<string, EdgeLayouted>();
|
|
||||||
|
|
||||||
for (let edge of store.edges) {
|
|
||||||
const sourceNode = store.nodeLookup.get(edge.source);
|
|
||||||
const targetNode = store.nodeLookup.get(edge.target);
|
|
||||||
|
|
||||||
if (!sourceNode || !targetNode) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we reuse the previous edge object if
|
|
||||||
// the current and previous edge are the same
|
|
||||||
// and the source and target node are the same
|
|
||||||
// and references to internalNodes are the same
|
|
||||||
const previous = previousLayoutedEdges.get(edge.id);
|
|
||||||
if (
|
|
||||||
previous &&
|
|
||||||
edge === previous.edge &&
|
|
||||||
sourceNode == previous.sourceNode &&
|
|
||||||
targetNode == previous.targetNode
|
|
||||||
) {
|
|
||||||
layoutedEdges.set(edge.id, previous);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const edgePosition = getEdgePosition({
|
|
||||||
id: edge.id,
|
|
||||||
sourceNode,
|
|
||||||
targetNode,
|
|
||||||
sourceHandle: edge.sourceHandle || null,
|
|
||||||
targetHandle: edge.targetHandle || null,
|
|
||||||
connectionMode: store.connectionMode,
|
|
||||||
onError: store.onerror
|
|
||||||
});
|
|
||||||
|
|
||||||
if (edgePosition) {
|
|
||||||
layoutedEdges.set(edge.id, {
|
|
||||||
...edge,
|
|
||||||
zIndex: getElevatedEdgeZIndex({
|
|
||||||
selected: edge.selected,
|
|
||||||
zIndex: edge.zIndex,
|
|
||||||
sourceNode,
|
|
||||||
targetNode,
|
|
||||||
elevateOnSelect: false
|
|
||||||
}),
|
|
||||||
...edgePosition,
|
|
||||||
sourceNode,
|
|
||||||
targetNode,
|
|
||||||
edge
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
previousLayoutedEdges = layoutedEdges;
|
|
||||||
return layoutedEdges;
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="svelte-flow__edges">
|
<div class="svelte-flow__edges">
|
||||||
@@ -82,7 +19,7 @@
|
|||||||
<MarkerDefinition />
|
<MarkerDefinition />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
{#each layoutedEdges.values() as edge (edge.id)}
|
{#each store.visible.edges.values() as edge (edge.id)}
|
||||||
<EdgeWrapper
|
<EdgeWrapper
|
||||||
{store}
|
{store}
|
||||||
{edge}
|
{edge}
|
||||||
@@ -93,13 +30,14 @@
|
|||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
{#if layoutedEdges.size > 0}
|
{#if !store.edgesInitialized && store.visible.edges.size > 0}
|
||||||
<CallOnMount
|
<CallOnMount
|
||||||
onMount={() => {
|
onMount={() => {
|
||||||
store.edgesInitialized = true;
|
store.edgesInitialized = true;
|
||||||
}}
|
}}
|
||||||
onDestroy={() => {
|
onDestroy={() => {
|
||||||
store.edgesInitialized = false;
|
// TODO: this needs to be handled differently
|
||||||
|
// store.edgesInitialized = false;
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -3,9 +3,8 @@
|
|||||||
|
|
||||||
import { NodeWrapper } from '$lib/components/NodeWrapper';
|
import { NodeWrapper } from '$lib/components/NodeWrapper';
|
||||||
|
|
||||||
import type { Node, NodeEvents } from '$lib/types';
|
import type { NodeEvents } from '$lib/types';
|
||||||
import type { SvelteFlowStore } from '$lib/store/types';
|
import type { SvelteFlowStore } from '$lib/store/types';
|
||||||
import type { NodeLookup } from '@xyflow/system';
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
store,
|
store,
|
||||||
@@ -42,15 +41,10 @@
|
|||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
resizeObserver?.disconnect();
|
resizeObserver?.disconnect();
|
||||||
});
|
});
|
||||||
|
|
||||||
// We pass an unused reference to nodes to trigger a re-render
|
|
||||||
function getNodes(nodeLookup: NodeLookup, nodes: Node[]) {
|
|
||||||
return nodeLookup.values();
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="svelte-flow__nodes">
|
<div class="svelte-flow__nodes">
|
||||||
{#each getNodes(store.nodeLookup, store.nodes) as node (node.id)}
|
{#each store.visible.nodes.values() as node (node.id)}
|
||||||
<NodeWrapper
|
<NodeWrapper
|
||||||
{store}
|
{store}
|
||||||
{node}
|
{node}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export type SvelteFlowProps = NodeEvents &
|
|||||||
id?: string;
|
id?: string;
|
||||||
/** An array of nodes to render in a controlled flow.
|
/** An array of nodes to render in a controlled flow.
|
||||||
* @example
|
* @example
|
||||||
* const nodes = writable([
|
* const nodes = $state.raw([
|
||||||
* {
|
* {
|
||||||
* id: 'node-1',
|
* id: 'node-1',
|
||||||
* type: 'input',
|
* type: 'input',
|
||||||
@@ -64,7 +64,7 @@ export type SvelteFlowProps = NodeEvents &
|
|||||||
nodes: Node[];
|
nodes: Node[];
|
||||||
/** An array of edges to render in a controlled flow.
|
/** An array of edges to render in a controlled flow.
|
||||||
* @example
|
* @example
|
||||||
* const edges = writable([
|
* const edges = $state.raw([
|
||||||
* {
|
* {
|
||||||
* id: 'edge-1-2',
|
* id: 'edge-1-2',
|
||||||
* source: 'node-1',
|
* source: 'node-1',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useStore } from '$lib/store';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook for seeing if nodes are initialized
|
* Hook for seeing if nodes are initialized
|
||||||
* @returns - nodesInitialized Writable
|
* @returns - reactive nodesInitialized
|
||||||
*/
|
*/
|
||||||
export function useNodesInitialized() {
|
export function useNodesInitialized() {
|
||||||
const { nodesInitialized } = $derived(useStore());
|
const { nodesInitialized } = $derived(useStore());
|
||||||
@@ -15,7 +15,7 @@ export function useNodesInitialized() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook for seeing if the flow is initialized
|
* Hook for seeing if the flow is initialized
|
||||||
* @returns - initialized Writable
|
* @returns - reactive initialized
|
||||||
*/
|
*/
|
||||||
export function useInitialized() {
|
export function useInitialized() {
|
||||||
const { initialized } = $derived(useStore());
|
const { initialized } = $derived(useStore());
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ import {
|
|||||||
type ConnectionLookup,
|
type ConnectionLookup,
|
||||||
type ParentLookup,
|
type ParentLookup,
|
||||||
pointToRendererPoint,
|
pointToRendererPoint,
|
||||||
type ColorModeClass
|
type ColorModeClass,
|
||||||
|
type Transform
|
||||||
} from '@xyflow/system';
|
} from '@xyflow/system';
|
||||||
|
|
||||||
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
|
import DefaultNode from '$lib/components/nodes/DefaultNode.svelte';
|
||||||
@@ -51,11 +52,13 @@ import type {
|
|||||||
OnBeforeDelete,
|
OnBeforeDelete,
|
||||||
IsValidConnection,
|
IsValidConnection,
|
||||||
Edge,
|
Edge,
|
||||||
Node
|
Node,
|
||||||
|
EdgeLayouted
|
||||||
} from '$lib/types';
|
} from '$lib/types';
|
||||||
|
|
||||||
import type { StoreSignals } from './types';
|
import type { StoreSignals } from './types';
|
||||||
import { MediaQuery } from 'svelte/reactivity';
|
import { MediaQuery } from 'svelte/reactivity';
|
||||||
|
import { gatherLayoutedEdges, getVisibleNodes } from './visibleElements';
|
||||||
|
|
||||||
export const initialNodeTypes = {
|
export const initialNodeTypes = {
|
||||||
input: InputNode,
|
input: InputNode,
|
||||||
@@ -72,6 +75,7 @@ export const initialEdgeTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getInitialStore = (signals: StoreSignals) => {
|
export const getInitialStore = (signals: StoreSignals) => {
|
||||||
|
const previousLayoutedEdges = new Map<string, EdgeLayouted>();
|
||||||
// We use a class here, because Svelte adds getters & setter for us.
|
// We use a class here, because Svelte adds getters & setter for us.
|
||||||
// Inline classes have some performance implications but we just call it once (max twice).
|
// Inline classes have some performance implications but we just call it once (max twice).
|
||||||
class SvelteFlowStore {
|
class SvelteFlowStore {
|
||||||
@@ -108,6 +112,50 @@ export const getInitialStore = (signals: StoreSignals) => {
|
|||||||
connectionLookup: ConnectionLookup = new Map();
|
connectionLookup: ConnectionLookup = new Map();
|
||||||
edgeLookup: EdgeLookup = new Map();
|
edgeLookup: EdgeLookup = new Map();
|
||||||
|
|
||||||
|
visible = $derived.by(() => {
|
||||||
|
// We need to access this._nodes to trigger on changes
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||||
|
this._nodes;
|
||||||
|
|
||||||
|
// We either add all or only visible nodes to visibleNodes here.
|
||||||
|
let visibleNodes = new Map();
|
||||||
|
let layoutedEdges = new Map<string, EdgeLayouted>();
|
||||||
|
// TODO: is there a more elegant solution??
|
||||||
|
if (this.onlyRenderVisibleElements) {
|
||||||
|
const transform: Transform = [this.viewport.x, this.viewport.y, this.viewport.zoom];
|
||||||
|
getVisibleNodes(this.nodeLookup, transform, this.width, this.height).forEach((node) => {
|
||||||
|
visibleNodes.set(node.id, node);
|
||||||
|
});
|
||||||
|
layoutedEdges = gatherLayoutedEdges(
|
||||||
|
this._edges,
|
||||||
|
this.nodeLookup,
|
||||||
|
previousLayoutedEdges,
|
||||||
|
this.connectionMode,
|
||||||
|
this.onerror,
|
||||||
|
true,
|
||||||
|
transform,
|
||||||
|
this.width,
|
||||||
|
this.height,
|
||||||
|
visibleNodes
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
visibleNodes = this.nodeLookup;
|
||||||
|
layoutedEdges = gatherLayoutedEdges(
|
||||||
|
this._edges,
|
||||||
|
this.nodeLookup,
|
||||||
|
previousLayoutedEdges,
|
||||||
|
this.connectionMode,
|
||||||
|
this.onerror,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
nodes: visibleNodes,
|
||||||
|
edges: layoutedEdges
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
domNode: HTMLDivElement | null = $derived(signals.domNode ?? null);
|
domNode: HTMLDivElement | null = $derived(signals.domNode ?? null);
|
||||||
width: number = $derived(signals.width ?? signals.props.width ?? 0);
|
width: number = $derived(signals.width ?? signals.props.width ?? 0);
|
||||||
height: number = $derived(signals.height ?? signals.props.height ?? 0);
|
height: number = $derived(signals.height ?? signals.props.height ?? 0);
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
import { derived } from 'svelte/store';
|
|
||||||
import { isEdgeVisible, getEdgePosition, getElevatedEdgeZIndex } from '@xyflow/system';
|
|
||||||
|
|
||||||
import type { EdgeLayouted } from '$lib/types';
|
|
||||||
import type { SvelteFlowStoreState } from './types';
|
|
||||||
|
|
||||||
export function getVisibleEdges(store: SvelteFlowStoreState) {
|
|
||||||
const visibleEdges = derived(
|
|
||||||
[
|
|
||||||
store.edges,
|
|
||||||
store.nodes,
|
|
||||||
store.nodeLookup,
|
|
||||||
store.onlyRenderVisibleElements,
|
|
||||||
store.viewport,
|
|
||||||
store.width,
|
|
||||||
store.height
|
|
||||||
],
|
|
||||||
([edges, , nodeLookup, onlyRenderVisibleElements, viewport, width, height]) => {
|
|
||||||
const visibleEdges =
|
|
||||||
onlyRenderVisibleElements && width && height
|
|
||||||
? edges.filter((edge) => {
|
|
||||||
const sourceNode = nodeLookup.get(edge.source);
|
|
||||||
const targetNode = nodeLookup.get(edge.target);
|
|
||||||
|
|
||||||
return (
|
|
||||||
sourceNode &&
|
|
||||||
targetNode &&
|
|
||||||
isEdgeVisible({
|
|
||||||
sourceNode,
|
|
||||||
targetNode,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
transform: [viewport.x, viewport.y, viewport.zoom]
|
|
||||||
})
|
|
||||||
);
|
|
||||||
})
|
|
||||||
: edges;
|
|
||||||
|
|
||||||
return visibleEdges;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return derived(
|
|
||||||
[visibleEdges, store.nodes, store.nodeLookup, store.connectionMode, store.onerror],
|
|
||||||
([visibleEdges, , nodeLookup, connectionMode, onerror]) => {
|
|
||||||
const layoutedEdges = visibleEdges.reduce<EdgeLayouted[]>((res, edge) => {
|
|
||||||
const sourceNode = nodeLookup.get(edge.source);
|
|
||||||
const targetNode = nodeLookup.get(edge.target);
|
|
||||||
|
|
||||||
if (!sourceNode || !targetNode) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
const edgePosition = getEdgePosition({
|
|
||||||
id: edge.id,
|
|
||||||
sourceNode,
|
|
||||||
targetNode,
|
|
||||||
sourceHandle: edge.sourceHandle || null,
|
|
||||||
targetHandle: edge.targetHandle || null,
|
|
||||||
connectionMode,
|
|
||||||
onError: onerror
|
|
||||||
});
|
|
||||||
|
|
||||||
if (edgePosition) {
|
|
||||||
res.push({
|
|
||||||
...edge,
|
|
||||||
zIndex: getElevatedEdgeZIndex({
|
|
||||||
selected: edge.selected,
|
|
||||||
zIndex: edge.zIndex,
|
|
||||||
sourceNode,
|
|
||||||
targetNode,
|
|
||||||
elevateOnSelect: false
|
|
||||||
}),
|
|
||||||
...edgePosition
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return layoutedEdges;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { derived } from 'svelte/store';
|
|
||||||
import { getNodesInside, type Transform } from '@xyflow/system';
|
|
||||||
import type { SvelteFlowStoreState } from './types';
|
|
||||||
|
|
||||||
export function getVisibleNodes(store: SvelteFlowStoreState) {
|
|
||||||
return derived(
|
|
||||||
[
|
|
||||||
store.nodeLookup,
|
|
||||||
store.onlyRenderVisibleElements,
|
|
||||||
store.width,
|
|
||||||
store.height,
|
|
||||||
store.viewport,
|
|
||||||
store.nodes
|
|
||||||
],
|
|
||||||
([nodeLookup, onlyRenderVisibleElements, width, height, viewport]) => {
|
|
||||||
const transform: Transform = [viewport.x, viewport.y, viewport.zoom];
|
|
||||||
|
|
||||||
return onlyRenderVisibleElements
|
|
||||||
? getNodesInside(nodeLookup, { x: 0, y: 0, width, height }, transform, true)
|
|
||||||
: Array.from(nodeLookup.values());
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
import type { Edge, EdgeLayouted, InternalNode } from '$lib/types';
|
||||||
|
import {
|
||||||
|
ConnectionMode,
|
||||||
|
getEdgePosition,
|
||||||
|
getElevatedEdgeZIndex,
|
||||||
|
getNodesInside,
|
||||||
|
isEdgeVisible,
|
||||||
|
type NodeLookup,
|
||||||
|
type OnError,
|
||||||
|
type Transform
|
||||||
|
} from '@xyflow/system';
|
||||||
|
|
||||||
|
export function getVisibleNodes(
|
||||||
|
nodeLookup: NodeLookup,
|
||||||
|
transform: Transform,
|
||||||
|
width: number,
|
||||||
|
height: number
|
||||||
|
) {
|
||||||
|
return getNodesInside(nodeLookup, { x: 0, y: 0, width: width, height: height }, transform, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: is this what we want?
|
||||||
|
export function gatherLayoutedEdges(
|
||||||
|
edges: Edge[],
|
||||||
|
nodeLookup: NodeLookup,
|
||||||
|
previousLayoutedEdges: Map<string, EdgeLayouted>,
|
||||||
|
connectionMode: ConnectionMode,
|
||||||
|
onerror: OnError,
|
||||||
|
onlyRenderVisibleElements: true,
|
||||||
|
transform: Transform,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
visibleNodes: Map<string, InternalNode>
|
||||||
|
): Map<string, EdgeLayouted>;
|
||||||
|
export function gatherLayoutedEdges(
|
||||||
|
edges: Edge[],
|
||||||
|
nodeLookup: NodeLookup,
|
||||||
|
previousLayoutedEdges: Map<string, EdgeLayouted>,
|
||||||
|
connectionMode: ConnectionMode,
|
||||||
|
onerror: OnError,
|
||||||
|
onlyRenderVisibleElements: false
|
||||||
|
): Map<string, EdgeLayouted>;
|
||||||
|
export function gatherLayoutedEdges(
|
||||||
|
edges: Edge[],
|
||||||
|
nodeLookup: NodeLookup,
|
||||||
|
previousLayoutedEdges: Map<string, EdgeLayouted>,
|
||||||
|
connectionMode: ConnectionMode,
|
||||||
|
onerror: OnError,
|
||||||
|
onlyRenderVisibleElements?: boolean,
|
||||||
|
transform?: Transform,
|
||||||
|
width?: number,
|
||||||
|
height?: number,
|
||||||
|
visibleNodes?: Map<string, InternalNode>
|
||||||
|
): Map<string, EdgeLayouted> {
|
||||||
|
const layoutedEdges = new Map<string, EdgeLayouted>();
|
||||||
|
for (const edge of edges) {
|
||||||
|
const sourceNode = nodeLookup.get(edge.source);
|
||||||
|
const targetNode = nodeLookup.get(edge.target);
|
||||||
|
|
||||||
|
if (!sourceNode || !targetNode) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onlyRenderVisibleElements) {
|
||||||
|
if (
|
||||||
|
isEdgeVisible({
|
||||||
|
sourceNode,
|
||||||
|
targetNode,
|
||||||
|
width: width!,
|
||||||
|
height: height!,
|
||||||
|
transform: transform!
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
visibleNodes!.set(sourceNode.id, sourceNode);
|
||||||
|
visibleNodes!.set(targetNode.id, targetNode);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we reuse the previous edge object if
|
||||||
|
// the current and previous edge are the same
|
||||||
|
// and the source and target node are the same
|
||||||
|
// and references to internalNodes are the same
|
||||||
|
const previous = previousLayoutedEdges.get(edge.id);
|
||||||
|
if (
|
||||||
|
previous &&
|
||||||
|
edge === previous.edge &&
|
||||||
|
sourceNode == previous.sourceNode &&
|
||||||
|
targetNode == previous.targetNode
|
||||||
|
) {
|
||||||
|
layoutedEdges.set(edge.id, previous);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const edgePosition = getEdgePosition({
|
||||||
|
id: edge.id,
|
||||||
|
sourceNode,
|
||||||
|
targetNode,
|
||||||
|
sourceHandle: edge.sourceHandle || null,
|
||||||
|
targetHandle: edge.targetHandle || null,
|
||||||
|
connectionMode: connectionMode,
|
||||||
|
onError: onerror
|
||||||
|
});
|
||||||
|
|
||||||
|
if (edgePosition) {
|
||||||
|
layoutedEdges.set(edge.id, {
|
||||||
|
...edge,
|
||||||
|
zIndex: getElevatedEdgeZIndex({
|
||||||
|
selected: edge.selected,
|
||||||
|
zIndex: edge.zIndex,
|
||||||
|
sourceNode,
|
||||||
|
targetNode,
|
||||||
|
elevateOnSelect: false
|
||||||
|
}),
|
||||||
|
...edgePosition,
|
||||||
|
sourceNode,
|
||||||
|
targetNode,
|
||||||
|
edge
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
previousLayoutedEdges = layoutedEdges;
|
||||||
|
|
||||||
|
return layoutedEdges;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user