@yworks/yfiles-layout-reactflow
Version:
yFiles Layouts for React Flow - A layout library for React Flow providing powerful yFiles layout algorithms and supporting components
1,243 lines (1,191 loc) • 50.4 kB
TypeScript
import { CircularLayoutEdgeDescriptor } from '@yfiles/yfiles';
import { CircularLayoutExteriorEdgeDescriptor } from '@yfiles/yfiles';
import { ComponentType } from 'react';
import { CSSProperties } from 'react';
import { Edge } from '@xyflow/react';
import { EdgeProps } from '@xyflow/react';
import { EdgeRouterEdgeDescriptor } from '@yfiles/yfiles';
import { HierarchicalLayoutEdgeDescriptor } from '@yfiles/yfiles';
import { HierarchicalLayoutNodeDescriptor } from '@yfiles/yfiles';
import { IGraph } from '@yfiles/yfiles';
import { ISubtreePlacer } from '@yfiles/yfiles';
import { LabelingCosts } from '@yfiles/yfiles';
import { Node as Node_2 } from '@xyflow/react';
import { NodeProps } from '@xyflow/react';
import { OrthogonalLayoutEdgeDescriptor } from '@yfiles/yfiles';
import { PartitionDescriptor } from '@yfiles/yfiles';
import { Position } from '@xyflow/react';
import * as react_jsx_runtime from 'react/jsx-runtime';
import { ReactNode } from 'react';
import { RefObject } from 'react';
/**
* A provider for child order comparators.
*
* For more information, see [ChildOrderData]{@link https://docs.yworks.com/yfileshtml/#/api/ChildOrderData}.
*/
export declare interface ChildOrderDataProvider<TNodeData, TEdgeData> {
/** Provides which edge should come first. */
outEdgeComparators?: (node: TNodeData) => (edge1: TEdgeData, edge2: TEdgeData) => number;
}
/**
* A provider for individual options per nodes or edges in a
* [CircularLayout]{@link https://docs.yworks.com/yfileshtml/#/api/CircularLayout}.
* It allows for defining a function that provide values for each element.
*
* For more information, see [CircularLayoutData]{@link https://docs.yworks.com/yfileshtml/#/api/CircularLayoutData}.
*/
export declare interface CircularLayoutDataProvider<TNodeData, TEdgeData> {
/** Provides 0, 1, or -1 for each edge to indicate if it is undirected, in layout direction, or against layout direction. */
edgeDirectedness?: (edge: TEdgeData) => number;
/** Provides the paddings for the group nodes, i.e., a rectangular area like padding in the interior of the node. */
groupNodePadding?: (node: TNodeData) => Insets;
/** Provides margins for nodes, i.e., a rectangular area around a specific node considered during the layout. */
nodeMargins?: (node: TNodeData) => NodeMargins;
/** Provides types which can influence the ordering of nodes during layout. */
nodeTypes?: (node: TNodeData) => any;
}
/**
* The configuration options for the circular layout algorithm that arranges graphs in a circular fashion.
* <p>
* For more information on the layout algorithm and its available settings,
* see [CircularLayout]{@link https://docs.yworks.com/yfileshtml/#/api/CircularLayout}.
* </p>
*/
export declare interface CircularLayoutOptions {
edgeDescriptor?: CircularLayoutEdgeDescriptor;
edgeRoutingPolicy?: 'interior' | 'automatic' | 'exterior';
exteriorEdgeDescriptor?: CircularLayoutExteriorEdgeDescriptor;
fromSketchMode?: boolean;
maximumDeviationAngle?: number;
nodeLabelPlacement?: 'consider' | 'generic' | 'ignore' | 'ray-like' | 'ray-like-leaves' | 'horizontal';
nodeLabelSpacing?: number;
partitionDescriptor?: PartitionDescriptor;
partitioningPolicy?: 'bcc-compact' | 'bcc-isolated' | 'single-cycle';
placeChildrenOnCommonRadius?: boolean;
starSubstructureSize?: number;
starSubstructureStyle?: 'none' | 'radial' | 'separated-radial';
starSubstructureTypeSeparation?: boolean;
}
/**
* The data that can be attached to an edge in the graph.
* This type extends the edge data with layout-specific information.
*/
export declare type EdgeData = {
/** The layout-specific information calculated by the layout algorithm. */
yData?: EdgeLayoutData;
/** The texts to display as the edge's labels. */
labels?: string[];
};
/**
* A descriptor for the placement of an edge label.
*/
export declare interface EdgeLabelPreferredPlacement {
/** The rotation angle of the label. */
angle?: number;
/** Whether to interpret the rotation angle relative to the edge direction. */
angleReference?: 'absolute' | 'relative-to-edge-flow';
/** The preferred distance between a label and the corresponding edge segment. */
distanceToEdge?: number;
/** Whether to place the label left, right, or on the edge. */
edgeSide?: 'left-of-edge' | 'on-edge' | 'right-of-edge';
/** Whether to place the label at the center, source, or target of the edge. */
placementAlongEdge?: 'at-source' | 'at-center' | 'at-target';
}
/**
* A component that renders edge labels with text that are placed at coordinates that resulted from a yFiles layout
* algorithm. At a single edge, there can be multiple edge labels which may be rotated.
*
* ```tsx
* export function CustomEdge(props: EdgeProps) {
* const [edgePath] = getPolylinePath({
* sourceX: props.sourceX,
* sourceY: props.sourceY,
* targetX: props.targetX,
* targetY: props.targetY,
* bends: props.data?.yData?.bends ?? []
* })
*
* return (
* <>
* <BaseEdge path={edgePath} {...props} />
* <EdgeLabelRenderer>
* <EdgeLabels
* labels={labels}
* ownerId={props.id}
* labelBoxes={props.data?.yData?.labelBoxes ?? []}
* ></EdgeLabels>
* </EdgeLabelRenderer>
* </>
* )
* }
* ```
*/
export declare function EdgeLabels({ labels, ownerId, labelBoxes, labelStyle }: EdgeLabelsProps): react_jsx_runtime.JSX.Element;
/**
* The properties that describe the labels of an edge with their layout and styling.
*/
export declare interface EdgeLabelsProps {
/**
* The list of labels for the given edge.
*/
labels: (Label | string | ReactNode)[];
/**
* The id of the edge to which the labels belong.
*/
ownerId: string;
/**
* The layout information for the labels.
*/
labelBoxes: LabelBox[];
/**
* An optional CSS style used for the label.
*/
labelStyle?: CSSProperties;
/**
* An optional CSS class used for styling the label.
*/
className?: string;
}
/**
* The result of the layout algorithm, which provides all the necessary information
* to route the edges and arrange the labels.
* This information will be stored in the `data.yData` of each edge.
*/
export declare interface EdgeLayoutData {
/**
* The bend points of an edge.
* This information will be used by the {@link PolylineEdge} to draw the edge path.
*/
bends: {
x: number;
y: number;
}[];
/**
* The layout information about the labels of a node or an edge.
* This information will be used by the {@link EdgeLabels} component.
*/
labelBoxes: LabelBox[];
/**
* The coordinates of an edge's source point relative to its source node's center.
* This information will be used by the {@link PolylineEdge} to draw the edge path.
*/
sourcePoint: {
x: number;
y: number;
};
/**
* The coordinates of an edge's target point relative to its target node's center.
* This information will be used by the {@link PolylineEdge} to draw the edge path.
*/
targetPoint: {
x: number;
y: number;
};
}
/**
* A provider for individual options per nodes or edges in a
* [EdgeRouter]{@link https://docs.yworks.com/yfileshtml/#/api/EdgeRouter}.
* It allows for defining a function that provide values for each element.
*
* For more information, see [EdgeRouterData]{@link https://docs.yworks.com/yfileshtml/#/api/EdgeRouterData}.
*/
export declare interface EdgeRouterDataProvider<TNodeData, TEdgeData> {
/** Provides descriptors for the placement of edge labels. */
edgeLabelPreferredPlacements?: (label: LabelData) => EdgeLabelPreferredPlacement;
/** Provides margins for nodes, i.e., a rectangular area around a specific node considered during the layout. */
nodeMargins?: (node: TNodeData) => NodeMargins;
/** Provides information about how an edge connects to its nodes. */
ports?: PortDataProvider<TEdgeData>;
/** Provides which edges should be routed. */
scope?: EdgeRouterScopeDataProvider<TNodeData, TEdgeData>;
/** Provides which edges should be grouped at source, i.e., share the beginning of their routes. */
sourceGroupIds?: (edge: TEdgeData) => any;
/** Provides which edges should be grouped at target, i.e., share the end of their routes. */
targetGroupIds?: (edge: TEdgeData) => any;
}
/**
* The configuration options for the edge routing algorithm that applies polyline routes to the edges of the graph.
* <p>
* For more information on layout algorithm and its available settings,
* see [EdgeRouter]{@link https://docs.yworks.com/yfileshtml/#/api/EdgeRouter}.
* </p>
*/
export declare interface EdgeRouterOptions {
defaultEdgeDescriptor?: EdgeRouterEdgeDescriptor;
edgeLabelPlacement?: 'consider-unaffected-edge-labels' | 'generic' | 'ignore' | 'integrated';
gridSpacing?: number;
minimumNodeToEdgeDistance?: number;
nodeLabelPlacement?: 'consider' | 'generic' | 'ignore' | 'ignore-group-labels';
rerouting?: boolean;
stopDuration?: number;
}
/**
* A provider for scope options in [EdgeRouter]{@link https://docs.yworks.com/yfileshtml/#/api/EdgeRouter}.
* It allows for defining a function that provide values for each element.
*
* For more information, see [EdgeRouterScopeData]{@link https://docs.yworks.com/yfileshtml/#/api/EdgeRouterScopeData}.
*/
export declare interface EdgeRouterScopeDataProvider<TNodeData, TEdgeData> {
/** Provides which edges should be routed. */
edges?: (edge: TEdgeData) => boolean;
/** Provides at which nodes edges should be routed. */
incidentNodes?: (node: TNodeData) => boolean;
}
/**
* A provider for individual options per nodes or edges in a
* [Labeling]{@link https://docs.yworks.com/yfileshtml/#/api/GenericLabeling}.
* It allows for defining a function that provide values for each element.
*
* For more information, see [LabelingData]{@link https://docs.yworks.com/yfileshtml/#/api/GenericLabelingData}.
*/
export declare interface GenericLabelingDataProvider {
/** Provides which labels should be placed. */
affectedLabels?: (label: LabelData) => boolean;
/** Provides descriptors for the placement of edge labels. */
edgeLabelPreferredPlacements?: (label: LabelData) => EdgeLabelPreferredPlacement;
}
/**
* The configuration options for the labeling algorithm that places the labels of a graph.
* <p>
* For more information on the labeling algorithm and its available settings,
* see [GenericLabeling]{@link https://docs.yworks.com/yfileshtml/#/api/GenericLabeling}.
* </p>
*/
export declare interface GenericLabelingOptions {
defaultEdgeLabelingCosts?: LabelingCosts;
defaultNodeLabelingCosts?: LabelingCosts;
deterministic?: boolean;
moveInternalNodeLabels?: boolean;
reduceLabelOverlaps?: boolean;
scope?: 'all' | 'edge-labels' | 'node-labels';
stopDuration?: number;
}
/**
* The function `getPolylinePath` returns everything you need to render a polyline edge between two nodes.
*
* ```tsx
* export function CustomEdge(props: EdgeProps) {
* const [edgePath] = getPolylinePath({
* sourceX: props.sourceX,
* sourceY: props.sourceY,
* targetX: props.targetX,
* targetY: props.targetY,
* bends: props.data?.yData?.bends ?? []
* })
*
* return ( <BaseEdge path={edgePath} {...props} /> )
* }
* ```
*
* @param params - The coordinates of the source point, the target point, and the bends.
* @returns an array that contains the edge path, the center location of the edge, e.g. to place a label, and the
* relative center location of the edge.
*/
export declare function getPolylinePath(params: PolylinePathProps): [path: string, labelX: number, labelY: number, offsetX: number, offsetY: number];
/**
* A provider for individual options per nodes or edges in a
* [HierarchicalLayout]{@link https://docs.yworks.com/yfileshtml/#/api/HierarchicalLayout}.
* It allows for defining a function that provide values for each element.
*
* For more information, see [HierarchicalLayoutData]{@link https://docs.yworks.com/yfileshtml/#/api/HierarchicalLayoutData}.
*/
export declare interface HierarchicalLayoutDataProvider<TNodeData, TEdgeData> {
/** Provides 0, 1, or -1 for each edge to indicate if it is undirected, in layout direction, or against layout direction. */
edgeDirectedness?: (edge: TEdgeData) => number;
/** Provides descriptors for the placement of edge labels. */
edgeLabelPreferredPlacements?: (label: LabelData) => EdgeLabelPreferredPlacement;
/** Provides a numerical value that represents the thickness of an edge. */
edgeThickness?: (edge: TEdgeData) => number;
/** Provides the paddings for the group nodes, i.e., a rectangular area like padding in the interior of the node. */
groupNodePadding?: (node: TNodeData) => Insets;
/** Provides margin for nodes, i.e., a rectangular area around a specific node considered during the layout. */
nodeMargins?: (node: TNodeData) => NodeMargins;
/** Provides types which can influence the ordering of nodes during layout. */
nodeTypes?: (node: TNodeData) => any;
/** Provides information about how an edge connects to its nodes. */
ports?: PortDataProvider<TEdgeData>;
/** Provides which edges should be grouped at source, i.e., share the beginning of their routes. */
sourceGroupIds?: (edge: TEdgeData) => any;
/** Provides which edges should be grouped at target, i.e., share the end of their routes. */
targetGroupIds?: (edge: TEdgeData) => any;
}
/**
* The configuration options for the hierarchical layout algorithm that arranges graphs in a hierarchical fashion.
* <p>
* For more information on the layout algorithm and its available settings,
* see [HierarchicalLayout]{@link https://docs.yworks.com/yfileshtml/#/api/HierarchicalLayout}.
* </p>
*/
export declare interface HierarchicalLayoutOptions {
automaticEdgeGrouping?: boolean;
componentArrangementPolicy?: 'compact' | 'topmost';
defaultEdgeDescriptor?: HierarchicalLayoutEdgeDescriptor;
defaultNodeDescriptor?: HierarchicalLayoutNodeDescriptor;
edgeDistance?: number;
edgeLabelPlacement?: 'generic' | 'ignore' | 'integrated';
fromScratchLayeringStrategy?: 'hierarchical-topmost' | 'hierarchical-optimal' | 'hierarchical-tight-tree' | 'hierarchical-downshift' | 'bfs' | 'from-sketch' | 'user-defined' | 'unknown';
fromSketchMode?: boolean;
gridSpacing?: number;
groupAlignmentPolicy?: 'top' | 'center' | 'bottom';
groupLayeringPolicy?: 'ignore-groups' | 'recursive' | 'recursive-compact';
layoutOrientation?: 'top-to-bottom' | 'left-to-right' | 'right-to-left' | 'bottom-to-top';
minimumLayerDistance?: number;
nodeDistance?: number;
nodeLabelPlacement?: 'consider' | 'generic' | 'ignore';
nodeToEdgeDistance?: number;
stopDuration?: number;
}
/**
* Initializes a Web Worker for the layout calculation.
*
* For example, this function can be used in a Web Worker for asynchronous layout calculation.
*
* ```tsx
* // LayoutWorker.ts
* import { initializeWebWorker } from '@yworks/yfiles-layout-reactflow/WebWorkerSupport'
* initializeWebWorker(self)
* ```
*
* ```tsx
* // index.tsx
* const layoutWorker = new Worker(new URL('./LayoutWorker', import.meta.url), {
* type: 'module'
* })
*
* const LayoutFlow = () => {
* const [nodes] = useNodesState(initialNodes)
* const [edges] = useEdgesState(initialEdges)
*
* const { runLayout } = useLayout({ layoutWorker })
*
* return (
* <ReactFlow>
* <Panel position="top-left">
* <button onClick={() => runLayout('HierarchicalLayout')}>Layout</button>
* </Panel>
* </ReactFlow>
* )
* }
*
* export default function Flow() {
* return (
* <ReactFlowProvider>
* <LayoutFlow />
* </ReactFlowProvider>
* )
* }
* ```
* @param self - The current worker
*/
export declare function initializeWebWorker(self: Window): void;
/**
* Represents the padding for a group node, i.e., a rectangular area inside the group node.
* If only a number is specified, the padding on all sides are the same.
*/
export declare type Insets = {
top: number;
left: number;
bottom: number;
right: number;
} | number;
/**
* A label with a text and styling properties.
*/
export declare interface Label {
/** The text of the label. */
label: string;
/** An optional CSS style used for the label. */
labelStyle?: CSSProperties;
/** An optional CSS class used for styling the label. */
className?: string;
}
/**
* The layout information of a label.
*/
export declare interface LabelBox {
/** The label id. */
id: string;
/** The x-coordinate of the label. */
x: number;
/** The y-coordinate of the label. */
y: number;
/** The width of the label. */
width: number;
/** The height of the label. */
height: number;
/**
* The rotation angle of the label in degrees.
* Used for checking whether the text has to be flipped and for retrieving the angle information from previous layouts.
*/
angle: number;
/**
* The CSS transform to be applied on the label element based on the result of the layout algorithm.
* By default, for edges the transform-origin is set to '0px 0px'.
*/
transform: string;
}
/**
* The properties that describe a label to the layout algorithm.
*/
export declare interface LabelData {
/** The label representation in the data. */
data: string | Label | ReactNode;
/** The index of the label in the list of labels attached to the same node or edge. */
labelIndex: number;
/** The id of the associated node or edge. */
ownerId: string;
}
/**
* All layout configurations supported by {@link useLayout}.
*/
export declare type LayoutAlgorithmOptions = GenericLabelingOptions | RadialTreeLayoutOptions | HierarchicalLayoutOptions | CircularLayoutOptions | OrganicLayoutOptions | OrthogonalLayoutOptions | EdgeRouterOptions | RadialLayoutOptions | TreeLayoutOptions;
/**
* The layout configuration is an object consisting of the layout name, and optionally, the layout options
* for the selected layout algorithm and the layout data provider.
*/
export declare type LayoutConfiguration<LayoutType = LayoutName, TNodeData = NodeProps, TEdgeData = EdgeProps> = LayoutType extends 'HierarchicalLayout' ? {
name: LayoutType;
layoutOptions?: HierarchicalLayoutOptions;
layoutData?: HierarchicalLayoutDataProvider<TNodeData, TEdgeData>;
} : LayoutType extends 'OrthogonalLayout' ? {
name: LayoutType;
layoutOptions?: OrthogonalLayoutOptions;
layoutData?: OrthogonalLayoutDataProvider<TNodeData, TEdgeData>;
} : LayoutType extends 'RadialLayout' ? {
name: LayoutType;
layoutOptions?: RadialLayoutOptions;
layoutData?: RadialLayoutDataProvider<TNodeData, TEdgeData>;
} : LayoutType extends 'CircularLayout' ? {
name: LayoutType;
layoutOptions?: CircularLayoutOptions;
layoutData?: CircularLayoutDataProvider<TNodeData, TEdgeData>;
} : LayoutType extends 'OrganicLayout' ? {
name: LayoutType;
layoutOptions?: OrganicLayoutOptions;
layoutData?: OrganicLayoutDataProvider<TNodeData, TEdgeData>;
} : LayoutType extends 'TreeLayout' ? {
name: LayoutType;
layoutOptions?: TreeLayoutOptions;
layoutData?: TreeLayoutDataProvider<TNodeData, TEdgeData>;
} : LayoutType extends 'RadialTreeLayout' ? {
name: LayoutType;
layoutOptions?: RadialTreeLayoutOptions;
layoutData?: RadialTreeLayoutDataProvider<TNodeData, TEdgeData>;
} : LayoutType extends 'EdgeRouter' ? {
name: LayoutType;
layoutOptions?: EdgeRouterOptions;
layoutData?: EdgeRouterDataProvider<TNodeData, TEdgeData>;
} : LayoutType extends 'GenericLabeling' ? {
name: LayoutType;
layoutOptions?: GenericLabelingOptions;
layoutData?: GenericLabelingDataProvider;
} : {
name: LayoutType;
layoutOptions?: undefined;
layoutData?: undefined;
};
/**
* Context information for running a layout algorithm.
*/
export declare interface LayoutContext {
/** A Web Worker for asynchronous layout calculation. */
layoutWorker?: Worker;
/**
* An optional reference to the React Flow element. This reference is particularly useful in scenarios where there
* are multiple React Flow elements on the same page or when the flow is encapsulated within a closed shadow DOM.
*/
reactFlowRef?: RefObject<HTMLDivElement>;
/**
* A callback function invoked when an error occurs during the layout process.
* It allows developers to handle errors and perform necessary actions when layout errors occur.
*/
onError?: (error: unknown) => void;
}
/**
* All providers for the additional data for layout algorithms supported by {@link useLayout}.
*/
export declare type LayoutDataProvider<TNodeData, TEdgeData> = GenericLabelingDataProvider | RadialTreeLayoutDataProvider<TNodeData, TEdgeData> | HierarchicalLayoutDataProvider<TNodeData, TEdgeData> | CircularLayoutDataProvider<TNodeData, TEdgeData> | OrganicLayoutDataProvider<TNodeData, TEdgeData> | OrthogonalLayoutDataProvider<TNodeData, TEdgeData> | EdgeRouterDataProvider<TNodeData, TEdgeData> | RadialLayoutDataProvider<TNodeData, TEdgeData> | TreeLayoutDataProvider<TNodeData, TEdgeData>;
/**
* The names of the layout algorithms {@link useLayout} supports.
*/
export declare type LayoutName = 'GenericLabeling' | 'RadialTreeLayout' | 'HierarchicalLayout' | 'CircularLayout' | 'OrganicLayout' | 'OrthogonalLayout' | 'EdgeRouter' | 'RadialLayout' | 'TreeLayout';
/**
* Contains helper functions to transfer node and edge data to a layout graph and back.
*/
export declare interface LayoutSupport {
/**
* Creates a graph from the given data that can be arranged by a yFiles layout algorithm.
*/
buildGraph: (nodes: Node_2[], edges: Edge[], zoom: number) => IGraph;
/**
* Transfers the calculated layout from the graph to lists of nodes and edges.
*/
transferLayout: (graph: IGraph) => {
arrangedNodes: Node_2[];
arrangedEdges: Edge[];
};
}
/**
* A node component with multiple handles and a label that supports the results of a yFiles layout
* algorithm.
*
* The information about the position of each handle will be given by the `data.yData` of each node,
* if any exists (see {@link NodeLayoutData}). Otherwise, handles will be placed on the top and on the bottom side of each node.
*
* ```tsx
* const nodeTypes = {
* handles: MultiHandleNode
* }
*
* const LayoutFlow = () => {
* const [nodes] = useNodesState(initialNodes)
* const [edges] = useEdgesState(initialEdges)
*
* return (
* <ReactFlow
* nodes={nodes}
* edges={edges}
* nodeTypes={nodeTypes}
* ></ReactFlow>
* )
* }
*
* export default function Flow() {
* return (
* <ReactFlowProvider>
* <LayoutFlow />
* </ReactFlowProvider>
* )
* }
* ```
*
* @param props - The properties of a React Flow node.
*/
export declare function MultiHandleNode(props: NodeProps): react_jsx_runtime.JSX.Element;
/**
* The data that can be attached to a node in the graph.
* This type extends the node data with layout-specific information.
*/
export declare type NodeData = {
/** The CSS properties to style the node's label. */
labelStyle?: CSSProperties;
/** The CSS class name to style the node. */
className?: string;
/** The text to display as the node's label. */
label?: string;
/** The layout-specific information calculated by the layout algorithm. */
yData?: NodeLayoutData;
};
/**
* A component that renders a node label with text that is placed at coordinates that resulted from a yFiles layout algorithm.
* Node labels can appear outside the node and be rotated.
* The text must be specified in `data.label` and the label box is retrieved from data.yData.labelBoxes.
*
* ```tsx
* export function CustomNode(props: NodeProps) {
* return (
* <>
* <NodeLabel {...props}></NodeLabel>
* </>
* )
* }
* ```
*/
export declare function NodeLabel({ data, id }: NodeProps<Node_2<NodeData>>): react_jsx_runtime.JSX.Element | undefined;
/**
* The result of the layout algorithm that provides all the necessary information
* to place the nodes and their handles, and arrange the labels.
* This information will be stored in the `data.yData` of each node.
*/
export declare interface NodeLayoutData {
/**
* The layout information about the labels of a node or an edge.
* This information will be used by the {@link NodeLabel} component.
*/
labelBoxes: LabelBox[];
/**
* The id, the location, and the side of the handle on the source node of the edge.
* This information will be used by the {@link MultiHandleNode} to arrange the node
* handles.
*/
sourceHandles: {
id: string;
location: {
x: number;
y: number;
};
position: Position;
}[];
/**
* The id, the location, and the side of the handle on the target node of the edge.
* This information will be used by the {@link MultiHandleNode} to arrange the node
* handles.
*/
targetHandles: {
id: string;
location: {
x: number;
y: number;
};
position: Position;
}[];
}
/**
* Represents margins for nodes, i.e., a rectangular area around each node in which no other graph
* elements can be placed during the layout. If only a number is specified, the margins extend the same on all sides.
*/
export declare type NodeMargins = {
top: number;
left: number;
bottom: number;
right: number;
} | number;
/**
* A provider for individual options per nodes or edges in a
* [OrganicLayout]{@link https://docs.yworks.com/yfileshtml/#/api/OrganicLayout}.
* It allows for defining a function that provide values for each element.
*
* For more information, see [OrganicLayoutData]{@link https://docs.yworks.com/yfileshtml/#/api/OrganicLayoutData}.
*/
export declare interface OrganicLayoutDataProvider<TNodeData, TEdgeData> {
/** Provides descriptors for the placement of edge labels. */
edgeLabelPreferredPlacements?: (label: LabelData) => EdgeLabelPreferredPlacement;
/** Provides the paddings for the group nodes, i.e., a rectangular area like padding in the interior of the node. */
groupNodePadding?: (node: TNodeData) => Insets;
/** Provides the minimal length that an edge should have. */
minimumEdgeLengths?: (edge: TEdgeData) => number;
/** Provides the minimal distance from a node to all other nodes. */
minimumNodeDistances?: (node: TNodeData) => number;
/** Provides margins for nodes, i.e., a rectangular area around a specific node considered during the layout. */
nodeMargins?: (node: TNodeData) => NodeMargins;
/** Provides types which can influence the ordering of nodes during layout. */
nodeTypes?: (node: TNodeData) => any;
/** Provides the preferred length for an edge. It is not mandatory but works as a guidance length. */
preferredEdgeLengths?: (edge: TEdgeData) => number;
/** Provides which nodes should be placed. */
scope?: OrganicScopeDataProvider<TNodeData>;
}
/**
* The configuration options for the organic layout algorithm that arranges graphs in an organic fashion.
* <p>
* For more information on the layout algorithm and its available settings,
* see [OrganicLayout]{@link https://docs.yworks.com/yfileshtml/#/api/OrganicLayout}.
* </p>
*/
export declare interface OrganicLayoutOptions {
allowClusterAsGroupSubstructure?: boolean;
allowNodeOverlaps?: boolean;
automaticGroupNodeCompaction?: boolean;
avoidNodeEdgeOverlap?: boolean;
chainRecognition?: boolean;
chainSubstructureSize?: number;
chainSubstructureStyle?: 'none' | 'rectangular' | 'rectangular-nested' | 'straight-line' | 'straight-line-nested' | 'disk' | 'disk-nested';
circleRecognition?: boolean;
clusteringPolicy?: 'none' | 'louvain-modularity' | 'edge-betweenness' | 'label-propagation' | 'user-defined';
compactnessFactor?: number;
cycleSubstructureSize?: number;
cycleSubstructureStyle?: 'none' | 'circular' | 'circular-nested';
defaultMinimumNodeDistance?: number;
defaultPreferredEdgeLength?: number;
deterministic?: boolean;
edgeLabelPlacement?: 'generic' | 'ignore' | 'integrated';
groupNodeCompactness?: number;
groupSubstructureScope?: 'no-groups' | 'groups-without-edges' | 'groups-without-inter-edges' | 'all-groups';
groupSubstructureSize?: number;
groupSubstructureStyle?: 'circle' | 'compact-disk' | 'disk' | 'organic-disk';
layoutOrientation?: 'top-to-bottom' | 'left-to-right' | 'right-to-left' | 'bottom-to-top';
nodeLabelPlacement?: 'consider' | 'generic' | 'ignore';
parallelSubstructureSize?: number;
parallelSubstructureStyle?: 'none' | 'rectangular' | 'radial' | 'straight-line';
parallelSubstructureTypeSeparation?: boolean;
preferredMinimumNodeToEdgeDistance?: number;
qualityTimeRatio?: number;
starSubstructureSize?: number;
starSubstructureStyle?: 'none' | 'radial' | 'radial-nested' | 'separated-radial' | 'circular' | 'circular-nested';
starSubstructureTypeSeparation?: boolean;
stopDuration?: number;
treeSubstructureSize?: number;
treeSubstructureStyle?: 'none' | 'oriented' | 'radial' | 'radial-tree';
}
/**
* A provider for scope options in [OrganicLayout]{@link https://docs.yworks.com/yfileshtml/#/api/OrganicLayout}.
* It allows for defining a function that provide values for each element.
*
* For more information, see [OrganicScopeData]{@link https://docs.yworks.com/yfileshtml/#/api/OrganicScopeData}.
*/
export declare interface OrganicScopeDataProvider<TNodeData> {
/** Provides how group nodes are handled. */
groupNodeHandlingPolicies?: (node: TNodeData) => 'fix-bounds' | 'fix-contents' | 'free';
/** Provides which nodes should be placed. */
nodes?: (node: TNodeData) => boolean;
/** Provides when to place a node. */
scopeModes?: (node: TNodeData) => 'affected' | 'fixed' | 'include-close-nodes' | 'include-extended-neighborhood';
}
/**
* A provider for individual options per nodes or edges in a
* [OrthogonalLayout]{@link https://docs.yworks.com/yfileshtml/#/api/OrthogonalLayout}.
* It allows for defining a function that provide values for each element.
*
* For more information, see [OrthogonalLayoutData]{@link https://docs.yworks.com/yfileshtml/#/api/OrthogonalLayoutData}.
*/
export declare interface OrthogonalLayoutDataProvider<TNodeData, TEdgeData> {
/** Provides 0, 1, or -1 for each edge to indicate if it is undirected, in layout direction, or against layout direction. */
edgeDirectedness?: (edge: TEdgeData) => number;
/** Provides descriptors for the placement of edge labels. */
edgeLabelPreferredPlacements?: (label: LabelData) => EdgeLabelPreferredPlacement;
/** Provides the paddings for the group nodes, i.e., a rectangular area like padding in the interior of the node. */
groupNodePadding?: (node: TNodeData) => Insets;
/** Provides margins for nodes, i.e., a rectangular area around a specific node considered during the layout. */
nodeMargins?: (node: TNodeData) => NodeMargins;
/** Provides types which can influence the ordering of nodes during layout. */
nodeTypes?: (node: TNodeData) => any;
/** Provides which edges should be grouped at source, i.e., share the beginning of their routes. */
sourceGroupIds?: (edge: TEdgeData) => any;
/** Provides which edges should be grouped at target, i.e., share the end of their routes. */
targetGroupIds?: (edge: TEdgeData) => any;
}
/**
* The configuration options for the Orthogonal layout algorithm that arranges graphs in an orthogonal fashion.
* <p>
* For more information on the layout algorithm and its available settings,
* see [OrthogonalLayout]{@link https://docs.yworks.com/yfileshtml/#/api/OrthogonalLayout}.
* </p>
*/
export declare interface OrthogonalLayoutOptions {
alignDegreeOneNodes?: boolean;
chainSubstructureSize?: number;
chainSubstructureStyle?: 'none' | 'straight' | 'wrapped-with-nodes-at-turns' | 'wrapped-with-bends-at-turns';
cycleSubstructureSize?: number;
cycleSubstructureStyle?: 'none' | 'circular' | 'circular-with-nodes-at-corners' | 'circular-with-bends-at-corners';
defaultEdgeDescriptor?: OrthogonalLayoutEdgeDescriptor;
edgeLabelPlacement?: 'generic' | 'ignore' | 'integrated';
fromSketchMode?: boolean;
gridSpacing?: number;
layoutOrientation?: 'top-to-bottom' | 'left-to-right' | 'right-to-left' | 'bottom-to-top';
nodeLabelPlacement?: 'consider' | 'generic' | 'ignore';
preferParallelRoutes?: boolean;
stopDuration?: number;
treeSubstructureOrientation?: 'top-to-bottom' | 'bottom-to-top' | 'left-to-right' | 'right-to-left' | 'auto-detect';
treeSubstructureSize?: number;
treeSubstructureStyle?: 'none' | 'default' | 'integrated' | 'compact' | 'aspect-ratio';
uniformPortAssignment?: boolean;
}
/**
* An edge component that supports bends and the result of a yFiles layout
* algorithm.
*
* The information about the edge path after running a layout algorithm will be given by the `data.yData`
* of each edge, see {@link EdgeLayoutData}.
*
* ```tsx
* const edgeTypes = {
* polyline: PolylineEdge
* }
*
* const LayoutFlow = () => {
* const [nodes] = useNodesState(initialNodes)
* const [edges] = useEdgesState(initialEdges)
*
* return (
* <ReactFlow
* nodes={nodes}
* edges={edges}
* edgeTypes={edgeTypes}
* ></ReactFlow>
* )
* }
*
* export default function Flow() {
* return (
* <ReactFlowProvider>
* <LayoutFlow />
* </ReactFlowProvider>
* )
* }
* ```
*
* @param props - The properties of a React Flow edge
*/
export declare function PolylineEdge(props: EdgeProps<Edge<EdgeData>>): react_jsx_runtime.JSX.Element;
/**
* Parameters that describe a polyline edge path.
*/
export declare interface PolylinePathProps {
/**
* The x-coordinate of the source point of the edge.
*/
sourceX: number;
/**
* The y-coordinate of the source point of the edge.
*/
sourceY: number;
/**
* The x-coordinate of the target point of the edge.
*/
targetX: number;
/**
* The y-coordinate of the target point of the edge.
*/
targetY: number;
/**
* The coordinates of the bends.
*/
bends: {
x: number;
y: number;
}[];
}
/**
* A provider for port data.
*
* For more information, see [PortData]{@link https://docs.yworks.com/yfileshtml/#/api/PortData}.
*/
export declare interface PortDataProvider<TEdgeData> {
/** Provides ids to align the source ports of edges at the same node. */
sourcePortAlignmentIds?: (edge: TEdgeData) => any;
/** Provides the sides of a node at which the edge should start. */
sourcePortCandidates?: (edge: TEdgeData) => PortSides[];
/** Provides ids to group edges at their source. */
sourcePortGroupIds?: (edge: TEdgeData) => any;
/** Provides ids to align the target ports of edges at the same node. */
targetPortAlignmentIds?: (edge: TEdgeData) => any;
/** Provides the sides of a node at which the edge should end. */
targetPortCandidates?: (edge: TEdgeData) => PortSides[];
/** Provides ids to group edges at their target. */
targetPortGroupIds?: (edge: TEdgeData) => any;
}
/**
* The port sides supported by layout data providers in {@link useLayout}.
*/
export declare type PortSides = 'end-in-flow' | 'any' | 'right' | 'left-in-flow' | 'top' | 'right-in-flow' | 'bottom' | 'left' | 'start-in-flow';
/**
* A provider for individual options per nodes or edges in a
* [RadialLayout]{@link https://docs.yworks.com/yfileshtml/#/api/RadialLayout}.
* It allows for defining a function that provide values for each element.
*
* For more information, see [RadialLayoutData]{@link https://docs.yworks.com/yfileshtml/#/api/RadialLayoutData}.
*/
export declare interface RadialLayoutDataProvider<TNodeData, TEdgeData> {
/** Provides which nodes should be placed on the innermost circle. */
centerNodes?: (node: TNodeData) => boolean;
/** Provides an order for outgoing edges at the given node in which the edges are arranged. */
childOrder?: ChildOrderDataProvider<TNodeData, TEdgeData>;
/** Provides the paddings for the group nodes, i.e., a rectangular area like padding in the interior of the node. */
groupNodePadding?: (node: TNodeData) => Insets;
/** Provides margins for nodes, i.e., a rectangular area around a specific node considered during the layout. */
nodeMargins?: (node: TNodeData) => NodeMargins;
/** Provides types which can influence the ordering of nodes during layout. */
nodeTypes?: (node: TNodeData) => any;
}
/**
* The configuration options for the radial layout algorithm that arranges graphs in a radial fashion.
* <p>
* For more information on the layout algorithm and its available settings,
* see [RadialLayout]{@link https://docs.yworks.com/yfileshtml/#/api/RadialLayout}.
* </p>
*/
export declare interface RadialLayoutOptions {
centerNodesPolicy?: 'directed' | 'centrality' | 'weighted-centrality';
createControlPoints?: boolean;
edgeRoutingStyle?: 'polyline' | 'arc' | 'radial-polyline' | 'curved';
layerSpacing?: number;
layeringStrategy?: 'bfs' | 'hierarchical' | 'dendrogram';
maximumChildSectorAngle?: number;
minimumBendAngle?: number;
minimumEdgeDistance?: number;
minimumLayerDistance?: number;
minimumNodeDistance?: number;
minimumSectorDistance?: number;
nodeLabelPlacement?: 'consider' | 'generic' | 'horizontal' | 'ignore' | 'ray-like' | 'ray-like-leaves';
nodeLabelSpacing?: number;
}
/**
* A provider for individual options per nodes or edges in a
* [RadialTreeLayoutLayout]{@link https://docs.yworks.com/yfileshtml/#/api/RadialTreeLayout}.
* It allows for defining a function that provide values for each element.
*
* For more information, see [RadialTreeLayoutData]{@link https://docs.yworks.com/yfileshtml/#/api/RadialTreeLayoutData}.
*/
export declare interface RadialTreeLayoutDataProvider<TNodeData, TEdgeData> {
/** Provides an order for the given edges in which the edges are arranged at a node. */
childOrder?: ChildOrderDataProvider<TNodeData, TEdgeData>;
/** Provides descriptors for the placement of edge labels. */
edgeLabelPreferredPlacements?: (label: LabelData) => EdgeLabelPreferredPlacement;
/** Provides the paddings for the group nodes, i.e., a rectangular area like padding in the interior of the node. */
groupNodePadding?: (node: TNodeData) => Insets;
/** Provides margins for nodes, i.e., a rectangular area around a specific node considered during the layout. */
nodeMargins?: (node: TNodeData) => NodeMargins;
/** Provides types which can influence the ordering of nodes during layout. */
nodeTypes?: (node: TNodeData) => any;
}
/**
* The configuration options for the radial tree layout algorithm
* that arranges the subtrees of the tree graph in a radial fashion.
* <p>
* For more information on the layout algorithm and its available settings,
* see [RadialTreeLayout]{@link https://docs.yworks.com/yfileshtml/#/api/RadialTreeLayout}.
* </p>
*/
export declare interface RadialTreeLayoutOptions {
allowOverlaps?: boolean;
chainStraighteningMode?: boolean;
childAlignmentPolicy?: 'plain' | 'same-center' | 'compact' | 'smart';
childOrderingPolicy?: 'compact' | 'symmetric' | 'from-sketch';
compactnessFactor?: number;
edgeLabelPlacement?: 'generic' | 'ignore' | 'integrated';
edgeLabelSpacing?: number;
minimumEdgeLength?: number;
minimumNodeDistance?: number;
nodeLabelPlacement?: 'consider' | 'generic' | 'horizontal' | 'ignore' | 'ray-like' | 'ray-like-leaves';
nodeLabelSpacing?: number;
preferredChildSectorAngle?: number;
preferredRootSectorAngle?: number;
rootSelectionPolicy?: 'directed-root' | 'center-root' | 'weighted-center-root';
}
/**
* Registers the [yFiles license]{@link http://docs.yworks.com/yfileshtml/#/dguide/licensing} which is needed to
* use the {@link useLayout} hook or the {@link useLayoutSupport} hook which are based on [yFiles for HTML]{@link https://www.yworks.com/products/yfiles-for-html}.
*
* ```tsx
* function App() {
* registerLicense(yFilesLicense)
*
* const { runLayout } = useLayout()
*
* return (
* <ReactFlow></ReactFlow>
* )
* }
* ```
*
* @param licenseKey - The license key to register
*/
export declare function registerLicense(licenseKey: Record<string, unknown>): void;
/**
* A provider for individual options per nodes or edges in a
* [TreeLayout]{@link https://docs.yworks.com/yfileshtml/#/api/TreeLayout}.
* It allows for defining a function that provide values for each element.
*
* For more information, see [TreeLayoutData]{@link https://docs.yworks.com/yfileshtml/#/api/TreeLayoutData}.
*/
export declare interface TreeLayoutDataProvider<TNodeData, TEdgeData> {
/** Provides which nodes should be placed separately from their siblings. */
assistantNodes?: (node: TNodeData) => boolean;
/** Provides an order for outgoing edges at the given node in which the edges are arranged. */
childOrder?: ChildOrderDataProvider<TNodeData, TEdgeData>;
/** Provides descriptors for the placement of edge labels. */
edgeLabelPreferredPlacements?: (label: LabelData) => EdgeLabelPreferredPlacement;
/** Provides the paddings for the group nodes, i.e., a rectangular area like padding in the interior of the node. */
groupNodePadding?: (node: TNodeData) => Insets;
/** Provides margins for nodes, i.e., a rectangular area around a specific node considered during the layout. */
nodeMargins?: (node: TNodeData) => NodeMargins;
/** Provides types which can influence the ordering of nodes during layout. */
nodeTypes?: (node: TNodeData) => any;
}
/**
* The configuration options for the tree layout algorithm that arranges graphs with a tree structure.
* <p>
* For more information on the layout algorithm and its available settings,
* see [TreeLayout]{@link https://docs.yworks.com/yfileshtml/#/api/TreeLayout}.
* </p>
*/
export declare interface TreeLayoutOptions {
allowMultiParent?: boolean;
defaultSubtreePlacer?: ISubtreePlacer;
edgeLabelPlacement?: 'generic' | 'ignore' | 'integrated';
layoutOrientation?: 'top-to-bottom' | 'left-to-right' | 'right-to-left' | 'bottom-to-top';
nodeLabelPlacement?: 'consider' | 'generic' | 'ignore';
}
/**
* A React hook that provides a callback to invoke the configured layout algorithm on the given data.
*
* ```tsx
* const edgeTypes = {
* default: PolylineEdge
* }
*
* const nodeTypes = {
* default: MultiHandleNode
* }
*
* const LayoutFlow = () => {
* const [nodes] = useNodesState(initialNodes)
* const [edges] = useEdgesState(initialEdges)
*
* const { runLayout, running } = useLayout()
*
* return (
* <ReactFlow
* nodes={nodes}
* edges={edges}
* nodeTypes={nodeTypes}
* edgeTypes={edgeTypes}
* >
* <Panel position="top-right">
* <button onClick={() => runLayout('OrthogonalLayout')} disabled={running}>Orthogonal Layout</button>
* </Panel>
* </ReactFlow>
* )
* }
*
* export default function Flow() {
* return (
* <ReactFlowProvider>
* <LayoutFlow />
* </ReactFlowProvider>
* )
* }
* ```
*
* @param context - The context information for running the layout algorithm.
* @returns a function to invoke the layout algorithm and a running state that indicates whether a layout is currently calculated.
*/
export declare function useLayout<TNodeData extends NodeProps = NodeProps, TEdgeData extends EdgeProps = EdgeProps>(context?: LayoutContext): {
runLayout: (configuration: LayoutConfiguration | LayoutName) => void;
running: boolean;
};
/**
* A React hook that provides helper function that prepare the data for the layout algorithm and
* retrieve the result.
*
* This hook is tailored for users interested in delving into [yFiles for HTML](https://www.yworks.com/products/yfiles-for-html),
* exploring various layout algorithms, and crafting advanced layout code for their applications.
*
* ```tsx
* const edgeTypes = {
* default: PolylineEdge
* }
*
* const nodeTypes = {
* default: MultiHandleNode
* }
*
* const LayoutFlow = () => {
* const [nodes, setNodes] = useNodesState(initialNodes)
* const [edges, setEdges] = useEdgesState(initialEdges)
* const { fitView, getZoom } = useReactFlow()
*
* const { buildGraph, transferLayout } = useLayoutSupport()
*
* const runLayout = useCallback(() => {
* // create a graph from data
* const graph = buildGraph(nodes, edges, getZoom())
*
* // configure a layout
* const hierarchicalLayout = new HierarchicalLayout()
* const hierarchicalLayoutData = new HierarchicalLayoutData({
* ports: {
* sourcePortCandidates: (edge: IEdge) => {
* const candidates = new EdgePortCandidates()
* if (edge.tag.id === 'e0') {
* candidates.addFreeCandidate(PortSides.LEFT)
* } else if (edge.tag.id === 'e1') {
* candidates.addFreeCandidate(PortSides.RIGHT)
* } else {
* candidates.addFreeCandidate(PortSides.START_IN_FLOW)
* }
* return candidates
* }
* }
* })
*
* // apply the layout
* graph.applyLayout(hierarchicalLayout, hierarchicalLayoutData)
*
* // transfer the new coordinates to the data
* const { arrangedEdges, arrangedNodes } = transferLayout(graph)
* setNodes(arrangedNodes)
* setEdges(arrangedEdges)
*
* // fit the graph into the view
* fitView()
* }, [nodes, edges, buildGraph, transferLayout, setNodes, setEdges, fitView, getZoom])
*
* return (
* <ReactFlow
* nodes={nodes}
* edges={edges}
* nodeTypes={nodeTypes}
* edgeTypes={edgeTypes}
* >
* <Panel position="top-right">
* <button onClick={runLayout}>Layout</button>
* </Panel>
* </ReactFlow>
* )
* }
*
* export default function Flow() {
* return (
* <ReactFlowProvider>
* <LayoutFlow />
* </ReactFlowProvider>
* )
* }
* ```
* @param {RefObject<HTMLElement>}[reactFlowRef] An optional reference to the React Flow element. This reference is
* particularly useful in scenarios where there are multiple React Flow elements on the same page or when the flow is
* encapsulated within a closed shadow DOM.
* @returns functions to transfer the data into a graph and get the layout information from the graph.
*/
export declare function useLayoutSupport(reactFlowRef?: RefObject<HTMLElement>): LayoutSupport;
/**
* A React hook that executes the given callback when all nodes are measured by React Flow and have a size.
*
* ```tsx
* const edgeTypes = {
* default: PolylineEdge
* }
*
* const nodeTypes = {
* default: MultiHandleNode
* }
*
* const LayoutFlow = () => {
* const [nodes] = useNodesState(initialNodes)
* const [edges] = useEdgesState(initialEdges)
*
* const { runLayout, running } = useLayout()
*
* // run initial layout after the nodes have been measured
* useNodesMeasuredEffect(() => {
* runLayout('OrthogonalLayout')
* })
*
* return (
* <ReactFlow
* nodes={nodes}
* edges={edges}
* nodeTypes={nodeTypes}
* edgeTypes={edgeTypes}
* ></ReactFlow>
* )
* }
*
* export default function Flow() {
* return (
* <ReactFlowProvider>
* <LayoutFlow />
* </ReactFlowProvider>
* )
* }
* ```
*
* @param callback - A callback that is invoked when all nodes are measured.
*/
export declare function useNodesMeasuredEffect(callback: () => void): void;
/**
* A higher order component (hoc) that adds multiple handles to a node component, thus enabling this
* component for yFiles layout.
*
* ```tsx
* const CustomNode = () => (
* <div>Custom Node</div>
* )
*
* const nodeTypes = {
* custom: withMultiHandles(CustomNode)
* }
*
* const LayoutFlow = () => {
* const [nodes] = useNod