@deck.gl-community/graph-layers 9.1.1 → 9.2.0-beta.3
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 +107 -0
- package/dist/_deprecated/old-constants.d.ts.map +1 -0
- package/dist/_deprecated/old-constants.js +111 -0
- package/dist/_deprecated/old-constants.js.map +1 -0
- package/dist/core/cache.d.ts +0 -1
- package/dist/core/cache.js +0 -1
- package/dist/core/constants.d.ts +12 -100
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +3 -44
- package/dist/core/constants.js.map +1 -1
- package/dist/core/graph-engine.d.ts +63 -20
- package/dist/core/graph-engine.d.ts.map +1 -1
- package/dist/core/graph-engine.js +163 -72
- package/dist/core/graph-engine.js.map +1 -1
- package/dist/core/graph-layout.d.ts +63 -32
- package/dist/core/graph-layout.d.ts.map +1 -1
- package/dist/core/graph-layout.js +118 -36
- package/dist/core/graph-layout.js.map +1 -1
- package/dist/core/interaction-manager.d.ts +7 -5
- package/dist/core/interaction-manager.d.ts.map +1 -1
- package/dist/core/interaction-manager.js +64 -20
- package/dist/core/interaction-manager.js.map +1 -1
- package/dist/graph/arrow-graph.d.ts +69 -0
- package/dist/graph/arrow-graph.d.ts.map +1 -0
- package/dist/graph/arrow-graph.js +513 -0
- package/dist/graph/arrow-graph.js.map +1 -0
- package/dist/graph/classic-graph.d.ts +169 -0
- package/dist/graph/classic-graph.d.ts.map +1 -0
- package/dist/graph/classic-graph.js +390 -0
- package/dist/graph/classic-graph.js.map +1 -0
- package/dist/graph/edge.d.ts +12 -12
- package/dist/graph/edge.d.ts.map +1 -1
- package/dist/graph/edge.js +3 -6
- package/dist/graph/edge.js.map +1 -1
- package/dist/graph/functions/arrow-utils.d.ts +6 -0
- package/dist/graph/functions/arrow-utils.d.ts.map +1 -0
- package/dist/graph/functions/arrow-utils.js +67 -0
- package/dist/graph/functions/arrow-utils.js.map +1 -0
- package/dist/graph/functions/create-graph-from-data.d.ts +3 -0
- package/dist/graph/functions/create-graph-from-data.d.ts.map +1 -0
- package/dist/graph/functions/create-graph-from-data.js +12 -0
- package/dist/graph/functions/create-graph-from-data.js.map +1 -0
- package/dist/graph/graph-normalization.d.ts +10 -0
- package/dist/graph/graph-normalization.d.ts.map +1 -0
- package/dist/graph/graph-normalization.js +65 -0
- package/dist/graph/graph-normalization.js.map +1 -0
- package/dist/graph/graph.d.ts +62 -156
- package/dist/graph/graph.d.ts.map +1 -1
- package/dist/graph/graph.js +11 -301
- package/dist/graph/graph.js.map +1 -1
- package/dist/graph/node.d.ts +12 -13
- package/dist/graph/node.d.ts.map +1 -1
- package/dist/graph/node.js +5 -7
- package/dist/graph/node.js.map +1 -1
- package/dist/graph-data/arrow-graph-data-builder.d.ts +21 -0
- package/dist/graph-data/arrow-graph-data-builder.d.ts.map +1 -0
- package/dist/graph-data/arrow-graph-data-builder.js +105 -0
- package/dist/graph-data/arrow-graph-data-builder.js.map +1 -0
- package/dist/graph-data/graph-data-builder.d.ts +6 -0
- package/dist/graph-data/graph-data-builder.d.ts.map +1 -0
- package/dist/graph-data/graph-data-builder.js +1 -0
- package/dist/graph-data/graph-data-builder.js.map +1 -0
- package/dist/graph-data/graph-data.d.ts +40 -0
- package/dist/graph-data/graph-data.d.ts.map +1 -0
- package/dist/graph-data/graph-data.js +11 -0
- package/dist/graph-data/graph-data.js.map +1 -0
- package/dist/graph-data/plain-graph-data-builder.d.ts +20 -0
- package/dist/graph-data/plain-graph-data-builder.d.ts.map +1 -0
- package/dist/graph-data/plain-graph-data-builder.js +105 -0
- package/dist/graph-data/plain-graph-data-builder.js.map +1 -0
- package/dist/graph-style-schema.cdn.d.ts +2 -0
- package/dist/graph-style-schema.cdn.js +2 -0
- package/dist/graph-style-schema.json +12 -0
- package/dist/index.cjs +7851 -3250
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +35 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +42 -25
- package/dist/index.js.map +1 -1
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-fragment.glsl.d.ts +0 -1
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-fragment.glsl.js +0 -1
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex-tf.glsl.d.ts +0 -1
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex-tf.glsl.js +0 -1
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex.glsl.d.ts +0 -1
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex.glsl.js +0 -1
- package/dist/layers/common-layers/flow-path-layer/flow-path-layer.d.ts +0 -1
- 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 +1 -3
- 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 +83 -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 +133 -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 +0 -1
- package/dist/layers/common-layers/marker-layer/atlas-data-url.js +0 -1
- package/dist/layers/common-layers/marker-layer/marker-layer.d.ts +0 -1
- package/dist/layers/common-layers/marker-layer/marker-layer.js +2 -3
- package/dist/layers/common-layers/marker-layer/marker-list.d.ts +2 -63
- package/dist/layers/common-layers/marker-layer/marker-list.d.ts.map +1 -1
- package/dist/layers/common-layers/marker-layer/marker-list.js +1 -65
- package/dist/layers/common-layers/marker-layer/marker-list.js.map +1 -1
- package/dist/layers/common-layers/marker-layer/marker-mapping.d.ts +0 -1
- package/dist/layers/common-layers/marker-layer/marker-mapping.js +0 -1
- package/dist/layers/common-layers/spline-layer/spline-layer.d.ts +0 -1
- package/dist/layers/common-layers/spline-layer/spline-layer.js +0 -1
- package/dist/layers/common-layers/zoomable-text-layer/zoomable-text-layer.d.ts +0 -1
- package/dist/layers/common-layers/zoomable-text-layer/zoomable-text-layer.js +0 -1
- package/dist/layers/edge-attachment-helper.d.ts +15 -0
- package/dist/layers/edge-attachment-helper.d.ts.map +1 -0
- package/dist/layers/edge-attachment-helper.js +229 -0
- package/dist/layers/edge-attachment-helper.js.map +1 -0
- package/dist/layers/edge-layer.d.ts +1 -5
- package/dist/layers/edge-layer.d.ts.map +1 -1
- package/dist/layers/edge-layer.js +9 -11
- package/dist/layers/edge-layer.js.map +1 -1
- package/dist/layers/edge-layers/arrow-2d-geometry.d.ts +4 -0
- package/dist/layers/edge-layers/arrow-2d-geometry.d.ts.map +1 -0
- package/dist/layers/edge-layers/arrow-2d-geometry.js +42 -0
- package/dist/layers/edge-layers/arrow-2d-geometry.js.map +1 -0
- package/dist/layers/edge-layers/curved-edge-layer.d.ts +1 -2
- package/dist/layers/edge-layers/curved-edge-layer.js +1 -2
- package/dist/layers/edge-layers/edge-arrow-layer.d.ts +21 -0
- package/dist/layers/edge-layers/edge-arrow-layer.d.ts.map +1 -0
- package/dist/layers/edge-layers/edge-arrow-layer.js +131 -0
- package/dist/layers/edge-layers/edge-arrow-layer.js.map +1 -0
- package/dist/layers/edge-layers/edge-label-layer.d.ts +1 -2
- package/dist/layers/edge-layers/edge-label-layer.js +1 -2
- package/dist/layers/edge-layers/flow-layer.d.ts +1 -2
- package/dist/layers/edge-layers/flow-layer.js +1 -2
- package/dist/layers/edge-layers/path-edge-layer.d.ts +0 -1
- package/dist/layers/edge-layers/path-edge-layer.js +0 -1
- package/dist/layers/edge-layers/straight-line-edge-layer.d.ts +0 -1
- package/dist/layers/edge-layers/straight-line-edge-layer.js +0 -1
- package/dist/layers/graph-layer.d.ts +85 -29
- package/dist/layers/graph-layer.d.ts.map +1 -1
- package/dist/layers/graph-layer.js +635 -94
- package/dist/layers/graph-layer.js.map +1 -1
- package/dist/layers/node-layers/circle-layer.d.ts +0 -1
- package/dist/layers/node-layers/circle-layer.js +0 -1
- package/dist/layers/node-layers/image-layer.d.ts +0 -1
- package/dist/layers/node-layers/image-layer.js +0 -1
- package/dist/layers/node-layers/label-layer.d.ts +1 -2
- package/dist/layers/node-layers/label-layer.js +1 -2
- package/dist/layers/node-layers/path-rounded-rectangle-layer.d.ts +0 -1
- package/dist/layers/node-layers/path-rounded-rectangle-layer.js +1 -2
- package/dist/layers/node-layers/rectangle-layer.d.ts +0 -1
- package/dist/layers/node-layers/rectangle-layer.js +0 -1
- package/dist/layers/node-layers/rounded-rectangle-layer-fragment.d.ts +0 -1
- package/dist/layers/node-layers/rounded-rectangle-layer-fragment.js +0 -1
- package/dist/layers/node-layers/rounded-rectangle-layer.d.ts +1 -2
- package/dist/layers/node-layers/rounded-rectangle-layer.js +2 -3
- package/dist/layers/node-layers/zoomable-marker-layer.d.ts +1 -2
- package/dist/layers/node-layers/zoomable-marker-layer.js +1 -2
- package/dist/layouts/d3-dag/collapsable-d3-dag-layout.d.ts +24 -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 +251 -0
- package/dist/layouts/d3-dag/collapsable-d3-dag-layout.js.map +1 -0
- package/dist/layouts/d3-dag/d3-dag-layout.d.ts +102 -0
- package/dist/layouts/d3-dag/d3-dag-layout.d.ts.map +1 -0
- package/dist/layouts/d3-dag/d3-dag-layout.js +531 -0
- package/dist/layouts/d3-dag/d3-dag-layout.js.map +1 -0
- package/dist/layouts/d3-force/d3-force-layout.d.ts +23 -11
- package/dist/layouts/d3-force/d3-force-layout.d.ts.map +1 -1
- package/dist/layouts/d3-force/d3-force-layout.js +63 -29
- package/dist/layouts/d3-force/d3-force-layout.js.map +1 -1
- package/dist/layouts/d3-force/worker.d.ts +0 -1
- package/dist/layouts/d3-force/worker.js +0 -1
- package/dist/layouts/experimental/force-multi-graph-layout.d.ts +25 -20
- package/dist/layouts/experimental/force-multi-graph-layout.d.ts.map +1 -1
- package/dist/layouts/experimental/force-multi-graph-layout.js +60 -47
- package/dist/layouts/experimental/force-multi-graph-layout.js.map +1 -1
- package/dist/layouts/experimental/hive-plot-layout.d.ts +26 -20
- package/dist/layouts/experimental/hive-plot-layout.d.ts.map +1 -1
- package/dist/layouts/experimental/hive-plot-layout.js +43 -39
- package/dist/layouts/experimental/hive-plot-layout.js.map +1 -1
- package/dist/layouts/experimental/radial-layout.d.ts +20 -12
- package/dist/layouts/experimental/radial-layout.d.ts.map +1 -1
- package/dist/layouts/experimental/radial-layout.js +41 -19
- package/dist/layouts/experimental/radial-layout.js.map +1 -1
- package/dist/layouts/gpu-force/gpu-force-layout.d.ts +15 -12
- package/dist/layouts/gpu-force/gpu-force-layout.d.ts.map +1 -1
- package/dist/layouts/gpu-force/gpu-force-layout.js +71 -59
- package/dist/layouts/gpu-force/gpu-force-layout.js.map +1 -1
- package/dist/layouts/gpu-force/worker.d.ts +0 -1
- package/dist/layouts/gpu-force/worker.js +0 -1
- package/dist/layouts/simple-layout.d.ts +21 -31
- package/dist/layouts/simple-layout.d.ts.map +1 -1
- package/dist/layouts/simple-layout.js +33 -26
- package/dist/layouts/simple-layout.js.map +1 -1
- package/dist/loaders/dot-graph-loader.d.ts +25 -0
- package/dist/loaders/dot-graph-loader.d.ts.map +1 -0
- package/dist/loaders/dot-graph-loader.js +668 -0
- package/dist/loaders/dot-graph-loader.js.map +1 -0
- package/dist/loaders/json-graph-loader.d.ts +6 -0
- package/dist/loaders/json-graph-loader.d.ts.map +1 -0
- package/dist/loaders/json-graph-loader.js +31 -0
- package/dist/loaders/json-graph-loader.js.map +1 -0
- package/dist/loaders/parsers/edge-parsers.d.ts +2 -0
- package/dist/loaders/parsers/edge-parsers.d.ts.map +1 -0
- package/dist/loaders/{edge-parsers.js → parsers/edge-parsers.js} +2 -3
- package/dist/loaders/parsers/edge-parsers.js.map +1 -0
- package/dist/loaders/parsers/node-parsers.d.ts +2 -0
- package/dist/loaders/parsers/node-parsers.d.ts.map +1 -0
- package/dist/loaders/{node-parsers.js → parsers/node-parsers.js} +2 -3
- package/dist/loaders/parsers/node-parsers.js.map +1 -0
- package/dist/loaders/parsers/parse-json-graph.d.ts +29 -0
- package/dist/loaders/parsers/parse-json-graph.d.ts.map +1 -0
- package/dist/loaders/parsers/parse-json-graph.js +78 -0
- package/dist/loaders/parsers/parse-json-graph.js.map +1 -0
- package/dist/style/graph-layer-stylesheet.d.ts +34 -0
- package/dist/style/graph-layer-stylesheet.d.ts.map +1 -0
- package/dist/style/graph-layer-stylesheet.js +39 -0
- package/dist/style/graph-layer-stylesheet.js.map +1 -0
- package/dist/style/graph-style-accessor-map.d.ts +93 -0
- package/dist/style/graph-style-accessor-map.d.ts.map +1 -0
- package/dist/style/graph-style-accessor-map.js +93 -0
- package/dist/style/graph-style-accessor-map.js.map +1 -0
- package/dist/style/graph-style-engine.d.ts +12 -0
- package/dist/style/graph-style-engine.d.ts.map +1 -0
- package/dist/style/graph-style-engine.js +164 -0
- package/dist/style/graph-style-engine.js.map +1 -0
- package/dist/style/graph-stylesheet.schema.d.ts +310 -0
- package/dist/style/graph-stylesheet.schema.d.ts.map +1 -0
- package/dist/style/graph-stylesheet.schema.js +237 -0
- package/dist/style/graph-stylesheet.schema.js.map +1 -0
- package/dist/style/style-property.d.ts +2 -3
- package/dist/style/style-property.d.ts.map +1 -1
- package/dist/style/style-property.js +224 -48
- package/dist/style/style-property.js.map +1 -1
- package/dist/style/stylesheet-engine.d.ts +33 -0
- package/dist/style/stylesheet-engine.d.ts.map +1 -0
- package/dist/style/stylesheet-engine.js +121 -0
- package/dist/style/stylesheet-engine.js.map +1 -0
- package/dist/utils/collapsed-chains.d.ts +17 -0
- package/dist/utils/collapsed-chains.d.ts.map +1 -0
- package/dist/utils/collapsed-chains.js +192 -0
- package/dist/utils/collapsed-chains.js.map +1 -0
- package/dist/utils/layer-utils.d.ts +0 -1
- package/dist/utils/layer-utils.d.ts.map +1 -1
- package/dist/utils/layer-utils.js +0 -1
- package/dist/utils/log.d.ts +2 -1
- package/dist/utils/log.d.ts.map +1 -1
- package/dist/utils/log.js +12 -2
- package/dist/utils/log.js.map +1 -1
- package/dist/utils/node-boundary.d.ts +10 -0
- package/dist/utils/node-boundary.d.ts.map +1 -0
- package/dist/utils/node-boundary.js +130 -0
- package/dist/utils/node-boundary.js.map +1 -0
- package/dist/utils/polygon-calculations.d.ts +0 -1
- package/dist/utils/polygon-calculations.js +0 -1
- package/dist/utils/rank-grid.d.ts +30 -0
- package/dist/utils/rank-grid.d.ts.map +1 -0
- package/dist/utils/rank-grid.js +306 -0
- package/dist/utils/rank-grid.js.map +1 -0
- package/package.json +25 -13
- package/src/_deprecated/old-constants.ts +122 -0
- 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/constants.ts +21 -43
- package/src/core/graph-engine.ts +212 -80
- package/src/core/graph-layout.ts +175 -47
- package/src/core/interaction-manager.ts +93 -33
- package/src/graph/arrow-graph.ts +648 -0
- package/src/graph/classic-graph.ts +447 -0
- package/src/graph/edge.ts +13 -13
- 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 +15 -15
- 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 +82 -17
- 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/common-layers/marker-layer/marker-list.ts +62 -64
- package/src/layers/edge-attachment-helper.ts +361 -0
- package/src/layers/edge-layer.ts +6 -7
- package/src/layers/edge-layers/arrow-2d-geometry.ts +51 -0
- package/src/layers/edge-layers/edge-arrow-layer.ts +171 -0
- package/src/layers/graph-layer.ts +928 -130
- package/src/layouts/d3-dag/collapsable-d3-dag-layout.ts +330 -0
- package/src/layouts/d3-dag/d3-dag-layout.ts +739 -0
- package/src/layouts/d3-force/d3-force-layout.ts +83 -39
- package/src/layouts/experimental/force-multi-graph-layout.ts +72 -57
- package/src/layouts/experimental/hive-plot-layout.ts +60 -49
- package/src/layouts/experimental/radial-layout.ts +57 -26
- package/src/layouts/gpu-force/gpu-force-layout.ts +86 -72
- package/src/layouts/simple-layout.ts +51 -52
- 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} +4 -4
- package/src/loaders/{table-graph-loader.ts → deprecated/table-graph-loader.ts.disabled} +9 -9
- 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} +3 -3
- package/src/loaders/{node-parsers.ts → parsers/node-parsers.ts} +3 -3
- package/src/loaders/parsers/parse-json-graph.ts +134 -0
- package/src/style/graph-layer-stylesheet.ts +99 -0
- package/src/style/graph-style-accessor-map.ts +103 -0
- package/src/style/graph-style-engine.ts +232 -0
- package/src/style/graph-stylesheet.schema.ts +344 -0
- package/src/style/style-property.ts +314 -51
- package/src/style/stylesheet-engine.ts +168 -0
- package/src/utils/collapsed-chains.ts +255 -0
- package/src/utils/log.ts +15 -1
- package/src/utils/node-boundary.ts +238 -0
- package/src/utils/rank-grid.ts +426 -0
- package/dist/loaders/create-graph.d.ts +0 -13
- package/dist/loaders/create-graph.d.ts.map +0 -1
- package/dist/loaders/create-graph.js +0 -39
- package/dist/loaders/create-graph.js.map +0 -1
- package/dist/loaders/edge-parsers.d.ts +0 -3
- 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 -8
- package/dist/loaders/json-loader.d.ts.map +0 -1
- package/dist/loaders/json-loader.js +0 -17
- package/dist/loaders/json-loader.js.map +0 -1
- package/dist/loaders/node-parsers.d.ts +0 -3
- 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 -12
- package/dist/loaders/simple-json-graph-loader.d.ts.map +0 -1
- package/dist/loaders/simple-json-graph-loader.js +0 -21
- package/dist/loaders/simple-json-graph-loader.js.map +0 -1
- package/dist/loaders/table-graph-loader.d.ts +0 -17
- package/dist/loaders/table-graph-loader.d.ts.map +0 -1
- package/dist/loaders/table-graph-loader.js +0 -92
- package/dist/loaders/table-graph-loader.js.map +0 -1
- package/dist/style/style-sheet.d.ts +0 -11
- package/dist/style/style-sheet.d.ts.map +0 -1
- package/dist/style/style-sheet.js +0 -253
- package/dist/style/style-sheet.js.map +0 -1
- package/dist/widgets/long-press-button.d.ts +0 -13
- package/dist/widgets/long-press-button.d.ts.map +0 -1
- package/dist/widgets/long-press-button.js +0 -32
- package/dist/widgets/long-press-button.js.map +0 -1
- package/dist/widgets/view-control-widget.d.ts +0 -78
- package/dist/widgets/view-control-widget.d.ts.map +0 -1
- package/dist/widgets/view-control-widget.js +0 -195
- package/dist/widgets/view-control-widget.js.map +0 -1
- package/src/loaders/json-loader.ts +0 -19
- package/src/style/style-sheet.ts +0 -277
- package/src/widgets/long-press-button.tsx +0 -50
- package/src/widgets/view-control-widget.tsx +0 -337
|
@@ -2,19 +2,30 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
+
/* eslint-disable no-continue */
|
|
6
|
+
|
|
5
7
|
import type {CompositeLayerProps} from '@deck.gl/core';
|
|
6
8
|
import {COORDINATE_SYSTEM, CompositeLayer} from '@deck.gl/core';
|
|
9
|
+
import {PolygonLayer} from '@deck.gl/layers';
|
|
7
10
|
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {GraphLayout} from '../core/graph-layout';
|
|
11
|
+
import type {Graph, NodeInterface} from '../graph/graph';
|
|
12
|
+
import {ClassicGraph} from '../graph/classic-graph';
|
|
13
|
+
import {GraphLayout, type GraphLayoutEventDetail} from '../core/graph-layout';
|
|
11
14
|
import {GraphEngine} from '../core/graph-engine';
|
|
12
15
|
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
import {
|
|
17
|
+
GraphStylesheetEngine,
|
|
18
|
+
type GraphStylesheet
|
|
19
|
+
} from '../style/graph-style-engine';
|
|
16
20
|
|
|
17
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
DEFAULT_GRAPH_LAYER_STYLESHEET,
|
|
23
|
+
normalizeGraphLayerStylesheet,
|
|
24
|
+
type GraphLayerEdgeStyle,
|
|
25
|
+
type GraphLayerNodeStyle,
|
|
26
|
+
type GraphLayerStylesheet,
|
|
27
|
+
type NormalizedGraphLayerStylesheet
|
|
28
|
+
} from '../style/graph-layer-stylesheet';
|
|
18
29
|
|
|
19
30
|
// node layers
|
|
20
31
|
import {CircleLayer} from './node-layers/circle-layer';
|
|
@@ -29,22 +40,49 @@ import {ZoomableMarkerLayer} from './node-layers/zoomable-marker-layer';
|
|
|
29
40
|
import {EdgeLayer} from './edge-layer';
|
|
30
41
|
import {EdgeLabelLayer} from './edge-layers/edge-label-layer';
|
|
31
42
|
import {FlowLayer} from './edge-layers/flow-layer';
|
|
43
|
+
import {EdgeArrowLayer} from './edge-layers/edge-arrow-layer';
|
|
44
|
+
import {EdgeAttachmentHelper} from './edge-attachment-helper';
|
|
45
|
+
import {GridLayer, type GridLayerProps} from './common-layers/grid-layer/grid-layer';
|
|
32
46
|
|
|
33
|
-
import {
|
|
47
|
+
import {JSONGraphLoader} from '../loaders/json-graph-loader';
|
|
48
|
+
|
|
49
|
+
import {mixedGetPosition} from '../utils/layer-utils';
|
|
50
|
+
import {InteractionManager} from '../core/interaction-manager';
|
|
51
|
+
import {buildCollapsedChainLayers} from '../utils/collapsed-chains';
|
|
52
|
+
import {
|
|
53
|
+
mapRanksToYPositions,
|
|
54
|
+
selectRankLines,
|
|
55
|
+
type LabelAccessor,
|
|
56
|
+
type RankAccessor
|
|
57
|
+
} from '../utils/rank-grid';
|
|
58
|
+
|
|
59
|
+
import {warn} from '../utils/log';
|
|
34
60
|
|
|
35
61
|
const NODE_LAYER_MAP = {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
62
|
+
'rectangle': RectangleLayer,
|
|
63
|
+
'rounded-rectangle': RoundedRectangleLayer,
|
|
64
|
+
'path-rounded-rectangle': PathBasedRoundedRectangleLayer,
|
|
65
|
+
'icon': ImageLayer,
|
|
66
|
+
'circle': CircleLayer,
|
|
67
|
+
'label': LabelLayer,
|
|
68
|
+
'marker': ZoomableMarkerLayer
|
|
43
69
|
};
|
|
44
70
|
|
|
45
71
|
const EDGE_DECORATOR_LAYER_MAP = {
|
|
46
|
-
|
|
47
|
-
|
|
72
|
+
'edge-label': EdgeLabelLayer,
|
|
73
|
+
'flow': FlowLayer,
|
|
74
|
+
'arrow': EdgeArrowLayer
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
type GridLayerOverrides = Partial<Omit<GridLayerProps, 'id' | 'data' | 'direction'>>;
|
|
78
|
+
|
|
79
|
+
export type RankGridConfig = {
|
|
80
|
+
enabled?: boolean;
|
|
81
|
+
direction?: 'horizontal' | 'vertical';
|
|
82
|
+
maxLines?: number;
|
|
83
|
+
rankAccessor?: RankAccessor;
|
|
84
|
+
labelAccessor?: LabelAccessor;
|
|
85
|
+
gridProps?: GridLayerOverrides;
|
|
48
86
|
};
|
|
49
87
|
|
|
50
88
|
const SHARED_LAYER_PROPS = {
|
|
@@ -54,22 +92,65 @@ const SHARED_LAYER_PROPS = {
|
|
|
54
92
|
}
|
|
55
93
|
};
|
|
56
94
|
|
|
57
|
-
|
|
95
|
+
const NODE_STYLE_DEPRECATION_MESSAGE =
|
|
96
|
+
'GraphLayer: `nodeStyle` has been replaced by `stylesheet.nodes` and will be removed in a future release.';
|
|
97
|
+
const EDGE_STYLE_DEPRECATION_MESSAGE =
|
|
98
|
+
'GraphLayer: `edgeStyle` has been replaced by `stylesheet.edges` and will be removed in a future release.';
|
|
99
|
+
|
|
100
|
+
const GRAPH_PROP_DEPRECATION_MESSAGE =
|
|
101
|
+
'GraphLayer: `graph` prop is deprecated. Pass graphs via the `data` prop instead.';
|
|
102
|
+
const LAYOUT_REQUIRED_MESSAGE =
|
|
103
|
+
'GraphLayer: `layout` must be provided when supplying raw graph data.';
|
|
104
|
+
|
|
105
|
+
let NODE_STYLE_DEPRECATION_WARNED = false;
|
|
106
|
+
let EDGE_STYLE_DEPRECATION_WARNED = false;
|
|
107
|
+
let GRAPH_PROP_DEPRECATION_WARNED = false;
|
|
108
|
+
let LAYOUT_REQUIRED_WARNED = false;
|
|
109
|
+
|
|
110
|
+
export type GraphLayerRawData = {
|
|
111
|
+
name?: string;
|
|
112
|
+
nodes?: unknown[] | null;
|
|
113
|
+
edges?: unknown[] | null;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export type GraphLayerDataInput =
|
|
117
|
+
| GraphEngine
|
|
118
|
+
| Graph
|
|
119
|
+
| GraphLayerRawData
|
|
120
|
+
| unknown[]
|
|
121
|
+
| string
|
|
122
|
+
| null;
|
|
123
|
+
|
|
124
|
+
export type GraphLayerProps = CompositeLayerProps &
|
|
125
|
+
_GraphLayerProps & {
|
|
126
|
+
data?: GraphLayerDataInput | Promise<GraphLayerDataInput>;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
type EngineResolutionFlags = {
|
|
130
|
+
force: boolean;
|
|
131
|
+
dataChanged: boolean;
|
|
132
|
+
layoutChanged: boolean;
|
|
133
|
+
graphChanged: boolean;
|
|
134
|
+
engineChanged: boolean;
|
|
135
|
+
loaderChanged: boolean;
|
|
136
|
+
};
|
|
58
137
|
|
|
59
138
|
export type _GraphLayerProps = {
|
|
60
139
|
graph?: Graph;
|
|
61
140
|
layout?: GraphLayout;
|
|
62
|
-
graphLoader?: (opts: {json:
|
|
141
|
+
graphLoader?: (opts: {json: unknown}) => Graph | null;
|
|
63
142
|
engine?: GraphEngine;
|
|
64
143
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
144
|
+
onLayoutStart?: (detail?: GraphLayoutEventDetail) => void;
|
|
145
|
+
onLayoutChange?: (detail?: GraphLayoutEventDetail) => void;
|
|
146
|
+
onLayoutDone?: (detail?: GraphLayoutEventDetail) => void;
|
|
147
|
+
onLayoutError?: (error?: unknown) => void;
|
|
148
|
+
|
|
149
|
+
stylesheet?: GraphLayerStylesheet;
|
|
150
|
+
/** @deprecated Use `stylesheet.nodes`. */
|
|
151
|
+
nodeStyle?: GraphLayerNodeStyle[];
|
|
152
|
+
/** @deprecated Use `stylesheet.edges`. */
|
|
153
|
+
edgeStyle?: GraphLayerEdgeStyle | GraphLayerEdgeStyle[];
|
|
73
154
|
nodeEvents?: {
|
|
74
155
|
onMouseLeave?: () => void;
|
|
75
156
|
onHover?: () => void;
|
|
@@ -82,20 +163,27 @@ export type _GraphLayerProps = {
|
|
|
82
163
|
onHover: () => void;
|
|
83
164
|
};
|
|
84
165
|
enableDragging?: boolean;
|
|
166
|
+
rankGrid?: boolean | RankGridConfig;
|
|
167
|
+
resumeLayoutAfterDragging?: boolean;
|
|
85
168
|
};
|
|
86
169
|
|
|
170
|
+
/** Composite layer that renders graph nodes, edges, and decorators. */
|
|
87
171
|
export class GraphLayer extends CompositeLayer<GraphLayerProps> {
|
|
88
172
|
static layerName = 'GraphLayer';
|
|
89
173
|
|
|
90
|
-
static defaultProps: Required<_GraphLayerProps>
|
|
174
|
+
static defaultProps: Required<_GraphLayerProps> & {
|
|
175
|
+
data: {type: string; value: null; async: true};
|
|
176
|
+
} = {
|
|
91
177
|
// Composite layer props
|
|
92
178
|
// @ts-expect-error composite layer props
|
|
93
179
|
pickable: true,
|
|
180
|
+
data: {type: 'object', value: null, async: true},
|
|
94
181
|
|
|
95
182
|
// Graph props
|
|
96
|
-
graphLoader:
|
|
183
|
+
graphLoader: JSONGraphLoader,
|
|
97
184
|
|
|
98
|
-
|
|
185
|
+
stylesheet: DEFAULT_GRAPH_LAYER_STYLESHEET,
|
|
186
|
+
nodeStyle: undefined as unknown as GraphLayerNodeStyle[],
|
|
99
187
|
nodeEvents: {
|
|
100
188
|
onMouseLeave: () => {},
|
|
101
189
|
onHover: () => {},
|
|
@@ -103,30 +191,35 @@ export class GraphLayer extends CompositeLayer<GraphLayerProps> {
|
|
|
103
191
|
onClick: () => {},
|
|
104
192
|
onDrag: () => {}
|
|
105
193
|
},
|
|
106
|
-
edgeStyle:
|
|
107
|
-
stroke: 'black',
|
|
108
|
-
strokeWidth: 1,
|
|
109
|
-
// an array of styles for layers
|
|
110
|
-
decorators: []
|
|
111
|
-
},
|
|
194
|
+
edgeStyle: undefined as unknown as GraphLayerEdgeStyle | GraphLayerEdgeStyle[],
|
|
112
195
|
edgeEvents: {
|
|
113
196
|
onClick: () => {},
|
|
114
197
|
onHover: () => {}
|
|
115
198
|
},
|
|
116
|
-
enableDragging: false
|
|
199
|
+
enableDragging: false,
|
|
200
|
+
rankGrid: false,
|
|
201
|
+
resumeLayoutAfterDragging: true
|
|
117
202
|
};
|
|
118
203
|
|
|
119
204
|
// @ts-expect-error Some typescript confusion due to override of base class state
|
|
120
205
|
state!: CompositeLayer<GraphLayerProps>['state'] & {
|
|
121
206
|
interactionManager: InteractionManager;
|
|
122
|
-
graphEngine?: GraphEngine;
|
|
207
|
+
graphEngine?: GraphEngine | null;
|
|
208
|
+
layoutVersion: number;
|
|
209
|
+
layoutState?: string;
|
|
210
|
+
interactionVersion: number;
|
|
123
211
|
};
|
|
124
212
|
|
|
213
|
+
private readonly _edgeAttachmentHelper = new EdgeAttachmentHelper();
|
|
214
|
+
private _suppressNextDeckDataChange = false;
|
|
215
|
+
|
|
125
216
|
forceUpdate = () => {
|
|
126
|
-
if (this.
|
|
127
|
-
|
|
128
|
-
this.setChangeFlags({dataChanged: true} as any); // TODO
|
|
217
|
+
if (!this.state) {
|
|
218
|
+
return;
|
|
129
219
|
}
|
|
220
|
+
|
|
221
|
+
this.setNeedsRedraw();
|
|
222
|
+
this.setState({interactionVersion: this.state.interactionVersion + 1});
|
|
130
223
|
};
|
|
131
224
|
|
|
132
225
|
constructor(props: GraphLayerProps & CompositeLayerProps) {
|
|
@@ -134,126 +227,669 @@ export class GraphLayer extends CompositeLayer<GraphLayerProps> {
|
|
|
134
227
|
}
|
|
135
228
|
|
|
136
229
|
initializeState() {
|
|
230
|
+
const interactionManager = new InteractionManager(
|
|
231
|
+
{
|
|
232
|
+
nodeEvents: this.props.nodeEvents,
|
|
233
|
+
edgeEvents: this.props.edgeEvents,
|
|
234
|
+
engine: undefined as any,
|
|
235
|
+
enableDragging: Boolean(this.props.enableDragging),
|
|
236
|
+
resumeLayoutAfterDragging: Boolean(
|
|
237
|
+
this.props.resumeLayoutAfterDragging ?? GraphLayer.defaultProps.resumeLayoutAfterDragging
|
|
238
|
+
)
|
|
239
|
+
},
|
|
240
|
+
() => this.forceUpdate()
|
|
241
|
+
);
|
|
242
|
+
|
|
137
243
|
this.state = {
|
|
138
|
-
interactionManager
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
244
|
+
interactionManager,
|
|
245
|
+
graphEngine: null,
|
|
246
|
+
layoutVersion: 0,
|
|
247
|
+
layoutState: undefined,
|
|
248
|
+
interactionVersion: 0
|
|
249
|
+
} as typeof this.state;
|
|
250
|
+
|
|
251
|
+
this._syncInteractionManager(this.props, null);
|
|
252
|
+
this._refreshEngineFromProps(this.props, {force: true});
|
|
142
253
|
}
|
|
143
254
|
|
|
144
255
|
shouldUpdateState({changeFlags}) {
|
|
145
|
-
return changeFlags.dataChanged || changeFlags.propsChanged;
|
|
256
|
+
return changeFlags.dataChanged || changeFlags.propsChanged || changeFlags.stateChanged;
|
|
146
257
|
}
|
|
147
258
|
|
|
148
259
|
updateState({props, oldProps, changeFlags}) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
260
|
+
const propsDataChanged = props.data !== oldProps.data;
|
|
261
|
+
const deckDataChanged =
|
|
262
|
+
changeFlags.dataChanged && !(this._suppressNextDeckDataChange && !propsDataChanged);
|
|
263
|
+
const dataChanged = deckDataChanged || propsDataChanged;
|
|
264
|
+
const layoutChanged = props.layout !== oldProps.layout;
|
|
265
|
+
const graphChanged = props.graph !== oldProps.graph;
|
|
266
|
+
const engineChanged = props.engine !== oldProps.engine;
|
|
267
|
+
const loaderChanged = props.graphLoader !== oldProps.graphLoader;
|
|
268
|
+
|
|
269
|
+
const engineRefreshed = this._refreshEngineFromProps(props, {
|
|
270
|
+
dataChanged,
|
|
271
|
+
layoutChanged,
|
|
272
|
+
graphChanged,
|
|
273
|
+
engineChanged,
|
|
274
|
+
loaderChanged
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
if (!engineRefreshed && changeFlags.propsChanged) {
|
|
278
|
+
const engine = this.state.graphEngine;
|
|
279
|
+
if (engine) {
|
|
280
|
+
this._applyGraphEngineCallbacks(engine);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (!engineRefreshed && (changeFlags.propsChanged || changeFlags.stateChanged)) {
|
|
285
|
+
this._syncInteractionManager(props, this.state.graphEngine ?? null);
|
|
166
286
|
}
|
|
287
|
+
|
|
288
|
+
this._suppressNextDeckDataChange = false;
|
|
167
289
|
}
|
|
168
290
|
|
|
169
291
|
finalize() {
|
|
170
292
|
this._removeGraphEngine();
|
|
293
|
+
this._syncInteractionManager(this.props, null);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
private _getResolvedStylesheet(): NormalizedGraphLayerStylesheet {
|
|
297
|
+
const {stylesheet, nodeStyle, edgeStyle} = this.props;
|
|
298
|
+
|
|
299
|
+
const usingNodeStyle = typeof nodeStyle !== 'undefined';
|
|
300
|
+
if (usingNodeStyle && !NODE_STYLE_DEPRECATION_WARNED) {
|
|
301
|
+
warn(NODE_STYLE_DEPRECATION_MESSAGE);
|
|
302
|
+
NODE_STYLE_DEPRECATION_WARNED = true;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const usingEdgeStyle = typeof edgeStyle !== 'undefined';
|
|
306
|
+
if (usingEdgeStyle && !EDGE_STYLE_DEPRECATION_WARNED) {
|
|
307
|
+
warn(EDGE_STYLE_DEPRECATION_MESSAGE);
|
|
308
|
+
EDGE_STYLE_DEPRECATION_WARNED = true;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return normalizeGraphLayerStylesheet({
|
|
312
|
+
stylesheet,
|
|
313
|
+
nodeStyle: usingNodeStyle ? nodeStyle : undefined,
|
|
314
|
+
edgeStyle: usingEdgeStyle ? edgeStyle : undefined
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
private _createStylesheetEngine(
|
|
319
|
+
style: GraphStylesheet,
|
|
320
|
+
context: string
|
|
321
|
+
): GraphStylesheetEngine | null {
|
|
322
|
+
try {
|
|
323
|
+
return new GraphStylesheetEngine(style, {
|
|
324
|
+
stateUpdateTrigger: (this.state.interactionManager as any).getLastInteraction()
|
|
325
|
+
});
|
|
326
|
+
} catch (error) {
|
|
327
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
328
|
+
warn(`GraphLayer: Failed to apply ${context}: ${message}`);
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
private _refreshEngineFromProps(
|
|
334
|
+
props: GraphLayerProps,
|
|
335
|
+
{
|
|
336
|
+
force = false,
|
|
337
|
+
dataChanged = false,
|
|
338
|
+
layoutChanged = false,
|
|
339
|
+
graphChanged = false,
|
|
340
|
+
engineChanged = false,
|
|
341
|
+
loaderChanged = false
|
|
342
|
+
}: {
|
|
343
|
+
force?: boolean;
|
|
344
|
+
dataChanged?: boolean;
|
|
345
|
+
layoutChanged?: boolean;
|
|
346
|
+
graphChanged?: boolean;
|
|
347
|
+
engineChanged?: boolean;
|
|
348
|
+
loaderChanged?: boolean;
|
|
349
|
+
}
|
|
350
|
+
): boolean {
|
|
351
|
+
const {engine: nextEngine, shouldReplace} = this._resolveEngineCandidate(props, {
|
|
352
|
+
force,
|
|
353
|
+
dataChanged,
|
|
354
|
+
layoutChanged,
|
|
355
|
+
graphChanged,
|
|
356
|
+
engineChanged,
|
|
357
|
+
loaderChanged
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
if (nextEngine === undefined) {
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const currentEngine = this.state.graphEngine ?? null;
|
|
365
|
+
if (!shouldReplace && nextEngine === currentEngine) {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
this._setGraphEngine(nextEngine);
|
|
370
|
+
this._syncInteractionManager(props, nextEngine);
|
|
371
|
+
return true;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
private _resolveEngineCandidate(
|
|
375
|
+
props: GraphLayerProps,
|
|
376
|
+
flags: EngineResolutionFlags
|
|
377
|
+
): {engine: GraphEngine | null | undefined; shouldReplace: boolean} {
|
|
378
|
+
const dataResult = this._getEngineFromData(props, flags);
|
|
379
|
+
if (dataResult) {
|
|
380
|
+
return dataResult;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const engineResult = this._getEngineFromEngineProp(props, flags);
|
|
384
|
+
if (engineResult) {
|
|
385
|
+
return engineResult;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const graphResult = this._getEngineFromGraphProp(props, flags);
|
|
389
|
+
if (graphResult) {
|
|
390
|
+
return graphResult;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (props.data === null || props.graph === null || props.engine === null || flags.force) {
|
|
394
|
+
return {engine: null, shouldReplace: true};
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return {engine: undefined, shouldReplace: flags.force};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
private _getEngineFromData(
|
|
401
|
+
props: GraphLayerProps,
|
|
402
|
+
{force, dataChanged, layoutChanged, loaderChanged}: EngineResolutionFlags
|
|
403
|
+
): {engine: GraphEngine | null | undefined; shouldReplace: boolean} | null {
|
|
404
|
+
const dataValue = props.data as GraphLayerDataInput | null | undefined;
|
|
405
|
+
if (dataValue === null || typeof dataValue === 'undefined') {
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const shouldRebuild = force || dataChanged || layoutChanged || loaderChanged;
|
|
410
|
+
if (!shouldRebuild) {
|
|
411
|
+
return {engine: undefined, shouldReplace: false};
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const engine = this._deriveEngineFromData(dataValue, props);
|
|
415
|
+
if (typeof engine === 'undefined') {
|
|
416
|
+
return {engine: undefined, shouldReplace: false};
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return {
|
|
420
|
+
engine,
|
|
421
|
+
shouldReplace: true
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
private _getEngineFromEngineProp(
|
|
426
|
+
props: GraphLayerProps,
|
|
427
|
+
{force, engineChanged}: EngineResolutionFlags
|
|
428
|
+
): {engine: GraphEngine | null | undefined; shouldReplace: boolean} | null {
|
|
429
|
+
if (typeof props.engine === 'undefined') {
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (props.engine === null) {
|
|
434
|
+
return {engine: null, shouldReplace: true};
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return {
|
|
438
|
+
engine: props.engine,
|
|
439
|
+
shouldReplace: force || engineChanged
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
private _getEngineFromGraphProp(
|
|
444
|
+
props: GraphLayerProps,
|
|
445
|
+
{force, graphChanged, layoutChanged}: EngineResolutionFlags
|
|
446
|
+
): {engine: GraphEngine | null | undefined; shouldReplace: boolean} | null {
|
|
447
|
+
if (typeof props.graph === 'undefined') {
|
|
448
|
+
return null;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (props.graph === null) {
|
|
452
|
+
return {engine: null, shouldReplace: true};
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
this._warnGraphProp();
|
|
456
|
+
return {
|
|
457
|
+
engine: this._buildEngineFromGraph(props.graph, props.layout),
|
|
458
|
+
shouldReplace: force || graphChanged || layoutChanged
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
private _deriveEngineFromData(
|
|
463
|
+
data: GraphLayerDataInput,
|
|
464
|
+
props: GraphLayerProps
|
|
465
|
+
): GraphEngine | null | undefined {
|
|
466
|
+
if (data === null || typeof data === 'undefined') {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
if (typeof (data as PromiseLike<GraphLayerDataInput>)?.then === 'function') {
|
|
471
|
+
return undefined;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
if (data instanceof GraphEngine) {
|
|
475
|
+
return data;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const graphCandidate = this._coerceGraph(data);
|
|
479
|
+
if (graphCandidate) {
|
|
480
|
+
return this._buildEngineFromGraph(graphCandidate, props.layout);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
if (typeof data === 'string') {
|
|
484
|
+
return undefined;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if (Array.isArray(data) || isPlainObject(data)) {
|
|
488
|
+
const loader = props.graphLoader ?? JSONGraphLoader;
|
|
489
|
+
const graph = loader({json: data});
|
|
490
|
+
if (!graph) {
|
|
491
|
+
return null;
|
|
492
|
+
}
|
|
493
|
+
return this._buildEngineFromGraph(graph, props.layout);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
return null;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
private _buildEngineFromGraph(
|
|
500
|
+
graph: Graph | null,
|
|
501
|
+
layout?: GraphLayout | null
|
|
502
|
+
): GraphEngine | null {
|
|
503
|
+
if (!graph) {
|
|
504
|
+
return null;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
if (!layout) {
|
|
508
|
+
this._warnLayoutRequired();
|
|
509
|
+
return null;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
if (graph instanceof ClassicGraph && layout instanceof GraphLayout) {
|
|
513
|
+
return new GraphEngine({graph, layout});
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
if (layout instanceof GraphLayout && !(graph instanceof ClassicGraph)) {
|
|
517
|
+
const legacyGraph = this._convertToClassicGraph(graph);
|
|
518
|
+
if (legacyGraph) {
|
|
519
|
+
return new GraphEngine({graph: legacyGraph, layout});
|
|
520
|
+
}
|
|
521
|
+
this._warnLayoutRequired();
|
|
522
|
+
return null;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
if (layout) {
|
|
526
|
+
return new GraphEngine({graph, layout});
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
this._warnLayoutRequired();
|
|
530
|
+
return null;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
private _syncInteractionManager(props: GraphLayerProps, engine: GraphEngine | null) {
|
|
534
|
+
const resumeLayoutAfterDragging =
|
|
535
|
+
props.resumeLayoutAfterDragging ?? GraphLayer.defaultProps.resumeLayoutAfterDragging;
|
|
536
|
+
|
|
537
|
+
this.state.interactionManager.updateProps({
|
|
538
|
+
nodeEvents: props.nodeEvents ?? GraphLayer.defaultProps.nodeEvents,
|
|
539
|
+
edgeEvents: props.edgeEvents ?? GraphLayer.defaultProps.edgeEvents,
|
|
540
|
+
engine: (engine ?? props.engine ?? null) as any,
|
|
541
|
+
enableDragging: Boolean(props.enableDragging),
|
|
542
|
+
resumeLayoutAfterDragging: Boolean(resumeLayoutAfterDragging)
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
private _warnGraphProp() {
|
|
547
|
+
if (!GRAPH_PROP_DEPRECATION_WARNED) {
|
|
548
|
+
warn(GRAPH_PROP_DEPRECATION_MESSAGE);
|
|
549
|
+
GRAPH_PROP_DEPRECATION_WARNED = true;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
private _warnLayoutRequired() {
|
|
554
|
+
if (!LAYOUT_REQUIRED_WARNED) {
|
|
555
|
+
warn(LAYOUT_REQUIRED_MESSAGE);
|
|
556
|
+
LAYOUT_REQUIRED_WARNED = true;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
private _isGraph(value: unknown): value is Graph {
|
|
561
|
+
if (!value || typeof value !== 'object') {
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
const candidate = value as Graph;
|
|
566
|
+
return (
|
|
567
|
+
typeof candidate.getNodes === 'function' && typeof candidate.getEdges === 'function'
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
private _coerceGraph(value: unknown): Graph | null {
|
|
572
|
+
if (value instanceof ClassicGraph) {
|
|
573
|
+
return value;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
if (this._isGraph(value)) {
|
|
577
|
+
return value;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
return null;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
private _convertToClassicGraph(graph: Graph): ClassicGraph | null {
|
|
584
|
+
if (graph instanceof ClassicGraph) {
|
|
585
|
+
return graph;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
const candidate = graph as Graph & {toClassicGraph?: () => ClassicGraph | null};
|
|
589
|
+
if (typeof candidate.toClassicGraph === 'function') {
|
|
590
|
+
try {
|
|
591
|
+
return candidate.toClassicGraph() ?? null;
|
|
592
|
+
} catch (error) {
|
|
593
|
+
warn('GraphLayer: failed to convert graph to ClassicGraph for layout compatibility.', error);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
return null;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
private _updateLayoutSnapshot(engine?: GraphEngine | null) {
|
|
601
|
+
const activeEngine = engine ?? this.state.graphEngine ?? null;
|
|
602
|
+
|
|
603
|
+
if (!activeEngine) {
|
|
604
|
+
if (this.state.layoutVersion !== 0 || typeof this.state.layoutState !== 'undefined') {
|
|
605
|
+
this._suppressNextDeckDataChange = true;
|
|
606
|
+
this.setState({layoutVersion: 0, layoutState: undefined});
|
|
607
|
+
}
|
|
608
|
+
this.setNeedsRedraw();
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
const nextVersion = activeEngine.getLayoutLastUpdate();
|
|
613
|
+
const nextState = activeEngine.getLayoutState();
|
|
614
|
+
|
|
615
|
+
if (this.state.layoutVersion !== nextVersion || this.state.layoutState !== nextState) {
|
|
616
|
+
this._suppressNextDeckDataChange = true;
|
|
617
|
+
this.setState({layoutVersion: nextVersion, layoutState: nextState});
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
this.setNeedsRedraw();
|
|
171
621
|
}
|
|
172
622
|
|
|
173
|
-
|
|
623
|
+
private _handleLayoutEvent = () => {
|
|
624
|
+
this._updateLayoutSnapshot();
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
_setGraphEngine(graphEngine: GraphEngine | null) {
|
|
174
628
|
if (graphEngine === this.state.graphEngine) {
|
|
629
|
+
if (graphEngine) {
|
|
630
|
+
this._applyGraphEngineCallbacks(graphEngine);
|
|
631
|
+
}
|
|
632
|
+
this._updateLayoutSnapshot(graphEngine);
|
|
175
633
|
return;
|
|
176
634
|
}
|
|
177
635
|
|
|
178
636
|
this._removeGraphEngine();
|
|
637
|
+
|
|
179
638
|
if (graphEngine) {
|
|
180
639
|
this.state.graphEngine = graphEngine;
|
|
181
|
-
this.
|
|
182
|
-
|
|
183
|
-
this.
|
|
640
|
+
this._applyGraphEngineCallbacks(graphEngine);
|
|
641
|
+
graphEngine.run();
|
|
642
|
+
this._updateLayoutSnapshot(graphEngine);
|
|
643
|
+
} else {
|
|
644
|
+
this.state.graphEngine = null;
|
|
645
|
+
this._updateLayoutSnapshot(null);
|
|
184
646
|
}
|
|
185
647
|
}
|
|
186
648
|
|
|
187
649
|
_removeGraphEngine() {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
650
|
+
const engine = this.state.graphEngine;
|
|
651
|
+
if (engine) {
|
|
652
|
+
engine.setProps({
|
|
653
|
+
onLayoutStart: undefined,
|
|
654
|
+
onLayoutChange: undefined,
|
|
655
|
+
onLayoutDone: undefined,
|
|
656
|
+
onLayoutError: undefined
|
|
657
|
+
});
|
|
658
|
+
engine.clear();
|
|
191
659
|
this.state.graphEngine = null;
|
|
660
|
+
this._updateLayoutSnapshot(null);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
private _applyGraphEngineCallbacks(engine: GraphEngine) {
|
|
665
|
+
engine.setProps({
|
|
666
|
+
onLayoutStart: (detail) => {
|
|
667
|
+
this._handleLayoutEvent();
|
|
668
|
+
this.props.onLayoutStart?.(detail);
|
|
669
|
+
},
|
|
670
|
+
onLayoutChange: (detail) => {
|
|
671
|
+
this._handleLayoutEvent();
|
|
672
|
+
this.props.onLayoutChange?.(detail);
|
|
673
|
+
},
|
|
674
|
+
onLayoutDone: (detail) => {
|
|
675
|
+
this._handleLayoutEvent();
|
|
676
|
+
this.props.onLayoutDone?.(detail);
|
|
677
|
+
},
|
|
678
|
+
onLayoutError: (error) => {
|
|
679
|
+
this._handleLayoutEvent();
|
|
680
|
+
this.props.onLayoutError?.(error);
|
|
681
|
+
}
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
private _createRankGridLayer(): GridLayer | null {
|
|
686
|
+
const engine = this.state.graphEngine;
|
|
687
|
+
if (!engine) {
|
|
688
|
+
return null;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
const {enabled, config} = this._normalizeRankGridConfig(this.props.rankGrid);
|
|
692
|
+
if (!enabled) {
|
|
693
|
+
return null;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
const bounds = this._resolveRankGridBounds(engine);
|
|
697
|
+
if (!bounds) {
|
|
698
|
+
return null;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
const data = this._buildRankGridData(engine, config, bounds);
|
|
702
|
+
if (!data) {
|
|
703
|
+
return null;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
const direction = config?.direction ?? 'horizontal';
|
|
707
|
+
const gridProps = config?.gridProps ?? {};
|
|
708
|
+
|
|
709
|
+
return new GridLayer({
|
|
710
|
+
id: `${this.props.id}-rank-grid`,
|
|
711
|
+
data,
|
|
712
|
+
direction,
|
|
713
|
+
xMin: bounds.xMin,
|
|
714
|
+
xMax: bounds.xMax,
|
|
715
|
+
yMin: bounds.yMin,
|
|
716
|
+
yMax: bounds.yMax,
|
|
717
|
+
pickable: false,
|
|
718
|
+
...gridProps
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
private _normalizeRankGridConfig(
|
|
723
|
+
value: GraphLayerProps['rankGrid']
|
|
724
|
+
): {enabled: boolean; config?: RankGridConfig} {
|
|
725
|
+
if (typeof value === 'boolean') {
|
|
726
|
+
return {enabled: value};
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
if (value && typeof value === 'object') {
|
|
730
|
+
return {enabled: value.enabled ?? true, config: value};
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
return {enabled: false};
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
private _resolveRankGridBounds(engine: GraphEngine):
|
|
737
|
+
| {xMin: number; xMax: number; yMin: number; yMax: number}
|
|
738
|
+
| null {
|
|
739
|
+
const bounds = engine.getLayoutBounds();
|
|
740
|
+
if (!bounds) {
|
|
741
|
+
return null;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
const [[minXRaw, minYRaw], [maxXRaw, maxYRaw]] = bounds;
|
|
745
|
+
const values = [minXRaw, minYRaw, maxXRaw, maxYRaw];
|
|
746
|
+
if (!values.every((value) => typeof value === 'number' && Number.isFinite(value))) {
|
|
747
|
+
return null;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
return {
|
|
751
|
+
xMin: Math.min(minXRaw, maxXRaw),
|
|
752
|
+
xMax: Math.max(minXRaw, maxXRaw),
|
|
753
|
+
yMin: Math.min(minYRaw, maxYRaw),
|
|
754
|
+
yMax: Math.max(minYRaw, maxYRaw)
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
private _buildRankGridData(
|
|
759
|
+
engine: GraphEngine,
|
|
760
|
+
config: RankGridConfig | undefined,
|
|
761
|
+
bounds: {yMin: number; yMax: number}
|
|
762
|
+
): Array<{label: string; rank: number; originalLabel?: string | number; yPosition: number}> | null {
|
|
763
|
+
const rankLabelPrefix = this._resolveRankFieldLabel(config?.rankAccessor);
|
|
764
|
+
// @ts-ignore iterator type
|
|
765
|
+
const rankPositions = mapRanksToYPositions(engine.getNodes(), engine.getNodePosition, {
|
|
766
|
+
rankAccessor: config?.rankAccessor,
|
|
767
|
+
labelAccessor: config?.labelAccessor,
|
|
768
|
+
yRange: {min: bounds.yMin, max: bounds.yMax}
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
if (rankPositions.length === 0) {
|
|
772
|
+
return null;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
const selectedRanks = selectRankLines(rankPositions, {
|
|
776
|
+
yMin: bounds.yMin,
|
|
777
|
+
yMax: bounds.yMax,
|
|
778
|
+
maxCount: config?.maxLines ?? 8
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
if (selectedRanks.length === 0) {
|
|
782
|
+
return null;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
return selectedRanks.map(({rank, label, yPosition}) => ({
|
|
786
|
+
label: `${rankLabelPrefix} ${rank}`,
|
|
787
|
+
rank,
|
|
788
|
+
originalLabel: label === undefined ? undefined : label,
|
|
789
|
+
yPosition
|
|
790
|
+
}));
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
private _resolveRankFieldLabel(rankAccessor: RankAccessor | undefined): string {
|
|
794
|
+
if (!rankAccessor) {
|
|
795
|
+
return 'srank';
|
|
796
|
+
}
|
|
797
|
+
if (typeof rankAccessor === 'string' && rankAccessor.length > 0) {
|
|
798
|
+
return rankAccessor;
|
|
799
|
+
}
|
|
800
|
+
if (typeof rankAccessor === 'function' && rankAccessor.name) {
|
|
801
|
+
return rankAccessor.name;
|
|
192
802
|
}
|
|
803
|
+
return 'rank';
|
|
193
804
|
}
|
|
194
805
|
|
|
195
806
|
createNodeLayers() {
|
|
196
807
|
const engine = this.state.graphEngine;
|
|
197
|
-
const {
|
|
198
|
-
|
|
808
|
+
const {nodes: nodeStyles} = this._getResolvedStylesheet();
|
|
809
|
+
|
|
810
|
+
if (!engine || !Array.isArray(nodeStyles) || nodeStyles.length === 0) {
|
|
199
811
|
return [];
|
|
200
812
|
}
|
|
201
813
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
814
|
+
const baseLayers = nodeStyles
|
|
815
|
+
.filter(Boolean)
|
|
816
|
+
.map((style, idx) => {
|
|
817
|
+
const {pickable = true, visible = true, data = (nodes) => nodes, ...restStyle} = style;
|
|
818
|
+
const LayerType = NODE_LAYER_MAP[style.type];
|
|
819
|
+
if (!LayerType) {
|
|
820
|
+
warn(`GraphLayer: Invalid node type "${style.type}".`);
|
|
821
|
+
return null;
|
|
822
|
+
}
|
|
823
|
+
const stylesheet = this._createStylesheetEngine(
|
|
824
|
+
restStyle as unknown as GraphStylesheet,
|
|
825
|
+
`node stylesheet "${style.type}"`
|
|
826
|
+
);
|
|
827
|
+
if (!stylesheet) {
|
|
828
|
+
return null;
|
|
829
|
+
}
|
|
830
|
+
const getOffset = stylesheet.getDeckGLAccessor('getOffset');
|
|
831
|
+
return new LayerType({
|
|
832
|
+
...SHARED_LAYER_PROPS,
|
|
833
|
+
id: `node-rule-${idx}`,
|
|
834
|
+
data: data(engine.getNodes()),
|
|
835
|
+
getPosition: mixedGetPosition(engine.getNodePosition, getOffset),
|
|
836
|
+
pickable,
|
|
837
|
+
positionUpdateTrigger: [
|
|
838
|
+
engine.getLayoutLastUpdate(),
|
|
839
|
+
engine.getLayoutState(),
|
|
840
|
+
stylesheet.getDeckGLAccessorUpdateTrigger('getOffset')
|
|
841
|
+
].join(),
|
|
842
|
+
stylesheet,
|
|
843
|
+
visible
|
|
844
|
+
} as any);
|
|
845
|
+
})
|
|
846
|
+
.filter(Boolean) as any[];
|
|
847
|
+
|
|
848
|
+
const chainLayers = this._createChainOverlayLayers(engine);
|
|
849
|
+
|
|
850
|
+
return [...baseLayers, ...chainLayers];
|
|
228
851
|
}
|
|
229
852
|
|
|
230
853
|
createEdgeLayers() {
|
|
231
854
|
const engine = this.state.graphEngine;
|
|
232
|
-
const {
|
|
855
|
+
const {edges: edgeStyles, nodes: nodeStyles} = this._getResolvedStylesheet();
|
|
856
|
+
|
|
857
|
+
if (!engine || !edgeStyles) {
|
|
858
|
+
return [];
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
const edgeStyleArray = Array.isArray(edgeStyles) ? edgeStyles : [edgeStyles];
|
|
233
862
|
|
|
234
|
-
if (
|
|
863
|
+
if (edgeStyleArray.length === 0) {
|
|
235
864
|
return [];
|
|
236
865
|
}
|
|
237
866
|
|
|
238
|
-
|
|
867
|
+
const getLayoutInfo = this._edgeAttachmentHelper.getLayoutAccessor({
|
|
868
|
+
engine,
|
|
869
|
+
interactionManager: this.state.interactionManager,
|
|
870
|
+
nodeStyle: nodeStyles
|
|
871
|
+
});
|
|
872
|
+
|
|
873
|
+
return edgeStyleArray
|
|
239
874
|
.filter(Boolean)
|
|
240
875
|
.flatMap((style, idx) => {
|
|
241
876
|
const {decorators, data = (edges) => edges, visible = true, ...restEdgeStyle} = style;
|
|
242
|
-
const stylesheet =
|
|
877
|
+
const stylesheet = this._createStylesheetEngine(
|
|
243
878
|
{
|
|
244
|
-
type: '
|
|
879
|
+
type: 'edge',
|
|
245
880
|
...restEdgeStyle
|
|
246
|
-
},
|
|
247
|
-
|
|
248
|
-
stateUpdateTrigger: (this.state.interactionManager as any).getLastInteraction()
|
|
249
|
-
}
|
|
881
|
+
} as GraphStylesheet,
|
|
882
|
+
'edge stylesheet'
|
|
250
883
|
);
|
|
884
|
+
if (!stylesheet) {
|
|
885
|
+
return [];
|
|
886
|
+
}
|
|
251
887
|
|
|
252
888
|
const edgeLayer = new EdgeLayer({
|
|
253
889
|
...SHARED_LAYER_PROPS,
|
|
254
890
|
id: `edge-layer-${idx}`,
|
|
255
891
|
data: data(engine.getEdges()),
|
|
256
|
-
getLayoutInfo
|
|
892
|
+
getLayoutInfo,
|
|
257
893
|
pickable: true,
|
|
258
894
|
positionUpdateTrigger: [engine.getLayoutLastUpdate(), engine.getLayoutState()].join(),
|
|
259
895
|
stylesheet,
|
|
@@ -261,28 +897,38 @@ export class GraphLayer extends CompositeLayer<GraphLayerProps> {
|
|
|
261
897
|
} as any);
|
|
262
898
|
|
|
263
899
|
if (!decorators || !Array.isArray(decorators) || decorators.length === 0) {
|
|
264
|
-
return edgeLayer;
|
|
900
|
+
return [edgeLayer];
|
|
265
901
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
902
|
+
|
|
903
|
+
const decoratorLayers = decorators
|
|
904
|
+
.filter(Boolean)
|
|
905
|
+
// @ts-ignore eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
906
|
+
.map((decoratorStyle, idx2) => {
|
|
907
|
+
const DecoratorLayer = EDGE_DECORATOR_LAYER_MAP[decoratorStyle.type];
|
|
908
|
+
if (!DecoratorLayer) {
|
|
909
|
+
warn(`GraphLayer: Invalid edge decorator type "${decoratorStyle.type}".`);
|
|
910
|
+
return null;
|
|
911
|
+
}
|
|
912
|
+
const decoratorStylesheet = this._createStylesheetEngine(
|
|
913
|
+
decoratorStyle as unknown as GraphStylesheet,
|
|
914
|
+
`edge decorator stylesheet "${decoratorStyle.type}"`
|
|
915
|
+
);
|
|
916
|
+
if (!decoratorStylesheet) {
|
|
917
|
+
return null;
|
|
918
|
+
}
|
|
919
|
+
return new DecoratorLayer({
|
|
920
|
+
...SHARED_LAYER_PROPS,
|
|
921
|
+
id: `edge-decorator-${idx2}`,
|
|
922
|
+
data: data(engine.getEdges()),
|
|
923
|
+
getLayoutInfo,
|
|
924
|
+
pickable: true,
|
|
925
|
+
positionUpdateTrigger: [engine.getLayoutLastUpdate(), engine.getLayoutState()].join(),
|
|
926
|
+
stylesheet: decoratorStylesheet
|
|
927
|
+
} as any);
|
|
928
|
+
})
|
|
929
|
+
.filter(Boolean);
|
|
930
|
+
|
|
931
|
+
return [edgeLayer, ...decoratorLayers];
|
|
286
932
|
});
|
|
287
933
|
}
|
|
288
934
|
|
|
@@ -307,6 +953,158 @@ export class GraphLayer extends CompositeLayer<GraphLayerProps> {
|
|
|
307
953
|
}
|
|
308
954
|
|
|
309
955
|
renderLayers() {
|
|
310
|
-
|
|
956
|
+
const layers: any[] = [];
|
|
957
|
+
const gridLayer = this._createRankGridLayer();
|
|
958
|
+
if (gridLayer) {
|
|
959
|
+
layers.push(gridLayer);
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
const edgeLayers = this.createEdgeLayers();
|
|
963
|
+
if (Array.isArray(edgeLayers) && edgeLayers.length > 0) {
|
|
964
|
+
layers.push(...edgeLayers);
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
const nodeLayers = this.createNodeLayers();
|
|
968
|
+
if (Array.isArray(nodeLayers) && nodeLayers.length > 0) {
|
|
969
|
+
layers.push(...nodeLayers);
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
return layers;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
private _createChainOverlayLayers(engine: GraphEngine) {
|
|
976
|
+
const chainData = buildCollapsedChainLayers(engine);
|
|
977
|
+
if (!chainData) {
|
|
978
|
+
return [];
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
const {
|
|
982
|
+
collapsedNodes,
|
|
983
|
+
collapsedOutlineNodes,
|
|
984
|
+
expandedNodes,
|
|
985
|
+
expandedOutlineNodes,
|
|
986
|
+
getChainOutlinePolygon,
|
|
987
|
+
outlineUpdateTrigger
|
|
988
|
+
} = chainData;
|
|
989
|
+
|
|
990
|
+
const layers: any[] = [];
|
|
991
|
+
|
|
992
|
+
if (collapsedOutlineNodes.length > 0) {
|
|
993
|
+
layers.push(
|
|
994
|
+
new PolygonLayer({
|
|
995
|
+
...SHARED_LAYER_PROPS,
|
|
996
|
+
id: 'collapsed-chain-outlines',
|
|
997
|
+
data: collapsedOutlineNodes,
|
|
998
|
+
getPolygon: (node: NodeInterface) => getChainOutlinePolygon(node),
|
|
999
|
+
stroked: true,
|
|
1000
|
+
filled: false,
|
|
1001
|
+
getLineColor: [220, 64, 64, 220],
|
|
1002
|
+
getLineWidth: 2,
|
|
1003
|
+
lineWidthUnits: 'pixels',
|
|
1004
|
+
lineWidthMinPixels: 2,
|
|
1005
|
+
pickable: true,
|
|
1006
|
+
updateTriggers: {
|
|
1007
|
+
getPolygon: [outlineUpdateTrigger]
|
|
1008
|
+
}
|
|
1009
|
+
})
|
|
1010
|
+
);
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
const collapsedMarkerStylesheet = this._createStylesheetEngine(
|
|
1014
|
+
{
|
|
1015
|
+
type: 'marker',
|
|
1016
|
+
fill: [64, 96, 192, 255],
|
|
1017
|
+
size: 32,
|
|
1018
|
+
marker: 'circle-plus-filled',
|
|
1019
|
+
offset: [24, -24],
|
|
1020
|
+
scaleWithZoom: false
|
|
1021
|
+
} as GraphStylesheet<'marker'>,
|
|
1022
|
+
'collapsed chain marker stylesheet'
|
|
1023
|
+
);
|
|
1024
|
+
|
|
1025
|
+
if (collapsedMarkerStylesheet && collapsedNodes.length > 0) {
|
|
1026
|
+
const getOffset = collapsedMarkerStylesheet.getDeckGLAccessor('getOffset');
|
|
1027
|
+
layers.push(
|
|
1028
|
+
new ZoomableMarkerLayer({
|
|
1029
|
+
...SHARED_LAYER_PROPS,
|
|
1030
|
+
id: 'collapsed-chain-markers',
|
|
1031
|
+
data: collapsedNodes,
|
|
1032
|
+
getPosition: mixedGetPosition(engine.getNodePosition, getOffset),
|
|
1033
|
+
pickable: true,
|
|
1034
|
+
positionUpdateTrigger: [
|
|
1035
|
+
engine.getLayoutLastUpdate(),
|
|
1036
|
+
engine.getLayoutState(),
|
|
1037
|
+
collapsedMarkerStylesheet.getDeckGLAccessorUpdateTrigger('getOffset')
|
|
1038
|
+
].join(),
|
|
1039
|
+
stylesheet: collapsedMarkerStylesheet,
|
|
1040
|
+
visible: true
|
|
1041
|
+
} as any)
|
|
1042
|
+
);
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
if (expandedOutlineNodes.length > 0) {
|
|
1046
|
+
layers.push(
|
|
1047
|
+
new PolygonLayer({
|
|
1048
|
+
...SHARED_LAYER_PROPS,
|
|
1049
|
+
id: 'expanded-chain-outlines',
|
|
1050
|
+
data: expandedOutlineNodes,
|
|
1051
|
+
getPolygon: (node: NodeInterface) => getChainOutlinePolygon(node),
|
|
1052
|
+
stroked: true,
|
|
1053
|
+
filled: false,
|
|
1054
|
+
getLineColor: [64, 96, 192, 200],
|
|
1055
|
+
getLineWidth: 2,
|
|
1056
|
+
lineWidthUnits: 'pixels',
|
|
1057
|
+
lineWidthMinPixels: 2,
|
|
1058
|
+
pickable: true,
|
|
1059
|
+
updateTriggers: {
|
|
1060
|
+
getPolygon: [outlineUpdateTrigger]
|
|
1061
|
+
}
|
|
1062
|
+
})
|
|
1063
|
+
);
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
const expandedMarkerStylesheet = this._createStylesheetEngine(
|
|
1067
|
+
{
|
|
1068
|
+
type: 'marker',
|
|
1069
|
+
fill: [64, 96, 192, 255],
|
|
1070
|
+
size: 32,
|
|
1071
|
+
marker: 'circle-minus-filled',
|
|
1072
|
+
offset: [24, -24],
|
|
1073
|
+
scaleWithZoom: false
|
|
1074
|
+
} as GraphStylesheet<'marker'>,
|
|
1075
|
+
'expanded chain marker stylesheet'
|
|
1076
|
+
);
|
|
1077
|
+
|
|
1078
|
+
if (expandedMarkerStylesheet && expandedNodes.length > 0) {
|
|
1079
|
+
const getOffset = expandedMarkerStylesheet.getDeckGLAccessor('getOffset');
|
|
1080
|
+
layers.push(
|
|
1081
|
+
new ZoomableMarkerLayer({
|
|
1082
|
+
...SHARED_LAYER_PROPS,
|
|
1083
|
+
id: 'expanded-chain-markers',
|
|
1084
|
+
data: expandedNodes,
|
|
1085
|
+
getPosition: mixedGetPosition(engine.getNodePosition, getOffset),
|
|
1086
|
+
pickable: true,
|
|
1087
|
+
positionUpdateTrigger: [
|
|
1088
|
+
engine.getLayoutLastUpdate(),
|
|
1089
|
+
engine.getLayoutState(),
|
|
1090
|
+
expandedMarkerStylesheet.getDeckGLAccessorUpdateTrigger('getOffset')
|
|
1091
|
+
].join(),
|
|
1092
|
+
stylesheet: expandedMarkerStylesheet,
|
|
1093
|
+
visible: true
|
|
1094
|
+
} as any)
|
|
1095
|
+
);
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
return layers;
|
|
311
1099
|
}
|
|
312
1100
|
}
|
|
1101
|
+
|
|
1102
|
+
function isPlainObject(value: unknown): value is Record<string | number | symbol, unknown> {
|
|
1103
|
+
if (!value || typeof value !== 'object') {
|
|
1104
|
+
return false;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
const prototype = Object.getPrototypeOf(value);
|
|
1108
|
+
return prototype === Object.prototype || prototype === null;
|
|
1109
|
+
}
|
|
1110
|
+
|