refactor(edges): simplify edge rendering

This commit is contained in:
moklick
2023-11-16 15:41:30 +01:00
parent b659443507
commit 08e61f3111
12 changed files with 275 additions and 318 deletions
@@ -18,6 +18,7 @@
export let target: $$Props['target'] = '';
export let data: $$Props['data'] = {};
export let style: $$Props['style'] = undefined;
export let zIndex: $$Props['zIndex'] = undefined;
export let animated: $$Props['animated'] = false;
export let selected: $$Props['selected'] = false;
@@ -95,42 +96,44 @@
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
{#if !hidden}
<g
class={cc(['svelte-flow__edge', className])}
class:animated
class:selected
data-id={id}
on:click={onClick}
on:contextmenu={onContextMenu}
aria-label={ariaLabel === null
? undefined
: ariaLabel
? ariaLabel
: `Edge from ${source} to ${target}`}
role="img"
>
<svelte:component
this={edgeComponent}
{id}
{source}
{target}
{sourceX}
{sourceY}
{targetX}
{targetY}
{sourcePosition}
{targetPosition}
{animated}
{selected}
{label}
{labelStyle}
{data}
{style}
{interactionWidth}
sourceHandleId={sourceHandle}
targetHandleId={targetHandle}
markerStart={markerStartUrl}
markerEnd={markerEndUrl}
/>
</g>
<svg class="svelte-flow__edgewrapper" style:zIndex>
<g
class={cc(['svelte-flow__edge', className])}
class:animated
class:selected
data-id={id}
on:click={onClick}
on:contextmenu={onContextMenu}
aria-label={ariaLabel === null
? undefined
: ariaLabel
? ariaLabel
: `Edge from ${source} to ${target}`}
role="img"
>
<svelte:component
this={edgeComponent}
{id}
{source}
{target}
{sourceX}
{sourceY}
{targetX}
{targetY}
{sourcePosition}
{targetPosition}
{animated}
{selected}
{label}
{labelStyle}
{data}
{style}
{interactionWidth}
sourceHandleId={sourceHandle}
targetHandleId={targetHandle}
markerStart={markerStartUrl}
markerEnd={markerEndUrl}
/>
</g>
</svg>
{/if}
@@ -9,7 +9,7 @@
const {
elementsSelectable,
edgeTree,
visibleEdges,
edges: { setDefaultOptions }
} = useStore();
@@ -18,57 +18,47 @@
});
</script>
{#each $edgeTree as group (group.level)}
<svg style="z-index: {group.level}" class="svelte-flow__edges">
{#if group.isMaxLevel} <MarkerDefinition />{/if}
<g>
{#each group.edges as edge (edge.id)}
{@const edgeType = edge.type || 'default'}
{@const selectable = !!(
edge.selectable ||
($elementsSelectable && typeof edge.selectable === 'undefined')
)}
<EdgeWrapper
id={edge.id}
source={edge.source}
target={edge.target}
data={edge.data}
style={edge.style}
animated={edge.animated}
selected={edge.selected}
hidden={edge.hidden}
label={edge.label}
labelStyle={edge.labelStyle}
markerStart={edge.markerStart}
markerEnd={edge.markerEnd}
sourceHandle={edge.sourceHandle}
targetHandle={edge.targetHandle}
sourceX={edge.sourceX}
sourceY={edge.sourceY}
targetX={edge.targetX}
targetY={edge.targetY}
sourcePosition={edge.sourcePosition}
targetPosition={edge.targetPosition}
ariaLabel={edge.ariaLabel}
interactionWidth={edge.interactionWidth}
class={edge.class}
type={edgeType}
{selectable}
on:edgeclick
on:edgecontextmenu
/>
{/each}
</g>
<div class="svelte-flow__edges">
<svg class="svelte-flow__container">
<MarkerDefinition />
</svg>
{/each}
<style>
.svelte-flow__edges {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
</style>
{#each $visibleEdges as edge (edge.id)}
{@const edgeType = edge.type || 'default'}
{@const selectable = !!(
edge.selectable ||
($elementsSelectable && typeof edge.selectable === 'undefined')
)}
<EdgeWrapper
id={edge.id}
source={edge.source}
target={edge.target}
data={edge.data}
style={edge.style}
animated={edge.animated}
selected={edge.selected}
hidden={edge.hidden}
label={edge.label}
labelStyle={edge.labelStyle}
markerStart={edge.markerStart}
markerEnd={edge.markerEnd}
sourceHandle={edge.sourceHandle}
targetHandle={edge.targetHandle}
sourceX={edge.sourceX}
sourceY={edge.sourceY}
targetX={edge.targetX}
targetY={edge.targetY}
sourcePosition={edge.sourcePosition}
targetPosition={edge.targetPosition}
ariaLabel={edge.ariaLabel}
interactionWidth={edge.interactionWidth}
class={edge.class}
type={edgeType}
zIndex={edge.zIndex}
{selectable}
on:edgeclick
on:edgecontextmenu
/>
{/each}
</div>
+2 -2
View File
@@ -24,7 +24,7 @@ import type { EdgeTypes, NodeTypes, Node, Edge, FitViewOptions, ConnectionData }
import { initialEdgeTypes, initialNodeTypes, getInitialStore } from './initial-store';
import type { SvelteFlowStore } from './types';
import { syncNodeStores, syncEdgeStores, syncViewportStores } from './utils';
import { getEdgeTree } from './edge-tree';
import { getVisibleEdges } from './visible-edges';
import { getVisibleNodes } from './visible-nodes';
import { getDerivedConnectionProps } from './derived-connection-props';
@@ -349,8 +349,8 @@ export function createStore({
...store,
// derived state
edgeTree: getEdgeTree(store),
connection: getDerivedConnectionProps(store, currentConnection),
visibleEdges: getVisibleEdges(store),
visibleNodes: getVisibleNodes(store),
markers: derived(
[store.edges, store.defaultMarkerColor, store.flowId],
@@ -91,7 +91,7 @@ export const getInitialStore = ({
nodeLookup: readable<Map<string, Node>>(nodeLookup),
visibleNodes: readable<Node[]>([]),
edges: createEdgesStore(edges),
edgeTree: readable<GroupedEdges<EdgeLayouted>[]>([]),
visibleEdges: readable<EdgeLayouted[]>([]),
height: writable<number>(500),
width: writable<number>(500),
minZoom: writable<number>(0.5),
@@ -1,10 +1,10 @@
import { derived } from 'svelte/store';
import { groupEdgesByZLevel, isEdgeVisible, getEdgePosition } from '@xyflow/system';
import { isEdgeVisible, getEdgePosition, adjustEdgeZIndex } from '@xyflow/system';
import type { EdgeLayouted } from '$lib/types';
import type { SvelteFlowStoreState } from './types';
export function getEdgeTree(store: SvelteFlowStoreState) {
export function getVisibleEdges(store: SvelteFlowStoreState) {
const visibleEdges = derived(
[
store.edges,
@@ -41,8 +41,15 @@ export function getEdgeTree(store: SvelteFlowStoreState) {
);
return derived(
[visibleEdges, store.nodes, store.nodeLookup, store.connectionMode, store.onerror],
([visibleEdges, , nodeLookup, connectionMode, onerror]) => {
[
visibleEdges,
store.nodes,
store.nodeLookup,
store.connectionMode,
store.onlyRenderVisibleElements,
store.onerror
],
([visibleEdges, , nodeLookup, connectionMode, onlyRenderVisibleElements, onerror]) => {
const layoutedEdges = visibleEdges.reduce<EdgeLayouted[]>((res, edge) => {
const sourceNode = nodeLookup.get(edge.source);
const targetNode = nodeLookup.get(edge.target);
@@ -63,7 +70,7 @@ export function getEdgeTree(store: SvelteFlowStoreState) {
if (edgePosition) {
res.push({
...edge,
...adjustEdgeZIndex(edge, nodeLookup, onlyRenderVisibleElements),
...edgePosition
});
}
@@ -71,9 +78,7 @@ export function getEdgeTree(store: SvelteFlowStoreState) {
return res;
}, []);
const groupedEdges = groupEdgesByZLevel<EdgeLayouted>(layoutedEdges, nodeLookup, false);
return groupedEdges;
return layoutedEdges;
}
);
}
+1
View File
@@ -70,6 +70,7 @@ export type EdgeLayouted = Pick<
| 'ariaLabel'
| 'hidden'
| 'class'
| 'zIndex'
> &
EdgePosition & {
sourceNode?: Node;