@deck.gl-community/graph-layers 9.2.0-beta.2 → 9.2.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_deprecated/old-constants.d.ts +1 -0
- package/dist/_deprecated/old-constants.js +1 -0
- package/dist/core/cache.d.ts +1 -0
- package/dist/core/cache.js +1 -0
- package/dist/core/constants.d.ts +2 -1
- package/dist/core/constants.js +1 -0
- package/dist/core/graph-engine.d.ts +64 -21
- package/dist/core/graph-engine.d.ts.map +1 -1
- package/dist/core/graph-engine.js +158 -77
- package/dist/core/graph-engine.js.map +1 -1
- package/dist/core/graph-layout.d.ts +23 -18
- package/dist/core/graph-layout.d.ts.map +1 -1
- package/dist/core/graph-layout.js +35 -19
- package/dist/core/graph-layout.js.map +1 -1
- package/dist/core/interaction-manager.d.ts +5 -4
- package/dist/core/interaction-manager.d.ts.map +1 -1
- package/dist/core/interaction-manager.js +10 -7
- package/dist/core/interaction-manager.js.map +1 -1
- package/dist/graph/arrow-graph.d.ts +70 -0
- package/dist/graph/arrow-graph.d.ts.map +1 -0
- package/dist/graph/arrow-graph.js +514 -0
- package/dist/graph/arrow-graph.js.map +1 -0
- package/dist/graph/classic-graph.d.ts +170 -0
- package/dist/graph/classic-graph.d.ts.map +1 -0
- package/dist/graph/classic-graph.js +391 -0
- package/dist/graph/classic-graph.js.map +1 -0
- package/dist/graph/edge.d.ts +8 -7
- package/dist/graph/edge.d.ts.map +1 -1
- package/dist/graph/edge.js +1 -0
- package/dist/graph/edge.js.map +1 -1
- package/dist/graph/functions/arrow-utils.d.ts +7 -0
- package/dist/graph/functions/arrow-utils.d.ts.map +1 -0
- package/dist/graph/functions/arrow-utils.js +68 -0
- package/dist/graph/functions/arrow-utils.js.map +1 -0
- package/dist/graph/functions/create-graph-from-data.d.ts +4 -0
- package/dist/graph/functions/create-graph-from-data.d.ts.map +1 -0
- package/dist/graph/functions/create-graph-from-data.js +13 -0
- package/dist/graph/functions/create-graph-from-data.js.map +1 -0
- package/dist/graph/graph-normalization.d.ts +11 -0
- package/dist/graph/graph-normalization.d.ts.map +1 -0
- package/dist/graph/graph-normalization.js +66 -0
- package/dist/graph/graph-normalization.js.map +1 -0
- package/dist/graph/graph.d.ts +63 -155
- package/dist/graph/graph.d.ts.map +1 -1
- package/dist/graph/graph.js +12 -300
- package/dist/graph/graph.js.map +1 -1
- package/dist/graph/node.d.ts +8 -7
- package/dist/graph/node.d.ts.map +1 -1
- package/dist/graph/node.js +3 -2
- package/dist/graph/node.js.map +1 -1
- package/dist/graph-data/arrow-graph-data-builder.d.ts +22 -0
- package/dist/graph-data/arrow-graph-data-builder.d.ts.map +1 -0
- package/dist/graph-data/arrow-graph-data-builder.js +106 -0
- package/dist/graph-data/arrow-graph-data-builder.js.map +1 -0
- package/dist/graph-data/graph-data-builder.d.ts +7 -0
- package/dist/graph-data/graph-data-builder.d.ts.map +1 -0
- package/dist/graph-data/graph-data-builder.js +2 -0
- package/dist/graph-data/graph-data-builder.js.map +1 -0
- package/dist/graph-data/graph-data.d.ts +41 -0
- package/dist/graph-data/graph-data.d.ts.map +1 -0
- package/dist/graph-data/graph-data.js +12 -0
- package/dist/graph-data/graph-data.js.map +1 -0
- package/dist/graph-data/plain-graph-data-builder.d.ts +21 -0
- package/dist/graph-data/plain-graph-data-builder.d.ts.map +1 -0
- package/dist/graph-data/plain-graph-data-builder.js +106 -0
- package/dist/graph-data/plain-graph-data-builder.js.map +1 -0
- package/dist/graph-style-schema.cdn.js +1 -1
- package/dist/graph-style-schema.json +1 -1
- package/dist/index.cjs +6905 -4576
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +36 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +43 -29
- package/dist/index.js.map +1 -1
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-fragment.glsl.d.ts +1 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-fragment.glsl.js +1 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex-tf.glsl.d.ts +1 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex-tf.glsl.js +1 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex.glsl.d.ts +1 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex.glsl.js +1 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer.d.ts +1 -0
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer.d.ts.map +1 -1
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer.js +2 -2
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer.js.map +1 -1
- package/dist/layers/common-layers/grid-layer/grid-layer.d.ts +84 -0
- package/dist/layers/common-layers/grid-layer/grid-layer.d.ts.map +1 -0
- package/dist/layers/common-layers/grid-layer/grid-layer.js +134 -0
- package/dist/layers/common-layers/grid-layer/grid-layer.js.map +1 -0
- package/dist/layers/common-layers/marker-layer/atlas-data-url.d.ts +1 -0
- package/dist/layers/common-layers/marker-layer/atlas-data-url.js +1 -0
- package/dist/layers/common-layers/marker-layer/marker-layer.d.ts +1 -0
- package/dist/layers/common-layers/marker-layer/marker-layer.js +3 -2
- package/dist/layers/common-layers/marker-layer/marker-list.d.ts +1 -0
- package/dist/layers/common-layers/marker-layer/marker-list.js +1 -0
- package/dist/layers/common-layers/marker-layer/marker-mapping.d.ts +1 -0
- package/dist/layers/common-layers/marker-layer/marker-mapping.js +1 -0
- package/dist/layers/common-layers/spline-layer/spline-layer.d.ts +1 -0
- package/dist/layers/common-layers/spline-layer/spline-layer.js +1 -0
- package/dist/layers/common-layers/zoomable-text-layer/zoomable-text-layer.d.ts +1 -0
- package/dist/layers/common-layers/zoomable-text-layer/zoomable-text-layer.js +1 -0
- package/dist/layers/edge-attachment-helper.d.ts +4 -3
- package/dist/layers/edge-attachment-helper.d.ts.map +1 -1
- package/dist/layers/edge-attachment-helper.js +4 -4
- package/dist/layers/edge-attachment-helper.js.map +1 -1
- package/dist/layers/edge-layer.d.ts +1 -0
- package/dist/layers/edge-layer.js +4 -3
- package/dist/layers/edge-layers/arrow-2d-geometry.d.ts +1 -0
- package/dist/layers/edge-layers/arrow-2d-geometry.js +1 -0
- package/dist/layers/edge-layers/curved-edge-layer.d.ts +2 -1
- package/dist/layers/edge-layers/curved-edge-layer.js +2 -1
- package/dist/layers/edge-layers/edge-arrow-layer.d.ts +1 -0
- package/dist/layers/edge-layers/edge-arrow-layer.js +2 -1
- package/dist/layers/edge-layers/edge-label-layer.d.ts +2 -1
- package/dist/layers/edge-layers/edge-label-layer.js +2 -1
- package/dist/layers/edge-layers/flow-layer.d.ts +2 -1
- package/dist/layers/edge-layers/flow-layer.js +2 -1
- package/dist/layers/edge-layers/path-edge-layer.d.ts +1 -0
- package/dist/layers/edge-layers/path-edge-layer.js +1 -0
- package/dist/layers/edge-layers/straight-line-edge-layer.d.ts +1 -0
- package/dist/layers/edge-layers/straight-line-edge-layer.js +1 -0
- package/dist/layers/graph-layer.d.ts +75 -17
- package/dist/layers/graph-layer.d.ts.map +1 -1
- package/dist/layers/graph-layer.js +450 -64
- package/dist/layers/graph-layer.js.map +1 -1
- package/dist/layers/node-layers/circle-layer.d.ts +1 -0
- package/dist/layers/node-layers/circle-layer.js +1 -0
- package/dist/layers/node-layers/image-layer.d.ts +1 -0
- package/dist/layers/node-layers/image-layer.js +1 -0
- package/dist/layers/node-layers/label-layer.d.ts +2 -1
- package/dist/layers/node-layers/label-layer.js +2 -1
- package/dist/layers/node-layers/path-rounded-rectangle-layer.d.ts +1 -0
- package/dist/layers/node-layers/path-rounded-rectangle-layer.js +2 -1
- package/dist/layers/node-layers/rectangle-layer.d.ts +1 -0
- package/dist/layers/node-layers/rectangle-layer.js +1 -0
- package/dist/layers/node-layers/rounded-rectangle-layer-fragment.d.ts +1 -0
- package/dist/layers/node-layers/rounded-rectangle-layer-fragment.js +1 -0
- package/dist/layers/node-layers/rounded-rectangle-layer.d.ts +2 -1
- package/dist/layers/node-layers/rounded-rectangle-layer.js +3 -2
- package/dist/layers/node-layers/zoomable-marker-layer.d.ts +2 -1
- package/dist/layers/node-layers/zoomable-marker-layer.js +2 -1
- package/dist/layouts/d3-dag/collapsable-d3-dag-layout.d.ts +25 -0
- package/dist/layouts/d3-dag/collapsable-d3-dag-layout.d.ts.map +1 -0
- package/dist/layouts/d3-dag/collapsable-d3-dag-layout.js +252 -0
- package/dist/layouts/d3-dag/collapsable-d3-dag-layout.js.map +1 -0
- package/dist/layouts/d3-dag/d3-dag-layout.d.ts +48 -62
- package/dist/layouts/d3-dag/d3-dag-layout.d.ts.map +1 -1
- package/dist/layouts/d3-dag/d3-dag-layout.js +89 -273
- package/dist/layouts/d3-dag/d3-dag-layout.js.map +1 -1
- package/dist/layouts/d3-force/d3-force-layout.d.ts +22 -9
- package/dist/layouts/d3-force/d3-force-layout.d.ts.map +1 -1
- package/dist/layouts/d3-force/d3-force-layout.js +42 -22
- package/dist/layouts/d3-force/d3-force-layout.js.map +1 -1
- package/dist/layouts/d3-force/worker.d.ts +1 -0
- package/dist/layouts/d3-force/worker.js +1 -0
- package/dist/layouts/experimental/force-multi-graph-layout.d.ts +21 -16
- package/dist/layouts/experimental/force-multi-graph-layout.d.ts.map +1 -1
- package/dist/layouts/experimental/force-multi-graph-layout.js +49 -39
- package/dist/layouts/experimental/force-multi-graph-layout.js.map +1 -1
- package/dist/layouts/experimental/hive-plot-layout.d.ts +20 -16
- package/dist/layouts/experimental/hive-plot-layout.d.ts.map +1 -1
- package/dist/layouts/experimental/hive-plot-layout.js +35 -35
- package/dist/layouts/experimental/hive-plot-layout.js.map +1 -1
- package/dist/layouts/experimental/radial-layout.d.ts +14 -8
- package/dist/layouts/experimental/radial-layout.d.ts.map +1 -1
- package/dist/layouts/experimental/radial-layout.js +33 -15
- package/dist/layouts/experimental/radial-layout.js.map +1 -1
- package/dist/layouts/gpu-force/gpu-force-layout.d.ts +13 -9
- package/dist/layouts/gpu-force/gpu-force-layout.d.ts.map +1 -1
- package/dist/layouts/gpu-force/gpu-force-layout.js +61 -57
- package/dist/layouts/gpu-force/gpu-force-layout.js.map +1 -1
- package/dist/layouts/gpu-force/worker.d.ts +1 -0
- package/dist/layouts/gpu-force/worker.js +1 -0
- package/dist/layouts/simple-layout.d.ts +10 -26
- package/dist/layouts/simple-layout.d.ts.map +1 -1
- package/dist/layouts/simple-layout.js +15 -18
- package/dist/layouts/simple-layout.js.map +1 -1
- package/dist/loaders/dot-graph-loader.d.ts +26 -0
- package/dist/loaders/dot-graph-loader.d.ts.map +1 -0
- package/dist/loaders/dot-graph-loader.js +669 -0
- package/dist/loaders/dot-graph-loader.js.map +1 -0
- package/dist/loaders/json-graph-loader.d.ts +7 -0
- package/dist/loaders/json-graph-loader.d.ts.map +1 -0
- package/dist/loaders/json-graph-loader.js +32 -0
- package/dist/loaders/json-graph-loader.js.map +1 -0
- package/dist/loaders/parsers/edge-parsers.d.ts +3 -0
- package/dist/loaders/parsers/edge-parsers.d.ts.map +1 -0
- package/dist/loaders/{edge-parsers.js → parsers/edge-parsers.js} +2 -1
- package/dist/loaders/parsers/edge-parsers.js.map +1 -0
- package/dist/loaders/parsers/node-parsers.d.ts +3 -0
- package/dist/loaders/parsers/node-parsers.d.ts.map +1 -0
- package/dist/loaders/{node-parsers.js → parsers/node-parsers.js} +2 -1
- package/dist/loaders/parsers/node-parsers.js.map +1 -0
- package/dist/loaders/parsers/parse-json-graph.d.ts +30 -0
- package/dist/loaders/parsers/parse-json-graph.d.ts.map +1 -0
- package/dist/loaders/parsers/parse-json-graph.js +79 -0
- package/dist/loaders/parsers/parse-json-graph.js.map +1 -0
- package/dist/style/graph-layer-stylesheet.d.ts +3 -2
- package/dist/style/graph-layer-stylesheet.js +1 -0
- package/dist/style/graph-style-accessor-map.d.ts +1 -0
- package/dist/style/graph-style-accessor-map.js +1 -0
- package/dist/style/graph-style-engine.d.ts +6 -3
- package/dist/style/graph-style-engine.d.ts.map +1 -1
- package/dist/style/graph-style-engine.js +7 -5
- package/dist/style/graph-style-engine.js.map +1 -1
- package/dist/style/graph-stylesheet.schema.d.ts +1 -0
- package/dist/style/graph-stylesheet.schema.js +1 -0
- package/dist/style/style-property.d.ts +1 -0
- package/dist/style/style-property.js +2 -1
- package/dist/style/{style-engine.d.ts → stylesheet-engine.d.ts} +5 -4
- package/dist/style/stylesheet-engine.d.ts.map +1 -0
- package/dist/style/{style-engine.js → stylesheet-engine.js} +4 -3
- package/dist/style/stylesheet-engine.js.map +1 -0
- package/dist/utils/collapsed-chains.d.ts +10 -9
- package/dist/utils/collapsed-chains.d.ts.map +1 -1
- package/dist/utils/collapsed-chains.js +2 -6
- package/dist/utils/collapsed-chains.js.map +1 -1
- package/dist/utils/layer-utils.d.ts +1 -0
- package/dist/utils/layer-utils.js +1 -0
- package/dist/utils/log.d.ts +1 -0
- package/dist/utils/log.js +1 -0
- package/dist/utils/node-boundary.d.ts +1 -0
- package/dist/utils/node-boundary.js +1 -0
- package/dist/utils/polygon-calculations.d.ts +1 -0
- package/dist/utils/polygon-calculations.js +1 -0
- package/dist/utils/rank-grid.d.ts +31 -0
- package/dist/utils/rank-grid.d.ts.map +1 -0
- package/dist/utils/rank-grid.js +307 -0
- package/dist/utils/rank-grid.js.map +1 -0
- package/package.json +7 -11
- package/src/_disabled/arrow-graph-data.ts.disabled +18 -0
- package/src/_disabled/columnar-graph-data-builder.ts.disabled +250 -0
- package/src/_disabled/graph-runtime-layout.ts.disabled +29 -0
- package/src/core/graph-engine.ts +201 -84
- package/src/core/graph-layout.ts +52 -29
- package/src/core/interaction-manager.ts +20 -20
- package/src/graph/arrow-graph.ts +648 -0
- package/src/graph/classic-graph.ts +447 -0
- package/src/graph/edge.ts +7 -7
- package/src/graph/functions/arrow-utils.ts +72 -0
- package/src/graph/functions/convert-arrow-graph-to-classic-graph.ts.disabled +47 -0
- package/src/graph/functions/convert-plain-graph-to-arrow-graph.ts.disabled +119 -0
- package/src/graph/functions/create-graph-from-data.ts +16 -0
- package/src/graph/functions/create-plain-graph-from-data.ts.disabled +176 -0
- package/src/graph/graph-normalization.ts +87 -0
- package/src/graph/graph.ts +68 -339
- package/src/graph/node.ts +9 -9
- package/src/graph/tabular-graph.ts.disabled +761 -0
- package/src/graph-data/arrow-graph-data-builder.ts +165 -0
- package/src/graph-data/graph-data-builder.ts +7 -0
- package/src/graph-data/graph-data.ts +57 -0
- package/src/graph-data/plain-graph-data-builder.ts +132 -0
- package/src/index.ts +53 -13
- package/src/layers/common-layers/flow-path-layer/flow-path-layer.ts +1 -2
- package/src/layers/common-layers/grid-layer/grid-layer.ts +237 -0
- package/src/layers/edge-attachment-helper.ts +22 -16
- package/src/layers/graph-layer.ts +642 -62
- package/src/layouts/d3-dag/collapsable-d3-dag-layout.ts +330 -0
- package/src/layouts/d3-dag/d3-dag-layout.ts +166 -396
- package/src/layouts/d3-force/d3-force-layout.ts +52 -30
- package/src/layouts/experimental/force-multi-graph-layout.ts +55 -49
- package/src/layouts/experimental/hive-plot-layout.ts +41 -42
- package/src/layouts/experimental/radial-layout.ts +39 -20
- package/src/layouts/gpu-force/gpu-force-layout.ts +72 -70
- package/src/layouts/simple-layout.ts +20 -44
- package/src/loaders/{create-graph.ts → deprecated/create-graph.ts.disabled} +6 -6
- package/src/loaders/deprecated/json-classic-graph-loader.ts.disabled +33 -0
- package/src/loaders/{simple-json-graph-loader.ts → deprecated/simple-json-graph-loader.ts.disabled} +3 -3
- package/src/loaders/{table-graph-loader.ts → deprecated/table-graph-loader.ts.disabled} +8 -8
- package/src/loaders/dot-graph-loader.ts +860 -0
- package/src/loaders/json-graph-loader.ts +48 -0
- package/src/loaders/parsers/create-graph-data.ts.disabled +45 -0
- package/src/loaders/{edge-parsers.ts → parsers/edge-parsers.ts} +2 -2
- package/src/loaders/{node-parsers.ts → parsers/node-parsers.ts} +2 -2
- package/src/loaders/parsers/parse-json-graph.ts +134 -0
- package/src/style/graph-style-engine.ts +5 -2
- package/src/style/{style-engine.ts → stylesheet-engine.ts} +3 -3
- package/src/utils/collapsed-chains.ts +11 -17
- package/src/utils/rank-grid.ts +426 -0
- package/dist/loaders/create-graph.d.ts +0 -12
- package/dist/loaders/create-graph.d.ts.map +0 -1
- package/dist/loaders/create-graph.js +0 -38
- package/dist/loaders/create-graph.js.map +0 -1
- package/dist/loaders/edge-parsers.d.ts +0 -2
- package/dist/loaders/edge-parsers.d.ts.map +0 -1
- package/dist/loaders/edge-parsers.js.map +0 -1
- package/dist/loaders/json-loader.d.ts +0 -7
- package/dist/loaders/json-loader.d.ts.map +0 -1
- package/dist/loaders/json-loader.js +0 -16
- package/dist/loaders/json-loader.js.map +0 -1
- package/dist/loaders/node-parsers.d.ts +0 -2
- package/dist/loaders/node-parsers.d.ts.map +0 -1
- package/dist/loaders/node-parsers.js.map +0 -1
- package/dist/loaders/simple-json-graph-loader.d.ts +0 -11
- package/dist/loaders/simple-json-graph-loader.d.ts.map +0 -1
- package/dist/loaders/simple-json-graph-loader.js +0 -20
- package/dist/loaders/simple-json-graph-loader.js.map +0 -1
- package/dist/loaders/table-graph-loader.d.ts +0 -16
- package/dist/loaders/table-graph-loader.d.ts.map +0 -1
- package/dist/loaders/table-graph-loader.js +0 -91
- package/dist/loaders/table-graph-loader.js.map +0 -1
- package/dist/style/style-engine.d.ts.map +0 -1
- package/dist/style/style-engine.js.map +0 -1
- package/dist/widgets/long-press-button.d.ts +0 -12
- package/dist/widgets/long-press-button.d.ts.map +0 -1
- package/dist/widgets/long-press-button.js +0 -31
- package/dist/widgets/long-press-button.js.map +0 -1
- package/dist/widgets/view-control-widget.d.ts +0 -77
- package/dist/widgets/view-control-widget.d.ts.map +0 -1
- package/dist/widgets/view-control-widget.js +0 -197
- package/dist/widgets/view-control-widget.js.map +0 -1
- package/src/loaders/json-loader.ts +0 -19
- package/src/widgets/long-press-button.tsx +0 -50
- package/src/widgets/view-control-widget.tsx +0 -339
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
/* eslint-disable no-continue, complexity, max-statements */
|
|
6
6
|
|
|
7
7
|
import {GraphLayout, GraphLayoutProps} from '../../core/graph-layout';
|
|
8
|
-
import type {Graph} from '../../graph/graph';
|
|
8
|
+
import type {Graph, NodeInterface, EdgeInterface} from '../../graph/graph';
|
|
9
9
|
import {Node} from '../../graph/node';
|
|
10
|
-
import {Edge} from '../../graph/edge';
|
|
11
10
|
import {
|
|
12
11
|
coordCenter,
|
|
13
12
|
coordGreedy,
|
|
@@ -26,8 +25,8 @@ import {
|
|
|
26
25
|
layeringTopological,
|
|
27
26
|
sugiyama,
|
|
28
27
|
zherebko,
|
|
29
|
-
type Coord,
|
|
30
|
-
type Decross,
|
|
28
|
+
// type Coord,
|
|
29
|
+
// type Decross,
|
|
31
30
|
type DefaultGrid,
|
|
32
31
|
type DefaultSugiyama,
|
|
33
32
|
type DefaultZherebko,
|
|
@@ -39,46 +38,44 @@ import {
|
|
|
39
38
|
} from 'd3-dag';
|
|
40
39
|
import {log} from '../../utils/log';
|
|
41
40
|
|
|
42
|
-
export type
|
|
43
|
-
export type D3DagLayeringName = 'simplex' | 'longestPath' | 'topological';
|
|
44
|
-
export type D3DagDecrossName = 'twoLayer' | 'opt' | 'dfs';
|
|
45
|
-
export type D3DagCoordName = 'simplex' | 'greedy' | 'quad' | 'center' | 'topological';
|
|
46
|
-
export type D3DagDagBuilderName = 'graph' | 'connect' | 'stratify';
|
|
47
|
-
export type D3DagOrientation = 'TB' | 'BT' | 'LR' | 'RL';
|
|
48
|
-
export type D3DagCenterOption = boolean | {x?: boolean; y?: boolean};
|
|
49
|
-
|
|
50
|
-
export type D3DagLayoutOperator =
|
|
51
|
-
| DefaultSugiyama
|
|
52
|
-
| DefaultGrid
|
|
53
|
-
| DefaultZherebko
|
|
54
|
-
| ((dag: MutGraph<Node, Edge>) => LayoutResult);
|
|
55
|
-
|
|
56
|
-
export type D3DagLayoutOptions = GraphLayoutProps & {
|
|
41
|
+
export type D3DagLayoutProps = GraphLayoutProps & {
|
|
57
42
|
/** Which high-level layout operator to use. */
|
|
58
|
-
layout?:
|
|
43
|
+
layout?: 'sugiyama' | 'grid' | 'zherebko';
|
|
59
44
|
/** Layering operator used by sugiyama layouts. */
|
|
60
|
-
layering?:
|
|
45
|
+
layering?: 'simplex' | 'longestPath' | 'topological';
|
|
46
|
+
/** Accessor for node rank for layering */
|
|
47
|
+
nodeRank?: string | ((node: NodeInterface) => number | undefined);
|
|
61
48
|
/** Decrossing operator used by sugiyama layouts. */
|
|
62
|
-
decross?:
|
|
49
|
+
decross?: 'twoLayer' | 'opt' | 'dfs';
|
|
63
50
|
/** Coordinate assignment operator used by sugiyama layouts. */
|
|
64
|
-
coord?:
|
|
51
|
+
coord?: 'simplex' | 'greedy' | 'quad' | 'center' | 'topological';
|
|
65
52
|
/** Node sizing accessor passed to the active layout. */
|
|
66
|
-
nodeSize?: NodeSize<
|
|
53
|
+
nodeSize?: NodeSize<NodeInterface, EdgeInterface>;
|
|
67
54
|
/** Optional gap between nodes. Alias: separation. */
|
|
68
55
|
gap?: readonly [number, number];
|
|
69
56
|
/** Optional gap between nodes. */
|
|
70
57
|
separation?: readonly [number, number];
|
|
71
58
|
/** Orientation transform applied after the layout finishes. */
|
|
72
|
-
orientation?:
|
|
59
|
+
orientation?: 'TB' | 'BT' | 'LR' | 'RL';
|
|
73
60
|
/** Whether to center the layout along each axis. */
|
|
74
|
-
center?:
|
|
61
|
+
center?: boolean | {x?: boolean; y?: boolean};
|
|
75
62
|
/** How to convert the Graph into a DAG. */
|
|
76
|
-
dagBuilder?:
|
|
77
|
-
|
|
78
|
-
|
|
63
|
+
dagBuilder?: 'graph' | 'connect' | 'stratify';
|
|
64
|
+
|
|
65
|
+
customDagBuilder?: DagBuilder;
|
|
66
|
+
customLayout?: D3DagLayoutOperator;
|
|
67
|
+
customLayering?: LayeringOperator;
|
|
68
|
+
customDecross?: DecrossOperator;
|
|
69
|
+
customCoord?: CoordOperator;
|
|
79
70
|
};
|
|
80
71
|
|
|
81
|
-
type
|
|
72
|
+
export type D3DagLayoutOperator =
|
|
73
|
+
| DefaultSugiyama
|
|
74
|
+
| DefaultGrid
|
|
75
|
+
| DefaultZherebko
|
|
76
|
+
| ((dag: MutGraph<NodeInterface, EdgeInterface>) => LayoutResult);
|
|
77
|
+
|
|
78
|
+
type DagBuilder = (graph: Graph) => MutGraph<NodeInterface, EdgeInterface>;
|
|
82
79
|
|
|
83
80
|
type LayeringOperator =
|
|
84
81
|
| ReturnType<typeof layeringSimplex>
|
|
@@ -95,23 +92,16 @@ type CoordOperator =
|
|
|
95
92
|
| ReturnType<typeof coordSimplex>
|
|
96
93
|
| ReturnType<typeof coordTopological>;
|
|
97
94
|
|
|
98
|
-
type LayoutCallable = (dag: MutGraph<
|
|
95
|
+
type LayoutCallable = (dag: MutGraph<NodeInterface, EdgeInterface>) => LayoutResult;
|
|
99
96
|
|
|
100
97
|
type LayoutWithConfiguration = LayoutCallable & {
|
|
101
98
|
layering?: (layer?: any) => any;
|
|
102
99
|
decross?: (decross?: any) => any;
|
|
103
100
|
coord?: (coord?: any) => any;
|
|
104
|
-
nodeSize?: (size?: NodeSize<
|
|
101
|
+
nodeSize?: (size?: NodeSize<NodeInterface, EdgeInterface>) => any;
|
|
105
102
|
gap?: (gap?: readonly [number, number]) => any;
|
|
106
103
|
};
|
|
107
104
|
|
|
108
|
-
type CollapsedChainDescriptor = {
|
|
109
|
-
id: string;
|
|
110
|
-
nodeIds: (string | number)[];
|
|
111
|
-
edgeIds: (string | number)[];
|
|
112
|
-
representativeId: string | number;
|
|
113
|
-
};
|
|
114
|
-
|
|
115
105
|
type DagBounds = {
|
|
116
106
|
minX: number;
|
|
117
107
|
maxX: number;
|
|
@@ -121,59 +111,74 @@ type DagBounds = {
|
|
|
121
111
|
centerY: number;
|
|
122
112
|
};
|
|
123
113
|
|
|
114
|
+
const DAG_ID_SEPARATOR = '::';
|
|
115
|
+
|
|
124
116
|
const DEFAULT_NODE_SIZE: readonly [number, number] = [140, 120];
|
|
125
117
|
const DEFAULT_GAP: readonly [number, number] = [0, 0];
|
|
126
118
|
|
|
127
|
-
const LAYERING_FACTORIES
|
|
119
|
+
const LAYERING_FACTORIES = {
|
|
128
120
|
simplex: layeringSimplex,
|
|
129
121
|
longestPath: layeringLongestPath,
|
|
130
122
|
topological: layeringTopological
|
|
131
|
-
}
|
|
123
|
+
} as const satisfies Record<string, () => LayeringOperator>;
|
|
132
124
|
|
|
133
|
-
const DECROSS_FACTORIES
|
|
125
|
+
const DECROSS_FACTORIES = {
|
|
134
126
|
twoLayer: decrossTwoLayer,
|
|
135
127
|
opt: decrossOpt,
|
|
136
128
|
dfs: decrossDfs
|
|
137
|
-
}
|
|
129
|
+
} as const satisfies Record<string, () => DecrossOperator>;
|
|
138
130
|
|
|
139
|
-
const COORD_FACTORIES
|
|
131
|
+
const COORD_FACTORIES = {
|
|
140
132
|
simplex: coordSimplex,
|
|
141
133
|
greedy: coordGreedy,
|
|
142
134
|
quad: coordQuad,
|
|
143
135
|
center: coordCenter,
|
|
144
136
|
topological: coordTopological
|
|
145
|
-
}
|
|
137
|
+
} as const satisfies Record<string, () => CoordOperator>;
|
|
146
138
|
|
|
147
|
-
const LAYOUT_FACTORIES
|
|
139
|
+
const LAYOUT_FACTORIES = {
|
|
148
140
|
sugiyama: () => sugiyama(),
|
|
149
141
|
grid: () => grid(),
|
|
150
142
|
zherebko: () => zherebko()
|
|
151
|
-
}
|
|
143
|
+
} as const satisfies Record<string, () => LayoutWithConfiguration>;
|
|
152
144
|
|
|
153
|
-
|
|
145
|
+
function isNodeInterface(value: unknown): value is NodeInterface {
|
|
146
|
+
return Boolean(value) && typeof value === 'object' && (value as NodeInterface).isNode === true;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function isEdgeInterface(value: unknown): value is EdgeInterface {
|
|
150
|
+
return Boolean(value) && typeof value === 'object' && (value as EdgeInterface).isEdge === true;
|
|
151
|
+
}
|
|
154
152
|
|
|
155
153
|
/**
|
|
156
154
|
* Layout that orchestrates d3-dag operators from declarative options.
|
|
157
155
|
*/
|
|
158
|
-
export class D3DagLayout extends GraphLayout<
|
|
159
|
-
static defaultProps: Required<
|
|
156
|
+
export class D3DagLayout<PropsT extends D3DagLayoutProps = D3DagLayoutProps> extends GraphLayout<PropsT> {
|
|
157
|
+
static defaultProps: Readonly<Required<D3DagLayoutProps>> = {
|
|
158
|
+
...GraphLayout.defaultProps,
|
|
160
159
|
layout: 'sugiyama',
|
|
161
160
|
layering: 'topological',
|
|
162
161
|
decross: 'twoLayer',
|
|
163
162
|
coord: 'greedy',
|
|
163
|
+
nodeRank: undefined,
|
|
164
164
|
nodeSize: DEFAULT_NODE_SIZE,
|
|
165
165
|
gap: DEFAULT_GAP,
|
|
166
166
|
separation: DEFAULT_GAP,
|
|
167
167
|
orientation: 'TB',
|
|
168
168
|
center: true,
|
|
169
169
|
dagBuilder: 'graph',
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
|
|
171
|
+
customLayout: undefined,
|
|
172
|
+
customLayering: undefined,
|
|
173
|
+
customDecross: undefined,
|
|
174
|
+
customCoord: undefined,
|
|
175
|
+
customDagBuilder: undefined
|
|
176
|
+
} as const;
|
|
172
177
|
|
|
173
178
|
protected readonly _name = 'D3DagLayout';
|
|
174
179
|
|
|
175
|
-
|
|
176
|
-
private _dag: MutGraph<
|
|
180
|
+
protected _graph: Graph | null = null;
|
|
181
|
+
private _dag: MutGraph<NodeInterface, EdgeInterface> | null = null;
|
|
177
182
|
private _layoutOperator: LayoutWithConfiguration | null = null;
|
|
178
183
|
private _rawNodePositions = new Map<string | number, [number, number]>();
|
|
179
184
|
private _rawEdgePoints = new Map<string | number, [number, number][]>();
|
|
@@ -183,19 +188,32 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
183
188
|
private _lockedNodePositions = new Map<string | number, [number, number]>();
|
|
184
189
|
private _dagBounds: DagBounds | null = null;
|
|
185
190
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
private _chainDescriptors = new Map<string, CollapsedChainDescriptor>();
|
|
191
|
-
private _nodeToChainId = new Map<string | number, string>();
|
|
192
|
-
private _collapsedChainState = new Map<string, boolean>();
|
|
193
|
-
private _hiddenNodeIds = new Set<string | number>();
|
|
191
|
+
protected _nodeLookup = new Map<string | number, NodeInterface>();
|
|
192
|
+
protected _stringIdLookup = new Map<string, string | number>();
|
|
193
|
+
protected _edgeLookup = new Map<string, EdgeInterface>();
|
|
194
|
+
protected _incomingParentMap = new Map<string | number, (string | number)[]>();
|
|
194
195
|
|
|
195
|
-
constructor(
|
|
196
|
-
|
|
196
|
+
constructor(props: D3DagLayoutProps, defaultProps?: Required<PropsT>) {
|
|
197
|
+
// @ts-expect-error TS2345 - Type 'Required<D3DagLayoutProps>' is not assignable to type 'Required<PropsT>'.
|
|
198
|
+
super(props, defaultProps || D3DagLayout.defaultProps);
|
|
197
199
|
}
|
|
198
200
|
|
|
201
|
+
setProps(options: Partial<D3DagLayoutProps>): void {
|
|
202
|
+
this.props = {...this.props, ...options};
|
|
203
|
+
if (
|
|
204
|
+
options.layout !== undefined ||
|
|
205
|
+
options.layering !== undefined ||
|
|
206
|
+
options.decross !== undefined ||
|
|
207
|
+
options.coord !== undefined ||
|
|
208
|
+
options.nodeSize !== undefined ||
|
|
209
|
+
options.gap !== undefined ||
|
|
210
|
+
options.separation !== undefined
|
|
211
|
+
) {
|
|
212
|
+
this._layoutOperator = null;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
|
|
199
217
|
initializeGraph(graph: Graph): void {
|
|
200
218
|
this.updateGraph(graph);
|
|
201
219
|
}
|
|
@@ -206,9 +224,6 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
206
224
|
this._stringIdLookup = new Map();
|
|
207
225
|
this._edgeLookup = new Map();
|
|
208
226
|
this._incomingParentMap = new Map();
|
|
209
|
-
this._chainDescriptors = new Map();
|
|
210
|
-
this._nodeToChainId = new Map();
|
|
211
|
-
this._hiddenNodeIds = new Set();
|
|
212
227
|
|
|
213
228
|
for (const node of graph.getNodes()) {
|
|
214
229
|
const id = node.getId();
|
|
@@ -246,80 +261,15 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
246
261
|
stop(): void {}
|
|
247
262
|
|
|
248
263
|
toggleCollapsedChain(chainId: string): void {
|
|
249
|
-
|
|
250
|
-
log.log(1, `D3DagLayout: toggleCollapsedChain(${chainId}) ignored (no graph)`);
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
if (!this._chainDescriptors.has(chainId)) {
|
|
254
|
-
this._refreshCollapsedChains();
|
|
255
|
-
}
|
|
256
|
-
if (!this._chainDescriptors.has(chainId)) {
|
|
257
|
-
log.log(1, `D3DagLayout: toggleCollapsedChain(${chainId}) skipped (unknown chain)`);
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
const collapsed = this._isChainCollapsed(chainId);
|
|
261
|
-
const nextState = !collapsed;
|
|
262
|
-
log.log(
|
|
263
|
-
0,
|
|
264
|
-
`D3DagLayout: toggleCollapsedChain(${chainId}) -> ${nextState ? 'collapsed' : 'expanded'}`
|
|
265
|
-
);
|
|
266
|
-
// eslint-disable-next-line no-console
|
|
267
|
-
console.log(
|
|
268
|
-
`D3DagLayout: toggleCollapsedChain(${chainId}) -> ${nextState ? 'collapsed' : 'expanded'}`
|
|
269
|
-
);
|
|
270
|
-
this._collapsedChainState.set(chainId, nextState);
|
|
271
|
-
this._runLayout();
|
|
264
|
+
log.log(1, `D3DagLayout: toggleCollapsedChain(${chainId}) ignored (collapsing disabled)`);
|
|
272
265
|
}
|
|
273
266
|
|
|
274
267
|
setCollapsedChains(chainIds: Iterable<string>): void {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
if (!this._chainDescriptors.size) {
|
|
280
|
-
this._refreshCollapsedChains();
|
|
281
|
-
}
|
|
282
|
-
const desired = new Set(chainIds);
|
|
283
|
-
log.log(0, `D3DagLayout: setCollapsedChains(${desired.size}) requested`);
|
|
284
|
-
let changed = false;
|
|
285
|
-
for (const chainId of this._chainDescriptors.keys()) {
|
|
286
|
-
const next = desired.has(chainId);
|
|
287
|
-
if (this._isChainCollapsed(chainId) !== next) {
|
|
288
|
-
this._collapsedChainState.set(chainId, next);
|
|
289
|
-
changed = true;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
if (changed) {
|
|
293
|
-
log.log(0, 'D3DagLayout: setCollapsedChains -> changes detected, rerunning layout');
|
|
294
|
-
// eslint-disable-next-line no-console
|
|
295
|
-
console.log('D3DagLayout: setCollapsedChains -> changes detected, rerunning layout');
|
|
296
|
-
this._runLayout();
|
|
297
|
-
} else {
|
|
298
|
-
log.log(1, 'D3DagLayout: setCollapsedChains -> no changes');
|
|
299
|
-
// eslint-disable-next-line no-console
|
|
300
|
-
console.log('D3DagLayout: setCollapsedChains -> no changes');
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
setPipelineOptions(options: Partial<D3DagLayoutOptions>): void {
|
|
305
|
-
this._options = {...this._options, ...options};
|
|
306
|
-
if (
|
|
307
|
-
options.layout !== undefined ||
|
|
308
|
-
options.layering !== undefined ||
|
|
309
|
-
options.decross !== undefined ||
|
|
310
|
-
options.coord !== undefined ||
|
|
311
|
-
options.nodeSize !== undefined ||
|
|
312
|
-
options.gap !== undefined ||
|
|
313
|
-
options.separation !== undefined
|
|
314
|
-
) {
|
|
315
|
-
this._layoutOperator = null;
|
|
316
|
-
}
|
|
317
|
-
if (options.collapseLinearChains !== undefined && this._graph) {
|
|
318
|
-
this._runLayout();
|
|
319
|
-
}
|
|
268
|
+
const desired = Array.isArray(chainIds) ? chainIds : Array.from(chainIds);
|
|
269
|
+
log.log(1, `D3DagLayout: setCollapsedChains(${desired.length}) ignored (collapsing disabled)`);
|
|
320
270
|
}
|
|
321
271
|
|
|
322
|
-
getNodePosition(node:
|
|
272
|
+
getNodePosition(node: NodeInterface): [number, number] | null {
|
|
323
273
|
if (this._shouldSkipNode(node.getId())) {
|
|
324
274
|
return null;
|
|
325
275
|
}
|
|
@@ -327,7 +277,7 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
327
277
|
return this._nodePositions.get(mappedId) || null;
|
|
328
278
|
}
|
|
329
279
|
|
|
330
|
-
getEdgePosition(edge:
|
|
280
|
+
getEdgePosition(edge: EdgeInterface):
|
|
331
281
|
| {
|
|
332
282
|
type: string;
|
|
333
283
|
sourcePosition: [number, number];
|
|
@@ -363,22 +313,22 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
363
313
|
};
|
|
364
314
|
}
|
|
365
315
|
|
|
366
|
-
getLinkControlPoints(edge:
|
|
316
|
+
getLinkControlPoints(edge: EdgeInterface): [number, number][] {
|
|
367
317
|
return this._edgeControlPoints.get(edge.getId()) || [];
|
|
368
318
|
}
|
|
369
319
|
|
|
370
|
-
lockNodePosition(node:
|
|
320
|
+
lockNodePosition(node: NodeInterface, x: number, y: number): void {
|
|
371
321
|
this._lockedNodePositions.set(node.getId(), [x, y]);
|
|
372
322
|
this._nodePositions.set(node.getId(), [x, y]);
|
|
373
323
|
this._onLayoutChange();
|
|
374
324
|
this._onLayoutDone();
|
|
375
325
|
}
|
|
376
326
|
|
|
377
|
-
unlockNodePosition(node:
|
|
327
|
+
unlockNodePosition(node: NodeInterface): void {
|
|
378
328
|
this._lockedNodePositions.delete(node.getId());
|
|
379
329
|
}
|
|
380
330
|
|
|
381
|
-
|
|
331
|
+
protected _runLayout(): void {
|
|
382
332
|
if (!this._graph) {
|
|
383
333
|
return;
|
|
384
334
|
}
|
|
@@ -398,160 +348,17 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
398
348
|
}
|
|
399
349
|
}
|
|
400
350
|
|
|
401
|
-
|
|
402
|
-
const previousChainCount = this._chainDescriptors.size;
|
|
403
|
-
if (!this._graph) {
|
|
404
|
-
if (previousChainCount > 0) {
|
|
405
|
-
log.log(0, 'D3DagLayout: clearing collapsed chains (graph unavailable)');
|
|
406
|
-
// eslint-disable-next-line no-console
|
|
407
|
-
console.log('D3DagLayout: clearing collapsed chains (graph unavailable)');
|
|
408
|
-
}
|
|
409
|
-
this._chainDescriptors.clear();
|
|
410
|
-
this._nodeToChainId.clear();
|
|
411
|
-
this._hiddenNodeIds.clear();
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
log.log(
|
|
416
|
-
0,
|
|
417
|
-
`D3DagLayout: refreshing collapsed chains (previous=${previousChainCount})`
|
|
418
|
-
);
|
|
419
|
-
// eslint-disable-next-line no-console
|
|
420
|
-
console.log(
|
|
421
|
-
`D3DagLayout: refreshing collapsed chains (previous=${previousChainCount})`
|
|
422
|
-
);
|
|
423
|
-
|
|
424
|
-
const collapseDefault =
|
|
425
|
-
this._options.collapseLinearChains ?? D3DagLayout.defaultProps.collapseLinearChains;
|
|
426
|
-
|
|
427
|
-
const previousStates = new Map(this._collapsedChainState);
|
|
428
|
-
|
|
429
|
-
this._chainDescriptors.clear();
|
|
430
|
-
this._nodeToChainId.clear();
|
|
431
|
-
this._hiddenNodeIds.clear();
|
|
432
|
-
|
|
433
|
-
const nodes = this._graph.getNodes();
|
|
434
|
-
const candidateNodes = new Set<string | number>();
|
|
435
|
-
const incomingCache = new Map<string | number, Edge[]>();
|
|
436
|
-
const outgoingCache = new Map<string | number, Edge[]>();
|
|
437
|
-
|
|
438
|
-
for (const node of nodes) {
|
|
439
|
-
const incoming = this._getIncomingEdges(node);
|
|
440
|
-
const outgoing = this._getOutgoingEdges(node);
|
|
441
|
-
incomingCache.set(node.getId(), incoming);
|
|
442
|
-
outgoingCache.set(node.getId(), outgoing);
|
|
443
|
-
if (incoming.length <= 1 && outgoing.length <= 1 && incoming.length + outgoing.length > 0) {
|
|
444
|
-
candidateNodes.add(node.getId());
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
const visited = new Set<string | number>();
|
|
449
|
-
for (const node of nodes) {
|
|
450
|
-
const nodeId = node.getId();
|
|
451
|
-
if (!candidateNodes.has(nodeId) || visited.has(nodeId)) {
|
|
452
|
-
continue;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
const incoming = incomingCache.get(nodeId) ?? [];
|
|
456
|
-
const hasCandidateParent =
|
|
457
|
-
incoming.length === 1 && candidateNodes.has(incoming[0].getSourceNodeId());
|
|
458
|
-
if (hasCandidateParent) {
|
|
459
|
-
continue;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
const chainNodeIds: (string | number)[] = [];
|
|
463
|
-
const chainEdgeIds: (string | number)[] = [];
|
|
464
|
-
let currentNode: Node | undefined = node;
|
|
465
|
-
|
|
466
|
-
while (currentNode) {
|
|
467
|
-
const currentId = currentNode.getId();
|
|
468
|
-
if (!candidateNodes.has(currentId) || visited.has(currentId)) {
|
|
469
|
-
break;
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
visited.add(currentId);
|
|
473
|
-
chainNodeIds.push(currentId);
|
|
474
|
-
|
|
475
|
-
const outgoing = outgoingCache.get(currentId) ?? [];
|
|
476
|
-
if (outgoing.length !== 1) {
|
|
477
|
-
break;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
const nextEdge = outgoing[0];
|
|
481
|
-
const nextNodeId = nextEdge.getTargetNodeId();
|
|
482
|
-
if (!candidateNodes.has(nextNodeId)) {
|
|
483
|
-
break;
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
const nextIncoming = incomingCache.get(nextNodeId) ?? [];
|
|
487
|
-
if (nextIncoming.length !== 1) {
|
|
488
|
-
break;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
chainEdgeIds.push(nextEdge.getId());
|
|
492
|
-
currentNode = this._nodeLookup.get(nextNodeId);
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
if (chainNodeIds.length > 1) {
|
|
496
|
-
const chainId = this._createChainId(chainNodeIds);
|
|
497
|
-
const collapsed = previousStates.has(chainId)
|
|
498
|
-
? previousStates.get(chainId)
|
|
499
|
-
: collapseDefault;
|
|
500
|
-
this._chainDescriptors.set(chainId, {
|
|
501
|
-
id: chainId,
|
|
502
|
-
nodeIds: chainNodeIds,
|
|
503
|
-
edgeIds: chainEdgeIds,
|
|
504
|
-
representativeId: chainNodeIds[0]
|
|
505
|
-
});
|
|
506
|
-
this._collapsedChainState.set(chainId, collapsed);
|
|
507
|
-
for (const chainNodeId of chainNodeIds) {
|
|
508
|
-
this._nodeToChainId.set(chainNodeId, chainId);
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
for (const key of previousStates.keys()) {
|
|
514
|
-
if (!this._chainDescriptors.has(key)) {
|
|
515
|
-
this._collapsedChainState.delete(key);
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
this._hiddenNodeIds.clear();
|
|
520
|
-
for (const [chainId, descriptor] of this._chainDescriptors) {
|
|
521
|
-
const collapsed = this._isChainCollapsed(chainId);
|
|
522
|
-
if (collapsed) {
|
|
523
|
-
for (const nodeId of descriptor.nodeIds) {
|
|
524
|
-
// eslint-disable-next-line max-depth
|
|
525
|
-
if (nodeId !== descriptor.representativeId) {
|
|
526
|
-
this._hiddenNodeIds.add(nodeId);
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
|
|
351
|
+
protected _refreshCollapsedChains(): void {
|
|
532
352
|
this._updateCollapsedChainNodeMetadata();
|
|
533
|
-
|
|
534
|
-
let collapsedCount = 0;
|
|
535
|
-
for (const chainId of this._chainDescriptors.keys()) {
|
|
536
|
-
if (this._isChainCollapsed(chainId)) {
|
|
537
|
-
collapsedCount++;
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
log.log(
|
|
541
|
-
0,
|
|
542
|
-
`D3DagLayout: refreshed collapsed chains -> total=${this._chainDescriptors.size}, collapsed=${collapsedCount}`
|
|
543
|
-
);
|
|
544
353
|
}
|
|
545
354
|
|
|
546
|
-
private _buildDag(): MutGraph<
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
if (typeof builder === 'function') {
|
|
550
|
-
const dag = builder(this._graph);
|
|
355
|
+
private _buildDag(): MutGraph<NodeInterface, EdgeInterface> {
|
|
356
|
+
if (this.props.customDagBuilder) {
|
|
357
|
+
const dag = this.props.customDagBuilder(this._graph);
|
|
551
358
|
return this._ensureEdgeData(dag);
|
|
552
359
|
}
|
|
553
360
|
|
|
554
|
-
switch (
|
|
361
|
+
switch (this.props.dagBuilder) {
|
|
555
362
|
case 'connect':
|
|
556
363
|
return this._buildDagWithConnect();
|
|
557
364
|
case 'stratify':
|
|
@@ -562,9 +369,9 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
562
369
|
}
|
|
563
370
|
}
|
|
564
371
|
|
|
565
|
-
private _buildDagWithGraph(): MutGraph<
|
|
566
|
-
const dag = createDagGraph<
|
|
567
|
-
const dagNodeLookup = new Map<string | number, MutGraphNode<
|
|
372
|
+
private _buildDagWithGraph(): MutGraph<NodeInterface, EdgeInterface> {
|
|
373
|
+
const dag = createDagGraph<NodeInterface, EdgeInterface>();
|
|
374
|
+
const dagNodeLookup = new Map<string | number, MutGraphNode<NodeInterface, EdgeInterface>>();
|
|
568
375
|
|
|
569
376
|
for (const node of this._graph.getNodes()) {
|
|
570
377
|
if (this._shouldSkipNode(node.getId())) {
|
|
@@ -594,17 +401,18 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
594
401
|
return dag;
|
|
595
402
|
}
|
|
596
403
|
|
|
597
|
-
private _buildDagWithConnect(): MutGraph<
|
|
598
|
-
type ConnectDatum = {source: string; target: string; edge:
|
|
404
|
+
private _buildDagWithConnect(): MutGraph<NodeInterface, EdgeInterface> {
|
|
405
|
+
type ConnectDatum = {source: string; target: string; edge: EdgeInterface};
|
|
599
406
|
|
|
600
407
|
const connect = graphConnect()
|
|
601
408
|
.sourceId(({source}: ConnectDatum): string => source)
|
|
602
409
|
.targetId(({target}: ConnectDatum): string => target)
|
|
603
|
-
.nodeDatum((id: string):
|
|
410
|
+
.nodeDatum((id: string): NodeInterface => this._nodeLookup.get(this._fromDagId(id)) ?? new Node({id}))
|
|
604
411
|
.single(true);
|
|
605
412
|
|
|
606
|
-
const
|
|
607
|
-
|
|
413
|
+
const edges = Array.from(this._graph.getEdges());
|
|
414
|
+
|
|
415
|
+
const data: ConnectDatum[] = edges
|
|
608
416
|
.filter((edge) => edge.isDirected())
|
|
609
417
|
.map((edge) => {
|
|
610
418
|
const sourceId = this._mapNodeId(edge.getSourceNodeId());
|
|
@@ -623,7 +431,7 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
623
431
|
const seenIds = new Set<string | number>();
|
|
624
432
|
for (const dagNode of dag.nodes()) {
|
|
625
433
|
const datum = dagNode.data;
|
|
626
|
-
if (datum
|
|
434
|
+
if (isNodeInterface(datum)) {
|
|
627
435
|
seenIds.add(datum.getId());
|
|
628
436
|
}
|
|
629
437
|
}
|
|
@@ -640,10 +448,10 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
640
448
|
return this._ensureEdgeData(dag);
|
|
641
449
|
}
|
|
642
450
|
|
|
643
|
-
private _buildDagWithStratify(): MutGraph<
|
|
451
|
+
private _buildDagWithStratify(): MutGraph<NodeInterface, EdgeInterface> {
|
|
644
452
|
const stratify = graphStratify()
|
|
645
|
-
.id((node:
|
|
646
|
-
.parentIds((node:
|
|
453
|
+
.id((node: NodeInterface): string => this._toDagId(node.getId()))
|
|
454
|
+
.parentIds((node: NodeInterface): Iterable<string> => {
|
|
647
455
|
const parentIds = this._incomingParentMap.get(node.getId()) ?? [];
|
|
648
456
|
const mapped = new Set<string>();
|
|
649
457
|
for (const parentId of parentIds) {
|
|
@@ -659,104 +467,65 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
659
467
|
return mapped;
|
|
660
468
|
});
|
|
661
469
|
|
|
662
|
-
const
|
|
470
|
+
const nodes = Array.from(this._graph.getNodes());
|
|
471
|
+
const dag = stratify(nodes.filter((node) => !this._shouldSkipNode(node.getId())));
|
|
663
472
|
return this._ensureEdgeData(dag);
|
|
664
473
|
}
|
|
665
474
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
this._options.collapseLinearChains ?? D3DagLayout.defaultProps.collapseLinearChains;
|
|
669
|
-
return this._collapsedChainState.get(chainId) ?? collapseDefault;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
private _shouldSkipNode(nodeId: string | number): boolean {
|
|
673
|
-
return this._hiddenNodeIds.has(nodeId);
|
|
475
|
+
protected _shouldSkipNode(_nodeId: string | number): boolean {
|
|
476
|
+
return false;
|
|
674
477
|
}
|
|
675
478
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
if (!chainId) {
|
|
679
|
-
return nodeId;
|
|
680
|
-
}
|
|
681
|
-
const descriptor = this._chainDescriptors.get(chainId);
|
|
682
|
-
if (!descriptor) {
|
|
683
|
-
return nodeId;
|
|
684
|
-
}
|
|
685
|
-
return this._isChainCollapsed(chainId) ? descriptor.representativeId : nodeId;
|
|
479
|
+
protected _mapNodeId(nodeId: string | number): string | number {
|
|
480
|
+
return nodeId;
|
|
686
481
|
}
|
|
687
482
|
|
|
688
|
-
|
|
483
|
+
protected _updateCollapsedChainNodeMetadata(): void {
|
|
689
484
|
if (!this._graph) {
|
|
690
485
|
return;
|
|
691
486
|
}
|
|
692
487
|
for (const node of this._graph.getNodes()) {
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
node.setDataProperty('collapsedEdgeIds', []);
|
|
700
|
-
node.setDataProperty('collapsedChainRepresentativeId', null);
|
|
701
|
-
node.setDataProperty('isCollapsedChain', false);
|
|
702
|
-
continue;
|
|
703
|
-
}
|
|
704
|
-
const descriptor = this._chainDescriptors.get(chainId);
|
|
705
|
-
if (!descriptor) {
|
|
706
|
-
node.setDataProperty('collapsedChainId', null);
|
|
707
|
-
node.setDataProperty('collapsedChainLength', 1);
|
|
708
|
-
node.setDataProperty('collapsedNodeIds', []);
|
|
709
|
-
node.setDataProperty('collapsedEdgeIds', []);
|
|
710
|
-
node.setDataProperty('collapsedChainRepresentativeId', null);
|
|
711
|
-
node.setDataProperty('isCollapsedChain', false);
|
|
712
|
-
continue;
|
|
713
|
-
}
|
|
714
|
-
const collapsed = this._isChainCollapsed(chainId);
|
|
715
|
-
node.setDataProperty('collapsedChainId', chainId);
|
|
716
|
-
node.setDataProperty('collapsedChainLength', collapsed ? descriptor.nodeIds.length : 1);
|
|
717
|
-
node.setDataProperty('collapsedNodeIds', descriptor.nodeIds);
|
|
718
|
-
node.setDataProperty('collapsedEdgeIds', descriptor.edgeIds);
|
|
719
|
-
node.setDataProperty('collapsedChainRepresentativeId', descriptor.representativeId);
|
|
720
|
-
node.setDataProperty('isCollapsedChain', collapsed);
|
|
488
|
+
node.setDataProperty('collapsedChainId', null);
|
|
489
|
+
node.setDataProperty('collapsedChainLength', 1);
|
|
490
|
+
node.setDataProperty('collapsedNodeIds', []);
|
|
491
|
+
node.setDataProperty('collapsedEdgeIds', []);
|
|
492
|
+
node.setDataProperty('collapsedChainRepresentativeId', null);
|
|
493
|
+
node.setDataProperty('isCollapsedChain', false);
|
|
721
494
|
}
|
|
722
495
|
}
|
|
723
496
|
|
|
724
|
-
|
|
725
|
-
return `chain:${nodeIds.map((id) => this._toDagId(id)).join('>')}`;
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
private _getIncomingEdges(node: Node): Edge[] {
|
|
497
|
+
protected _getIncomingEdges(node: NodeInterface): EdgeInterface[] {
|
|
729
498
|
const nodeId = node.getId();
|
|
730
499
|
return node
|
|
731
500
|
.getConnectedEdges()
|
|
732
501
|
.filter((edge) => edge.isDirected() && edge.getTargetNodeId() === nodeId);
|
|
733
502
|
}
|
|
734
503
|
|
|
735
|
-
|
|
504
|
+
protected _getOutgoingEdges(node: NodeInterface): EdgeInterface[] {
|
|
736
505
|
const nodeId = node.getId();
|
|
737
506
|
return node
|
|
738
507
|
.getConnectedEdges()
|
|
739
508
|
.filter((edge) => edge.isDirected() && edge.getSourceNodeId() === nodeId);
|
|
740
509
|
}
|
|
741
510
|
|
|
742
|
-
private _ensureEdgeData<T>(dag: MutGraph<
|
|
511
|
+
private _ensureEdgeData<T>(dag: MutGraph<NodeInterface, T>): MutGraph<NodeInterface, EdgeInterface> {
|
|
743
512
|
for (const link of dag.links()) {
|
|
744
|
-
if (link.data
|
|
513
|
+
if (isEdgeInterface(link.data)) {
|
|
745
514
|
continue;
|
|
746
515
|
}
|
|
747
516
|
const sourceNode = link.source.data;
|
|
748
517
|
const targetNode = link.target.data;
|
|
749
|
-
if (!(sourceNode
|
|
518
|
+
if (!isNodeInterface(sourceNode) || !isNodeInterface(targetNode)) {
|
|
750
519
|
continue;
|
|
751
520
|
}
|
|
752
521
|
const key = this._edgeKey(sourceNode.getId(), targetNode.getId());
|
|
753
522
|
const edge = this._edgeLookup.get(key);
|
|
754
523
|
if (edge) {
|
|
755
|
-
(link as unknown as MutGraphLink<
|
|
524
|
+
(link as unknown as MutGraphLink<NodeInterface, EdgeInterface>).data = edge;
|
|
756
525
|
}
|
|
757
526
|
}
|
|
758
527
|
|
|
759
|
-
return dag as unknown as MutGraph<
|
|
528
|
+
return dag as unknown as MutGraph<NodeInterface, EdgeInterface>;
|
|
760
529
|
}
|
|
761
530
|
|
|
762
531
|
private _getLayoutOperator(): LayoutWithConfiguration {
|
|
@@ -764,7 +533,7 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
764
533
|
return this._layoutOperator;
|
|
765
534
|
}
|
|
766
535
|
|
|
767
|
-
const layoutOption = this.
|
|
536
|
+
const layoutOption = this.props.layout ?? D3DagLayout.defaultProps.layout;
|
|
768
537
|
let layout: LayoutWithConfiguration;
|
|
769
538
|
|
|
770
539
|
if (typeof layoutOption === 'string') {
|
|
@@ -773,24 +542,41 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
773
542
|
layout = layoutOption as LayoutWithConfiguration;
|
|
774
543
|
}
|
|
775
544
|
|
|
776
|
-
|
|
777
|
-
|
|
545
|
+
// TODO - is 'none' operator an option in d3-dag?
|
|
546
|
+
if (layout.layering && this.props.layering) {
|
|
547
|
+
let layeringOperator = this.props.customLayering || LAYERING_FACTORIES[this.props.layering]();
|
|
548
|
+
layout = layout.layering(layeringOperator);
|
|
549
|
+
const {nodeRank} = this.props;
|
|
550
|
+
if (nodeRank) {
|
|
551
|
+
// @ts-expect-error TS2345 - Argument of type '(dagNode: MutGraphNode<NodeInterface, EdgeInterface>) => number | undefined' is not assignable to parameter of type '(dagNode: MutGraphNode<NodeInterface, EdgeInterface>) => number'.
|
|
552
|
+
layeringOperator = layeringOperator.rank((dagNode) => {
|
|
553
|
+
const node = dagNode.data as NodeInterface;
|
|
554
|
+
const rank = typeof nodeRank === 'function' ? nodeRank?.(node) : node?.getPropertyValue(nodeRank) || undefined;
|
|
555
|
+
// if (rank !== undefined) {
|
|
556
|
+
// console.log(`Node ${node.getId()} assigned to rank ${rank}`);
|
|
557
|
+
// }
|
|
558
|
+
return rank;
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
layout = layout.layering(layeringOperator);
|
|
778
562
|
}
|
|
779
563
|
|
|
780
|
-
if (layout.decross && this.
|
|
781
|
-
|
|
564
|
+
if (layout.decross && this.props.decross) {
|
|
565
|
+
const decrossOperator = this.props.customDecross || DECROSS_FACTORIES[this.props.decross]();
|
|
566
|
+
layout = layout.decross(decrossOperator);
|
|
782
567
|
}
|
|
783
568
|
|
|
784
|
-
if (layout.coord && this.
|
|
785
|
-
|
|
569
|
+
if (layout.coord && this.props.coord) {
|
|
570
|
+
const coordOperator = this.props.customCoord || COORD_FACTORIES[this.props.coord]();
|
|
571
|
+
layout = layout.coord(coordOperator);
|
|
786
572
|
}
|
|
787
573
|
|
|
788
|
-
const nodeSize = this.
|
|
574
|
+
const nodeSize = this.props.nodeSize ?? DEFAULT_NODE_SIZE;
|
|
789
575
|
if (layout.nodeSize) {
|
|
790
576
|
layout = layout.nodeSize(nodeSize);
|
|
791
577
|
}
|
|
792
578
|
|
|
793
|
-
const gap = this.
|
|
579
|
+
const gap = this.props.separation ?? this.props.gap ?? DEFAULT_GAP;
|
|
794
580
|
if (layout.gap) {
|
|
795
581
|
layout = layout.gap(gap);
|
|
796
582
|
}
|
|
@@ -799,27 +585,6 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
799
585
|
return layout;
|
|
800
586
|
}
|
|
801
587
|
|
|
802
|
-
private _resolveLayering(option: D3DagLayeringName | LayeringOperator): LayeringOperator {
|
|
803
|
-
if (typeof option === 'string') {
|
|
804
|
-
return LAYERING_FACTORIES[option]();
|
|
805
|
-
}
|
|
806
|
-
return option;
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
private _resolveDecross(option: D3DagDecrossName | DecrossOperator): Decross<Node, Edge> {
|
|
810
|
-
if (typeof option === 'string') {
|
|
811
|
-
return DECROSS_FACTORIES[option]();
|
|
812
|
-
}
|
|
813
|
-
return option;
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
private _resolveCoord(option: D3DagCoordName | CoordOperator): Coord<Node, Edge> {
|
|
817
|
-
if (typeof option === 'string') {
|
|
818
|
-
return COORD_FACTORIES[option]();
|
|
819
|
-
}
|
|
820
|
-
return option;
|
|
821
|
-
}
|
|
822
|
-
|
|
823
588
|
private _cacheGeometry(): void {
|
|
824
589
|
this._rawNodePositions.clear();
|
|
825
590
|
this._rawEdgePoints.clear();
|
|
@@ -870,7 +635,12 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
870
635
|
for (const link of this._dag.links()) {
|
|
871
636
|
const source = link.source.data;
|
|
872
637
|
const target = link.target.data;
|
|
873
|
-
|
|
638
|
+
if (!isNodeInterface(source) || !isNodeInterface(target)) {
|
|
639
|
+
continue;
|
|
640
|
+
}
|
|
641
|
+
const edge = isEdgeInterface(link.data)
|
|
642
|
+
? link.data
|
|
643
|
+
: this._edgeLookup.get(this._edgeKey(source.getId(), target.getId()));
|
|
874
644
|
if (!edge) {
|
|
875
645
|
continue;
|
|
876
646
|
}
|
|
@@ -892,7 +662,7 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
892
662
|
}
|
|
893
663
|
|
|
894
664
|
const {offsetX, offsetY} = this._getOffsets();
|
|
895
|
-
const orientation = this.
|
|
665
|
+
const orientation = this.props.orientation ?? D3DagLayout.defaultProps.orientation;
|
|
896
666
|
|
|
897
667
|
const transform = (x: number, y: number): [number, number] => {
|
|
898
668
|
const localX = x - offsetX;
|
|
@@ -934,7 +704,7 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
934
704
|
if (!this._dagBounds) {
|
|
935
705
|
return {offsetX: 0, offsetY: 0};
|
|
936
706
|
}
|
|
937
|
-
const centerOption = this.
|
|
707
|
+
const centerOption = this.props.center ?? true;
|
|
938
708
|
let offsetX = 0;
|
|
939
709
|
let offsetY = 0;
|
|
940
710
|
if (centerOption === true) {
|
|
@@ -955,15 +725,15 @@ export class D3DagLayout extends GraphLayout<D3DagLayoutOptions> {
|
|
|
955
725
|
this._bounds = this._calculateBounds(this._nodePositions.values());
|
|
956
726
|
}
|
|
957
727
|
|
|
958
|
-
|
|
728
|
+
protected _edgeKey(sourceId: string | number, targetId: string | number): string {
|
|
959
729
|
return `${this._toDagId(sourceId)}${DAG_ID_SEPARATOR}${this._toDagId(targetId)}`;
|
|
960
730
|
}
|
|
961
731
|
|
|
962
|
-
|
|
732
|
+
protected _toDagId(id: string | number): string {
|
|
963
733
|
return String(id);
|
|
964
734
|
}
|
|
965
735
|
|
|
966
|
-
|
|
736
|
+
protected _fromDagId(id: string): string | number {
|
|
967
737
|
return this._stringIdLookup.get(id) ?? id;
|
|
968
738
|
}
|
|
969
739
|
}
|