Fixed rerendering of edges & simplified rerendering of nodes
This commit is contained in:
@@ -45,7 +45,11 @@
|
|||||||
initialHeight,
|
initialHeight,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
dragHandle
|
dragHandle,
|
||||||
|
internals: {
|
||||||
|
z: zIndex = 0,
|
||||||
|
positionAbsolute: { x: positionX, y: positionY }
|
||||||
|
}
|
||||||
} = $derived(node);
|
} = $derived(node);
|
||||||
|
|
||||||
let { id } = node;
|
let { id } = node;
|
||||||
@@ -55,19 +59,6 @@
|
|||||||
let connectable = $derived(_connectable ?? store.nodesConnectable);
|
let connectable = $derived(_connectable ?? store.nodesConnectable);
|
||||||
let initialized = $derived(nodeHasDimensions(node));
|
let initialized = $derived(nodeHasDimensions(node));
|
||||||
|
|
||||||
// we also pass store.nodes to this function to rerender when a node changes
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
function getInternalNode(node: Node, nodes: Node[]) {
|
|
||||||
return { ...store.nodeLookup.get(node.id)! };
|
|
||||||
}
|
|
||||||
|
|
||||||
let {
|
|
||||||
internals: {
|
|
||||||
z: zIndex = 0,
|
|
||||||
positionAbsolute: { x: positionX, y: positionY }
|
|
||||||
}
|
|
||||||
} = $derived(getInternalNode(node, store.nodes));
|
|
||||||
|
|
||||||
function isInParentLookup(id: string) {
|
function isInParentLookup(id: string) {
|
||||||
return store.parentLookup.has(id);
|
return store.parentLookup.has(id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import type { SvelteFlowStore } from '$lib/store/types';
|
import type { SvelteFlowStore } from '$lib/store/types';
|
||||||
import type { Node } from '$lib/types';
|
import type { InternalNode } from '$lib/types';
|
||||||
|
|
||||||
export type ConnectableContext = {
|
export type ConnectableContext = {
|
||||||
value: boolean;
|
value: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NodeWrapperProps = {
|
export type NodeWrapperProps = {
|
||||||
node: Node;
|
node: InternalNode;
|
||||||
store: SvelteFlowStore;
|
store: SvelteFlowStore;
|
||||||
nodeClickDistance?: number;
|
nodeClickDistance?: number;
|
||||||
resizeObserver?: ResizeObserver | null;
|
resizeObserver?: ResizeObserver | null;
|
||||||
|
|||||||
@@ -28,10 +28,17 @@
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we reuse the previous edge object if the source and target node are the same as before
|
// we reuse the previous edge object if
|
||||||
// references to internalNodes that haven't changed stay the same
|
// 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);
|
const previous = previousLayoutedEdges.get(edge.id);
|
||||||
if (previous && sourceNode == previous.sourceNode && targetNode == previous.targetNode) {
|
if (
|
||||||
|
previous &&
|
||||||
|
edge == previous.edge &&
|
||||||
|
sourceNode == previous.sourceNode &&
|
||||||
|
targetNode == previous.targetNode
|
||||||
|
) {
|
||||||
layoutedEdges.set(edge.id, previous);
|
layoutedEdges.set(edge.id, previous);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -58,7 +65,8 @@
|
|||||||
}),
|
}),
|
||||||
...edgePosition,
|
...edgePosition,
|
||||||
sourceNode,
|
sourceNode,
|
||||||
targetNode
|
targetNode,
|
||||||
|
edge
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
|
|
||||||
import { NodeWrapper } from '$lib/components/NodeWrapper';
|
import { NodeWrapper } from '$lib/components/NodeWrapper';
|
||||||
|
|
||||||
import type { NodeEvents } from '$lib/types';
|
import type { Node, 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,
|
||||||
@@ -41,10 +42,15 @@
|
|||||||
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 store.nodes as node (node.id)}
|
{#each getNodes(store.nodeLookup, store.nodes) as node (node.id)}
|
||||||
<NodeWrapper
|
<NodeWrapper
|
||||||
{store}
|
{store}
|
||||||
{node}
|
{node}
|
||||||
|
|||||||
@@ -91,13 +91,14 @@ export const getInitialStore = (signals: StoreSignals) => {
|
|||||||
connectionLookup: ConnectionLookup = new Map();
|
connectionLookup: ConnectionLookup = new Map();
|
||||||
edgeLookup: EdgeLookup = new Map();
|
edgeLookup: EdgeLookup = new Map();
|
||||||
|
|
||||||
adoptNodes: Set<string> = $derived.by(() => {
|
adoptNodes: true = $derived.by(() => {
|
||||||
return adoptUserNodes(signals.nodes, this.nodeLookup, this.parentLookup, {
|
adoptUserNodes(signals.nodes, this.nodeLookup, this.parentLookup, {
|
||||||
nodeExtent: this.nodeExtent,
|
nodeExtent: this.nodeExtent,
|
||||||
nodeOrigin: this.nodeOrigin,
|
nodeOrigin: this.nodeOrigin,
|
||||||
elevateNodesOnSelect: false,
|
elevateNodesOnSelect: false,
|
||||||
checkEquality: true
|
checkEquality: true
|
||||||
});
|
});
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
adoptEdges: true = $derived.by(() => {
|
adoptEdges: true = $derived.by(() => {
|
||||||
updateConnectionLookup(this.connectionLookup, this.edgeLookup, signals.edges);
|
updateConnectionLookup(this.connectionLookup, this.edgeLookup, signals.edges);
|
||||||
|
|||||||
@@ -176,4 +176,5 @@ export type EdgeLayouted = Pick<
|
|||||||
targetNode?: Node;
|
targetNode?: Node;
|
||||||
sourceHandleId?: string | null;
|
sourceHandleId?: string | null;
|
||||||
targetHandleId?: string | null;
|
targetHandleId?: string | null;
|
||||||
|
edge: Edge;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user