d3-dag
Version:
Layout algorithms for visualizing directed acylic graphs.
132 lines (131 loc) • 6.03 kB
TypeScript
import type { Graph } from "./graph";
import { type LayoutResult, type NodeSize, type Rankdir } from "./layout";
/**
* a function to tweak a graph layout
*
* {@link Tweak}s allow abstracting over general modifications to graph
* layouts. There are several built in:
* - {@link tweakSize} - This tweak scales the graph so that its final size is
* a specified constant size.
* - {@link tweakFlip} - This tweak allows flipping the graph in various ways,
* so you could make a layout bottom up, or horizontal.
* - {@link tweakGrid} - Tweaks {@link grid} layout link points to make
* pleasing links easier to render.
* - {@link tweakShape} - Given the current {@link NodeSize}, sets the final
* control points of each link so that they end on the edge of the given
* shape. For simple layouts, this should prevent needing to render links
* behind nodes. In complex cases, it allows consistently rendering arrows or
* other link terminal icons at the edge of a shape.
* - {@link tweakSugiyama} - Adds control points inside the bounding box of
* source/target nodes, preventing edges from crossing over nodes.
* - {@link tweakGridHandles} - Moves grid edge bend points to the midpoint of
* the gap between rows, producing smoother edges for handle-based frameworks.
* - {@link tweakDirection} - Converts the default top-to-bottom layout to a
* specified direction (BT, LR, RL).
*
* You can also implement your own tweak. There's not a reason to give an
* example, as tweaks are pretty unbounded. As input you get a laidout graph,
* and the dimensions of that layout. Modify the graph arbitrarily, and return
* the new dimensions after tweaking the layout.
*/
export type Tweak<in N = never, in L = never> = (graph: Graph<N, L>, res: Readonly<LayoutResult>) => LayoutResult;
/**
* tweak the laidout dag by resizing it
*
* The x and y coordinates of everything are rescaled to fit within the specified size.
*/
export declare function tweakSize(size: Readonly<LayoutResult>): Tweak<unknown, unknown>;
/**
* This tweak adds extra control points to the grid layout
*
* The grid layout often looks best with rounded corners. This tweak adds extra
* control points to edges so that `d3.curveBasis` curves produce nice rounded
* edges.
*
* rounding should be set somewhere between 0 and nodeSize.
*/
export declare function tweakGrid(rounding: readonly [number, number]): Tweak<unknown, unknown>;
/**
* Tweak to flip the layout in several ways
*
* - `diagonal` : flips x and y coordinates turning x into y
* - `horizontal` : inverts x
* - `vertical` : inverts y
*/
export declare function tweakFlip(style?: "diagonal" | "horizontal" | "vertical"): Tweak<unknown, unknown>;
/**
* a shape callable used to truncate an edge path at a node
*
* This represents how to tweak the edge of a link conditioned on the shape of
* the node. This is useful for adding endings to an link (like arrows) that
* will align with a node well.
*/
export type Shape = (center: readonly [number, number], nodeSize: readonly [number, number], start: readonly [number, number], end: readonly [number, number]) => [number, number];
/**
* a bounding box shape for the full rectangle
*
* Useful with [`tweakShape`].
*/
export declare function shapeRect(center: readonly [number, number], nodeSize: readonly [number, number], start: readonly [number, number], end: readonly [number, number]): [number, number];
/**
* a bounding box shape for an ellipse
*
* Useful with [`tweakShape`].
*/
export declare function shapeEllipse(center: readonly [number, number], nodeSize: readonly [number, number], start: readonly [number, number], end: readonly [number, number]): [number, number];
/**
* a shape that aligns edges with the centered top or bottom of a node
*
* Useful with [`tweakShape`].
*/
export declare function shapeTopBottom(center: readonly [number, number], nodeSize: readonly [number, number], start: readonly [number, number], end: readonly [number, number]): [number, number];
/**
* tweak the layout by truncating edges early
*
* This tweak truncates edges at the extent of a node shape sized by a bounding
* box. After applying this tweak, edge endings like arrows can be easily
* rendered in the appropriate place.
*
* There are three built in {@link Shape}s:
* - {@link shapeRect} - a simple rectangle
* - {@link shapeEllipse} - an ellipse (circle for square node sizes)
* - {@link shapeTopBottom} - to center edges into the top or bottom of a node
*/
export declare function tweakShape<N, L>(nodeSize: NodeSize<N, L>, shape?: Shape): Tweak<N, L>;
/**
* tweak the sugiyama layout by add a control point inside the bounding box
*
* This tweak adds a control point to the edge (top / bottom) of the bounding
* box. This prevents edges from crossing over nodes when nodes are very far
* apart horizontally.
*
* @remarks
*
* If using in conjunction with {@link tweakShape}, this should occur first,
* although it shouldn't be strictly necessary.
*/
export declare function tweakSugiyama<N, L>(nodeSize: NodeSize<N, L>): Tweak<N, L>;
/**
* tweak grid edge bend points to the midpoint of the gap between rows
*
* Grid layouts place bend points at source or target y-levels, which can
* cause edges to kink when rendered with handle-based frameworks like React
* Flow. This tweak moves interior bend points to the midpoint of the gap
* between rows (bottom of node + half of y gap), producing smoother edges.
*
* @remarks
*
* This should be applied before flip tweaks.
*/
export declare function tweakGridHandles<N, L>(nodeSize: NodeSize<N, L>, gap: readonly [number, number]): Tweak<N, L>;
/**
* tweak the layout to apply a direction
*
* Layouts produce top-to-bottom (TB) output by default. This tweak converts
* the layout to the given direction by composing the appropriate flips.
*
* @remarks
*
* This should be applied after all other tweaks.
*/
export declare function tweakDirection(direction: Rankdir): Tweak<unknown, unknown>;