d3-dag
    Preparing search index...

      d3-dag

      A library for interacting with and laying out directed acyclic graphs (DAGs)

      Using d3-dag is usually a two step process. First you must create a Graph from your data. There are several available methods:

      • graph - when you want to start with an empty graph and build dynamically.
      • graphHierarchy - when your data already has a graph-like structure.
      • graphStratify - when your graph has a tabular structure, referencing parents by id.
      • graphConnect - when your graph has a link-based structure specifying pairs of node ids.
      • graphJson - when you serialized your graph using JSON.stringify.

      Then you lay it out using one of the provided algorithms. Each algorithm emits a LayoutResult with width and height, while updating the x and y coordinate of each node, and the control points of all links. The provided layout methods are:

      • sugiyama - for a general layered representation.
      • zherebko - for a simple topological layout.
      • grid - for an alternate topological layout.

      This renders a simple graph with a -> b -> c.

      // import relevant functions in whatever way is necessary
      import { graphConect, sugiyama } from "d3-dag";
      const builder = graphConnect(); // optionally customize with fluent interface
      const graph = builder([["a", "b"], ["b", "c"]]);
      const layout = sugiyama(); // optionally customize with fluent interface
      const { width, height } = layout(dag);
      for (const node of dag.nodes()) {
      console.log(node.data, node.x, node.y);
      }

      This gives a brief overview of the design and related common themes of the api. This started trying to mimic d3-hierarchy as closely as possible, although due to different design constraints many of the apis have diverged.

      Functions are named with the prefix of their class to help indicate their usage. This mimic the flat structure and naming found in d3, e.g. coordSimplex and coordGreedy are two coordinate assignment operators.

      All operators create their Default variant, e.g. the function sugiyama is used to create general operators following the Sugiyama interface, but specifically always return the type DefaultSugiyama.

      Types that start with Mut are mutable, incontrast to their immutable non-prefixed siblings. Note that this only refers to their inherent structural properties, exposed data can still be altered. Graphs can only be traversed while MutGraphs also allow nodes to be added.

      Some interfaces start with Callable this often indicates another interface without that prefix that is the union of a const return type or an accessor, e.g. SimplexWeight and CallableSimplexWeight. In these instances the non-callable variant is the same as a function that returns a constant, but will sometimes result in faster layouts.

      A few operators will default to expected data with a certain interface (which is then checked at runtime). These interfaces all start with Has, e.g. HasId.

      This library mimics d3 in that you primarily interact with it through operators. Operators are just functions whos behavior might be able to be altered using a fluent api. Alterations are always immutable, returning a new object with altered behavior. In order to track parameterizations, each operator may be parametrized with an Ops type that specifies the type of various parameters. These Ops types also allow infering the type of allowable data. See Ops below.

      Due to their immutability, you can't directly tweak operators that are already set, instead needing to assign new ones.

      const layout = sugiyama().decross(decrossOpt());
      // this creates a new decross opt, but doesn't change the existing layouts behavior
      layout.decross().dist(true); // noop
      // correctly assigns a new operator
      const newLayout = layout.decross(layout.decross().dist(true));

      Since most operators are functions of user data, their most general typing involves data of type never, e.g. data that can never be accessed. However in a lot of instances you may want operators that take unknown data, e.g. data of any time. This is actually the most narrow class of an operator. Sometimes type inference on functions can fail, and you'll see typescript errors relating to never data. This can usually be fixed by specifying types everywhere.

      Ops types allow this library to track typing requirements dynamically as different callbacks are passed. The upside to this is that types are always sound, appropriately detecting the proper types of their inputs. The downside is that you need to explicitely type anonymous functions so that the types can be inferred appropriately.

      For example, look at d3.line. With d3.line you specify the types at the beginning d3.line<{ x: number; y: number }>(). However, this operator is current invalid, because by default d3.line actually expects tuples. However you can then easily specify d3.line<{ x: number; y: number }>().x(({ x }) => x).y(({ y }) => y), because it's already expecting the appropriate type. The d3-dag version of this wouldn't allow setting an initial type, and instead you'd have to call it like: d3.line().x(({ x }: { x: number }) => x).y(({ y }: { y: number }) => y). At this point the input type would correctly be { x: number } & { y: number }. Keeping track of the function types in the Ops parameter allows doing this inference correctly. However, if the types aren't specified, the data type can get miss-inferred create problems downstream when data is actually passed in.

      The three layouts: sugiyama, zherebko, and grid have several common features.

      • They all return the width and height of the final layout as a LayoutResult.
      • They all take a NodeSize which specifies how large nodes are, and can either be a constant tuple of width and height, or a callback that's applied to each node.
      • They all take a gap which specifies the minimum width and height gap between nodes.
      • They all take an array of Tweaks that allows modifying the final layout in reusable ways.
      • They almost all take a Rank that allows overriding the order of a subset of the nodes. For the sugiyama layout this is internal to the Sugiyama#layering.

      Interfaces

      Connect
      ConnectOps
      Coord
      CoordCenter
      CoordGreedy
      CoordQuad
      CoordQuadOps
      CoordSimplex
      CoordSimplexOps
      CoordTopological
      DecrossDfs
      DecrossOpt
      DecrossTwoLayer
      DecrossTwoLayerOps
      Graph
      GraphNode
      Grid
      GridOps
      HasChildren
      HasId
      HasOneString
      HasParentIds
      HasZeroString
      Hierarchy
      Json
      JsonOps
      LaneGreedy
      LaneOpt
      Layering
      LayeringLongestPath
      LayeringLongestPathOps
      LayeringSimplex
      LayeringSimplexOps
      LayeringTopological
      LayeringTopologicalOps
      LayoutResult
      MutGraph
      MutGraphNode
      Named
      Stratify
      StratifyOps
      SugiLinkDatum
      SugiNodeDatum
      Sugiyama
      SugiyamaOps
      TwolayerAgg
      TwolayerGreedy
      TwolayerOpt
      WrappedChildren
      WrappedChildrenData
      WrappedParentData
      WrappedParentIds
      Zherebko
      ZherebkoOps

      Type Aliases

      Aggregator
      CallableLinkWeight
      CallableNodeSize
      CallableNodeWeight
      CallableSimplexWeight
      Children
      ChildrenData
      Decross
      DefaultConnect
      DefaultCoordQuad
      DefaultCoordSimplex
      DefaultDecrossTwoLayer
      DefaultGrid
      DefaultHierarchy
      DefaultJson
      DefaultLayeringLongestPath
      DefaultLayeringSimplex
      DefaultLayeringTopological
      DefaultStratify
      DefaultSugiyama
      DefaultTwolayerGreedy
      DefaultZherebko
      Group
      Hydrator
      Id
      IdNodeDatum
      Lane
      LinkWeight
      NodeLength
      NodeSize
      NodeWeight
      OptChecking
      ParentData
      ParentIds
      Rank
      Separation
      Shape
      SimplexWeight
      SugiDatum
      SugiNode
      SugiNodeLength
      SugiSeparation
      Tweak
      Twolayer
      U

      Functions

      aggMean
      aggMedian
      aggWeightedMedian
      cachedNodeSize
      coordCenter
      coordGreedy
      coordQuad
      coordSimplex
      coordTopological
      decrossDfs
      decrossOpt
      decrossTwoLayer
      graph
      graphConnect
      graphHierarchy
      graphJson
      graphStratify
      grid
      laneGreedy
      laneOpt
      layeringLongestPath
      layeringSimplex
      layeringTopological
      layerSeparation
      shapeEllipse
      shapeRect
      shapeTopBottom
      sizedSeparation
      splitNodeSize
      sugifyCompact
      sugifyLayer
      sugiNodeLength
      sugiyama
      tweakFlip
      tweakGrid
      tweakShape
      tweakSize
      twolayerAgg
      twolayerGreedy
      twolayerOpt
      unsugify
      zherebko