UNPKG

d3-dag

Version:

Layout algorithms for visualizing directed acylic graphs.

96 lines (95 loc) 3.8 kB
/** * A {@link LayeringSimplex} that assigns layers to minimize the number of * dummy nodes. * * @packageDocumentation */ import { Group, Layering } from "."; import { Rank } from "../../graph"; import { U } from "../../utils"; /** simplex operator operators */ export interface LayeringSimplexOps<in N = never, in L = never> { /** rank operator */ rank: Rank<N, L>; /** group operator */ group: Group<N, L>; } /** the node datum of a set of operators */ export type OpsNodeDatum<Ops extends LayeringSimplexOps> = Ops extends LayeringSimplexOps<infer N, never> ? N : never; /** the link datum of a set of operators */ export type OpsLinkDatum<Ops extends LayeringSimplexOps> = Ops extends LayeringSimplexOps<never, infer L> ? L : never; /** * A layering operator that assigns layers to minimize the number of dummy * nodes (long edges) added to the layout. * * Computing this layering requires solving an integer linear program, which * may take a long time, although in practice is often quite fast. This is * often known as the network simplex layering from * {@link https://www.graphviz.org/Documentation/TSE93.pdf | Gansner et al. * [1993]}. * * Because this is solving a linear program, it is relatively easy to add new * constraints. The current implementation allows specifying {@link rank} * constraints that indicate which nodes should be above other nodes, or * {@link group} constraints that say which nodes should be on the same layer. * Note that adding these constraints can cause the optimization to become * ill-defined. * * Create with {@link layeringSimplex}. */ export interface LayeringSimplex<Ops extends LayeringSimplexOps = LayeringSimplexOps> extends Layering<OpsNodeDatum<Ops>, OpsLinkDatum<Ops>> { /** * set the {@link Rank} * * Any node with a rank assigned will have a second ordering enforcing * ordering of the ranks. Note, this can cause the simplex optimization to be * ill-defined, and may result in an error during layout. */ rank<NewRank extends Rank>(newRank: NewRank): LayeringSimplex<U<Ops, "rank", NewRank>>; /** * get the current {@link Rank} */ rank(): Ops["rank"]; /** * set the {@link Group} * * Any node with a group assigned will have a second ordering enforcing all * nodes with the same group have the same layer. Note, this can cause the * simplex optimization to be ill-defined, and may result in an error during * layout. */ group<NewGroup extends Group>(newGroup: NewGroup): LayeringSimplex<U<Ops, "group", NewGroup>>; /** * get the current {@link Group} */ group(): Ops["group"]; /** @internal flag indicating that this is built in to d3dag and shouldn't error in specific instances */ readonly d3dagBuiltin: true; } /** default simplex operator */ export type DefaultLayeringSimplex = LayeringSimplex<{ /** unconstrained rank */ rank: Rank<unknown, unknown>; /** unconstrained group */ group: Group<unknown, unknown>; }>; /** * create a default {@link LayeringSimplex} * * This layering operator assigns layers to minimize the overall lengths of * edges. In most cases this strikes a good balance between compactness and * time to compute. * * The current implementation allows specifying {@link LayeringSimplex#rank} * constraints that indicate which nodes should be above other nodes, and * {@link LayeringSimplex#group} constraints that say which nodes should be on * the same layer. Note that adding these constraints can cause the * optimization to become ill-defined. * * @example * * ```ts * const layout = sugiyama().layering(layeringSimplex()); * ``` */ export declare function layeringSimplex(...args: never[]): DefaultLayeringSimplex;