UNPKG

d3-dag

Version:

Layout algorithms for visualizing directed acylic graphs.

52 lines (51 loc) 2.13 kB
/** * The definition of the {@link Twolayer} interface, which is used to * customize {@link DecrossTwoLayer}. * * @packageDocumentation */ import { SugiNode } from "../sugify"; /** * an operator for optimizing decrossings one layer at a time. * * This is used to customize {@link DecrossTwoLayer}. * * When called with `topDown = true` `topLayer` should be untouched, and * `bottomLayer` should be rearranged to minimize crossings. When * `topDown = false` then `topLayer` should be rearranged, and `bottomLayer` * should remain fixed. There are no requirements for how these needs to order * nodes, but doing so in such a way to minimize edge crossings is usually * desired. * * @example * * It's unlikely that you'll need to implement a custom two-layer operator as * this is already a heuristic solution to decrossing. However, in the event * that you do, we illustrate how to implement one where the order is stored in * the original nodes. Here dummy nodes (nodes that exist on long edges between * "real" nodes) are ordered according to the average value of their source and * target nodes. * * ```ts * function myTwoLayer(topLayer: SugiNode<{ ord: number }, unknown>[], bottomLayer: SugiNode<{ ord: number }, unknown>[], topDown: boolean): void { * let mutate = topDown ? bottomLayer : topLayer; * const vals = new Map<SugiNode, number>(); * for (const node of mutate) { * const { data } = node; * const val = data.role === "node" ? data.node.data.ord ? (data.link.source.data.ord + data.link.target.data.ord) / 2; * vals.set(node, val); * } * layer.sort((a, b) => vals.get(a)! - vals.get(b)!); * } * ``` */ export interface Twolayer<in NodeDatum = never, in LinkDatum = never> { /** * rearrange one layer conditioned on another * * @param topLayer - the top layer * @param bottomLayer - the bottom layer * @param topDown - if true rearrange `bottomLayer`, else rearrange `topLayer` */ (topLayer: SugiNode<NodeDatum, LinkDatum>[], bottomLayer: SugiNode<NodeDatum, LinkDatum>[], topDown: boolean): void; }