Merge branch 'xyflow' of github.com:wbkd/react-flow into xyflow

This commit is contained in:
moklick
2023-09-26 12:47:04 +02:00
12 changed files with 106 additions and 51 deletions

View File

@@ -223,7 +223,7 @@ const OverviewFlow = () => {
onEdgeMouseLeave={onEdgeMouseLeave}
onEdgeDoubleClick={onEdgeDoubleClick}
fitView
fitViewOptions={{ padding: 0.2 }}
fitViewOptions={{ padding: 0.1 /*nodes: [{ id: '1' }]*/ }}
attributionPosition="top-right"
maxZoom={Infinity}
onNodesDelete={onNodesDelete}

View File

@@ -131,8 +131,12 @@
{nodeTypes}
{edgeTypes}
fitView
minZoom={0.1}
maxZoom={2.5}
fitViewOptions={{
padding: 0.1,
nodes: [{ id: '1' }, { id: '2' }, { id: '3' }]
}}
minZoom={0}
maxZoom={Infinity}
selectionMode={SelectionMode.Full}
initialViewport={{ x: 100, y: 100, zoom: 2 }}
snapGrid={[25, 25]}

View File

@@ -32,9 +32,21 @@
const edges = writable([]);
const isValidConnection: IsValidConnection = (connection) => connection.target === 'B';
const defaultEdgeOptions = {
animated: true
};
</script>
<SvelteFlow {nodes} {edges} fitView minZoom={0.1} maxZoom={2.5} {isValidConnection}>
<SvelteFlow
{nodes}
{edges}
fitView
minZoom={0.1}
maxZoom={2.5}
{isValidConnection}
{defaultEdgeOptions}
>
<Controls />
<Background variant={BackgroundVariant.Dots} />
</SvelteFlow>

View File

@@ -80,13 +80,13 @@ const createRFStore = () =>
const nextNodes = updateAbsolutePositions(updatedNodes, nodeOrigin);
const nextFitViewDone =
fitViewDone ||
(fitViewOnInit &&
fitView({
...fitViewOnInitOptions,
nodes: nextNodes,
}));
let nextFitViewDone = fitViewDone;
if (!fitViewDone && fitViewOnInit) {
nextFitViewDone = fitView(nextNodes, {
...fitViewOnInitOptions,
nodes: fitViewOnInitOptions?.nodes || nextNodes,
});
}
set({ nodes: nextNodes, fitViewDone: nextFitViewDone });
@@ -241,9 +241,8 @@ const createRFStore = () =>
const { transform, width, height, panZoom, translateExtent } = get();
return panBySystem({ delta, panZoom, transform, translateExtent, width, height });
},
fitView: (options?: FitViewOptions): boolean => {
const { panZoom, nodes, width, height, minZoom, maxZoom, nodeOrigin } = get();
const fitViewNodes = options?.nodes || nodes;
fitView: (nodes: Node[], options?: FitViewOptions): boolean => {
const { panZoom, width, height, minZoom, maxZoom, nodeOrigin } = get();
if (!panZoom) {
return false;
@@ -251,7 +250,7 @@ const createRFStore = () =>
return fitViewSystem(
{
nodes: fitViewNodes as Node[],
nodes,
width,
height,
panZoom,

View File

@@ -155,7 +155,7 @@ export type ReactFlowActions = {
reset: () => void;
triggerNodeChanges: (changes: NodeChange[]) => void;
panBy: PanBy;
fitView: (options?: FitViewOptions) => boolean;
fitView: (nodes: Node[], options?: FitViewOptions) => boolean;
};
export type ReactFlowState = ReactFlowStore & ReactFlowActions;

View File

@@ -1,9 +1,23 @@
<script lang="ts">
import { onMount } from 'svelte';
import { EdgeWrapper } from '$lib/components/EdgeWrapper';
import { MarkerDefinition } from '$lib/container/EdgeRenderer/MarkerDefinition';
import { useStore } from '$lib/store';
import type { DefaultEdgeOptions } from '$lib/types';
const { width, height, elementsSelectable, edgeTree } = useStore();
export let defaultEdgeOptions: DefaultEdgeOptions | undefined;
const {
width,
height,
elementsSelectable,
edgeTree,
edges: { setDefaultOptions }
} = useStore();
onMount(() => {
if (defaultEdgeOptions) setDefaultOptions(defaultEdgeOptions);
});
</script>
{#each $edgeTree as group (group.level)}

View File

@@ -23,6 +23,7 @@
export let nodes: $$Props['nodes'];
export let edges: $$Props['edges'];
export let fitView: $$Props['fitView'] = undefined;
export let fitViewOptions: $$Props['fitViewOptions'] = undefined;
export let minZoom: $$Props['minZoom'] = undefined;
export let maxZoom: $$Props['maxZoom'] = undefined;
export let initialViewport: Viewport = { x: 0, y: 0, zoom: 1 };
@@ -57,6 +58,7 @@
export let onError: $$Props['onError'] = undefined;
export let attributionPosition: $$Props['attributionPosition'] = undefined;
export let proOptions: $$Props['proOptions'] = undefined;
export let defaultEdgeOptions: $$Props['defaultEdgeOptions'] = undefined;
export let defaultMarkerColor = '#b1b1b7';
@@ -81,6 +83,10 @@
store.fitViewOnInit.set(fitView);
}
if (fitViewOptions) {
store.fitViewOptions.set(fitViewOptions);
}
updateStore(store, {
nodeTypes,
edgeTypes,
@@ -153,7 +159,7 @@
>
<Pane on:paneclick panOnDrag={panOnDrag === undefined ? true : panOnDrag}>
<ViewportComponent>
<EdgeRenderer on:edgeclick on:edgecontextmenu />
<EdgeRenderer on:edgeclick on:edgecontextmenu {defaultEdgeOptions} />
<ConnectionLine />
<div class="svelte-flow__edgelabel-renderer" />
<NodeRenderer

View File

@@ -20,7 +20,15 @@ import type {
ProOptions
} from '@xyflow/system';
import type { Edge, Node, NodeTypes, KeyDefinition, EdgeTypes } from '$lib/types';
import type {
Edge,
Node,
NodeTypes,
KeyDefinition,
EdgeTypes,
DefaultEdgeOptions,
FitViewOptions
} from '$lib/types';
import type { Writable } from 'svelte/store';
export type SvelteFlowProps = DOMAttributes<HTMLDivElement> & {
@@ -33,6 +41,7 @@ export type SvelteFlowProps = DOMAttributes<HTMLDivElement> & {
panActivationKey?: KeyDefinition;
deleteKey?: KeyDefinition;
fitView?: boolean;
fitViewOptions?: FitViewOptions;
nodeOrigin?: NodeOrigin;
minZoom?: number;
maxZoom?: number;
@@ -58,6 +67,7 @@ export type SvelteFlowProps = DOMAttributes<HTMLDivElement> & {
autoPanOnNodeDrag?: boolean;
attributionPosition?: PanelPosition;
proOptions?: ProOptions;
defaultEdgeOptions?: DefaultEdgeOptions;
class?: string;
style?: string;

View File

@@ -90,13 +90,39 @@ export function createStore(): SvelteFlowStore {
return;
}
const fitViewOnInitDone =
get(store.fitViewOnInitDone) || (get(store.fitViewOnInit) && fitView({ nodes: nextNodes }));
if (!get(store.fitViewOnInitDone) && get(store.fitViewOnInit)) {
const fitViewOptions = get(store.fitViewOptions);
const fitViewOnInitDone = fitView(nextNodes, {
...fitViewOptions,
nodes: fitViewOptions?.nodes || nextNodes
});
store.fitViewOnInitDone.set(fitViewOnInitDone);
}
store.fitViewOnInitDone.set(fitViewOnInitDone);
store.nodes.set(nextNodes);
}
function fitView(nodes: Node[], options?: FitViewOptions) {
const panZoom = get(store.panZoom);
if (!panZoom) {
return false;
}
return fitViewUtil(
{
nodes,
width: get(store.width),
height: get(store.height),
minZoom: get(store.minZoom),
maxZoom: get(store.maxZoom),
panZoom,
nodeOrigin: get(store.nodeOrigin)
},
options
);
}
function zoomBy(factor: number, options?: ViewportHelperFunctionOptions) {
const panZoom = get(store.panZoom);
@@ -140,28 +166,6 @@ export function createStore(): SvelteFlowStore {
}
}
function fitView(options?: FitViewOptions) {
const panZoom = get(store.panZoom);
const fitViewNodes = options?.nodes || get(store.nodes);
if (!panZoom) {
return false;
}
return fitViewUtil(
{
nodes: fitViewNodes as Node[],
width: get(store.width),
height: get(store.height),
minZoom: get(store.minZoom),
maxZoom: get(store.maxZoom),
panZoom,
nodeOrigin: get(store.nodeOrigin)
},
{}
);
}
function resetSelectedItem<T extends Node | Edge>(item: T) {
if (item.selected) {
return {

View File

@@ -24,7 +24,14 @@ import BezierEdge from '$lib/components/edges/BezierEdge.svelte';
import StraightEdge from '$lib/components/edges/StraightEdge.svelte';
import SmoothStepEdge from '$lib/components/edges/SmoothStepEdge.svelte';
import StepEdge from '$lib/components/edges/StepEdge.svelte';
import type { ConnectionData, NodeTypes, EdgeTypes, EdgeLayouted, Node } from '$lib/types';
import type {
ConnectionData,
NodeTypes,
EdgeTypes,
EdgeLayouted,
Node,
FitViewOptions
} from '$lib/types';
import { createNodesStore, createEdgesStore } from './utils';
export const initConnectionData = {
@@ -64,6 +71,7 @@ export const getInitialStore = () => ({
autoPanOnConnect: writable<boolean>(true),
fitViewOnInit: writable<boolean>(false),
fitViewOnInitDone: writable<boolean>(false),
fitViewOptions: writable<FitViewOptions>(undefined),
panZoom: writable<PanZoomInstance | null>(null),
snapGrid: writable<SnapGrid | null>(null),
dragging: writable<boolean>(false),

View File

@@ -160,7 +160,7 @@ export const getTransformForBounds = (
height: number,
minZoom: number,
maxZoom: number,
padding = 0.1
padding: number
): Transform => {
const xZoom = width / (bounds.width * (1 + padding));
const yZoom = height / (bounds.height * (1 + padding));

View File

@@ -171,7 +171,7 @@ export function fitView<Params extends FitViewParamsBase<NodeBase>, Options exte
options?: Options
) {
const filteredNodes = nodes.filter((n) => {
const isVisible = options?.includeHiddenNodes ? n.width && n.height : !n.hidden;
const isVisible = n.width && n.height && (options?.includeHiddenNodes || !n.hidden);
if (options?.nodes?.length) {
return isVisible && options?.nodes.some((optionNode) => optionNode.id === n.id);
@@ -180,10 +180,8 @@ export function fitView<Params extends FitViewParamsBase<NodeBase>, Options exte
return isVisible;
});
const nodesInitialized = filteredNodes.every((n) => n.width && n.height);
if (nodes.length > 0 && nodesInitialized) {
const bounds = getRectOfNodes(nodes, nodeOrigin);
if (filteredNodes.length > 0) {
const bounds = getRectOfNodes(filteredNodes, nodeOrigin);
const [x, y, zoom] = getTransformForBounds(
bounds,