d3-dag
Version:
Layout algorithms for visualizing directed acylic graphs.
96 lines (95 loc) • 3.8 kB
TypeScript
/**
* 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;