d3-dag
Version:
Layout algorithms for visualizing directed acylic graphs.
173 lines (172 loc) • 6.12 kB
TypeScript
/**
* The {@link CoordQuad} positions nodes to minimize a quadratic
* optimization.
*
* @packageDocumentation
*/
import { Coord } from ".";
import { GraphLink, GraphNode } from "../../graph";
import { U } from "../../utils";
/**
* a strictly callable {@link NodeWeight}
*/
export interface CallableNodeWeight<NodeDatum = never, LinkDatum = never> {
/**
* get the weight of a node
*
* @param node - the node to get the weight of
* @returns weight - the corresponding weight
*/
(node: GraphNode<NodeDatum, LinkDatum>): number;
}
/**
* an accessor to get the optimization of the weight for a node
*
* Currently this is only used to set the {@link CoordQuad#nodeCurve}.
*/
export type NodeWeight<NodeDatum = never, LinkDatum = never> = number | CallableNodeWeight<NodeDatum, LinkDatum>;
/**
* a strictly callable {@link LinkWeight}
*/
export interface CallableLinkWeight<NodeDatum = never, LinkDatum = never> {
/**
* get the weight of a link
*
* @param link - the link to get the weight of
* @returns weight - the corresponding weight
*/
(link: GraphLink<NodeDatum, LinkDatum>): number;
}
/**
* an accessor to get the optimization of the weight for a link
*
* Currently this is used to set the following accessors:
* {@link CoordQuad#linkCurve}, {@link CoordQuad#vertWeak},
* {@link CoordQuad#vertStrong}.
*/
export type LinkWeight<NodeDatum = never, LinkDatum = never> = number | CallableLinkWeight<NodeDatum, LinkDatum>;
/** the operators for the quad operator */
export interface CoordQuadOps<N = never, L = never> {
/** the vert weak accessor */
vertWeak: LinkWeight<N, L>;
/** the vert strong accessor */
vertStrong: LinkWeight<N, L>;
/** the link weight accessor */
linkCurve: LinkWeight<N, L>;
/** the node weight accessor */
nodeCurve: NodeWeight<N, L>;
}
/** node datum for operators */
export type OpNodeDatum<O extends CoordQuadOps> = O extends CoordQuadOps<infer N, never> ? N : never;
/** link datum for operators */
export type OpLinkDatum<O extends CoordQuadOps> = O extends CoordQuadOps<never, infer L> ? L : never;
/**
* a {@link Coord} that places nodes to minimize a quadratic function
*
* This operators generally takes the longest of all built-in operators but
* produces a pleasing layout.
*
* Create with {@link coordQuad}.
*/
export interface CoordQuad<Ops extends CoordQuadOps> extends Coord<OpNodeDatum<Ops>, OpLinkDatum<Ops>> {
/**
* set the weak vertical accessor.
*
* The weak vertical accessor adds a penalty to make edges vertical. It's
* weak in that it applies to all edges equally regardless of length, and
* while it penalized non vertical edges, it allows curving in the middle of
* long edges.
*
* (default: `1`)
*/
vertWeak<NewVertWeak extends LinkWeight>(val: NewVertWeak): CoordQuad<U<Ops, "vertWeak", NewVertWeak>>;
/**
* get the current vertWeak accessor
*/
vertWeak(): Ops["vertWeak"];
/**
* set the strong vertical accessor.
*
* The strong vertical accessor adds a penalty to make edges vertical. It
* penealizes any section of an edge that isn't vertical, making longer edges
* contribute more to the overall impact on the objective.
*
* (default: `0`)
*/
vertStrong<NewVertStrong extends LinkWeight>(val: NewVertStrong): CoordQuad<U<Ops, "vertStrong", NewVertStrong>>;
/**
* get the current vertStrong accessor
*/
vertStrong(): Ops["vertStrong"];
/**
* set the link curve weight accessor
*
* The link curve weight penalizes links to reduce their curving, in
* dependent of their verticality. If using strongVert for an edge, it
* probably won't need a strong link curve weight.
*
* (default: `1`)
*/
linkCurve<NewLinkCurve extends LinkWeight>(val: NewLinkCurve): CoordQuad<U<Ops, "linkCurve", NewLinkCurve>>;
/**
* get the current link curve weight accessor
*/
linkCurve(): Ops["linkCurve"];
/**
* set the node curve weight accessor
*
* The node curve weight penalizes curves through nodes. If a node only has
* one incoming and one outgoing edge, it will try to make them match in
* angle. Note that it does it for all possible "through edges" so multiple
* incoming and multiple outgoing will get counted several times. It's not
* clear why this would ever be desirable, but it's possible to specify.
*
* (default: `0`)
*/
nodeCurve<NewNodeCurve extends NodeWeight>(val: NewNodeCurve): CoordQuad<U<Ops, "nodeCurve", NewNodeCurve>>;
/**
* get the current node curve accessor
*/
nodeCurve(): Ops["nodeCurve"];
/**
* set the weight for how close nodes should be to zero.
*
* This ensures the optimization is sound, and is necessary if there are
* certain types of disconnected components or zero weights for different
* curvature constraints. If the graph is connected and the weights are
* positive this can be set to zero, otherwise it should be positive, but
* small.
*
* (default: `1e-6`)
*/
compress(val: number): CoordQuad<Ops>;
/** get the current compress weight. */
compress(): number;
/** @internal flag indicating that this is built in to d3dag and shouldn't error in specific instances */
readonly d3dagBuiltin: true;
}
/** default quad operator */
export type DefaultCoordQuad = CoordQuad<{
/** default vert weak */
vertWeak: 1;
/** default vert strong */
vertStrong: 0;
/** default link curve */
linkCurve: 1;
/** default node curve */
nodeCurve: 0;
}>;
/**
* create a default {@link CoordQuad}
*
* This coordinate assignment operator tries to minimize the curve of links.
* Unlike {@link coordSimplex} it produces layouts with less verticality, which
* often look a little worse.
*
* @example
*
* ```ts
* const layout = sugiyama().coord(coordQuad().vertStrong(1));
* ```
*/
export declare function coordQuad(...args: never[]): DefaultCoordQuad;