elk 0.2.0 copy "elk: ^0.2.0" to clipboard
elk: ^0.2.0 copied to clipboard

Pure Dart layered graph layout (Sugiyama-style), inspired by the Eclipse Layout Kernel. Compound/hierarchical graphs, ports and orthogonal edge routing, with an elkjs-style graph API. No Flutter, no I [...]

elk #

elk is a pure Dart implementation of layered graph layout. It provides an elkjs-style graph model and supports compound graphs, ports, configurable spacing, model-order constraints, and orthogonal edge routing.

The implementation follows the same algorithm family as Eclipse Layout Kernel and elkjs, but it is not a translation of either project and does not promise identical coordinates.

Use #

import 'package:elk/elk.dart';

void main() {
  final result = const ElkLayered().layout(
    ElkGraph(
      layoutOptions: const ElkLayoutOptions(direction: ElkDirection.down),
      children: [
        ElkNode(id: 'a', width: 80, height: 40),
        ElkNode(id: 'b', width: 80, height: 40),
        ElkNode(id: 'c', width: 80, height: 40),
      ],
      edges: [
        ElkEdge(id: 'e1', sources: ['a'], targets: ['b']),
        ElkEdge(id: 'e2', sources: ['a'], targets: ['c']),
      ],
    ),
  );

  for (final node in result.children) {
    print('${node.id}: ${node.x}, ${node.y}');
  }
}

Node coordinates are relative to their parent. Use result.nodesById for a flat map with absolute coordinates.

Options #

ElkLayoutOptions controls direction, spacing, node placement, fixed alignment, hierarchy handling, model-order handling, edge merging, and cycle breaking. For example:

const options = ElkLayoutOptions(
  direction: ElkDirection.right,
  spacingBaseValue: 24,
  forceNodeModelOrder: true,
);

Edges can refer to a node ID or to an ElkPort ID. A node with children is laid out as a compound node. Existing elkjs graph JSON can be loaded with ElkGraph.fromJson.

Hierarchy modes #

Set hierarchyHandling on root or compound ElkLayoutOptions. JSON accepts org.eclipse.elk.hierarchyHandling, elk.hierarchyHandling, and hierarchyHandling.

Mode Behavior
includeChildren / INCLUDE_CHILDREN Routes edges across included compound boundaries.
separateChildren / SEPARATE_CHILDREN Lays out groups independently. Edges internal to each group, including links from its own boundary ports to its children, remain routed; edges crossing a separated boundary remain in the result with empty sections.
inherit / INHERIT Uses the enclosing mode; at the root, resolves to SEPARATE_CHILDREN.

Omitting the root mode preserves Dart's existing INCLUDE_CHILDREN default. Omitting a compound override inherits its enclosing mode. An explicit included child does not reconnect a boundary separated by an ancestor. A direction-only compound override changes direction without changing the inherited mode; a hierarchy-only override preserves the inherited direction.

Unlike elkjs 0.9.3, Dart retains cross-boundary edge IDs with empty sections when an included parent contains a separated child, rather than throwing. Unrouted edges have no positioned labels. Their original label metadata remains on the input graph. Consumers should draw only the sections that are present.

Dart also retains its existing mixed-direction support under INCLUDE_CHILDREN. elkjs 0.9.3 ignores nested directions in that mode. The broader coordinated hierarchy optimization remains tracked in issue #78; these modes do not promise identical coordinates or crossing order.

Validation #

The comparison tool under tool/validation runs the same graph set through this package and elkjs and writes side-by-side SVG output:

$ cd tool/validation
$ npm install
$ node run_elkjs.mjs
$ cd ../..
$ dart run tool/validation/compare.dart

The comparison checks layer assignment, node overlap, ordering, and graph bounds. Differences in within-layer ordering and exact coordinates are expected.

The hierarchy tests also read retained elkjs 0.9.3 inputs and outputs from test/fixtures/hierarchy_handling_elkjs.json. After an intentional reference update, regenerate them from the package root with node tool/validation/generate_hierarchy_reference.mjs. Ordinary tests never regenerate reference data.

License #

MIT. The package contains a vendored derivative of dart_dagre (Apache-2.0). See NOTICE and lib/src/dagre/LICENSE.

0
likes
130
points
1.24k
downloads

Documentation

API reference

Publisher

verified publisherroszkowski.dev

Weekly Downloads

Pure Dart layered graph layout (Sugiyama-style), inspired by the Eclipse Layout Kernel. Compound/hierarchical graphs, ports and orthogonal edge routing, with an elkjs-style graph API. No Flutter, no I/O — runs anywhere.

Repository (GitHub)
View/report issues
Contributing

Topics

#layout #graph #elk #diagram #visualization

License

MIT (license)

Dependencies

meta

More

Packages that depend on elk