@deck.gl-community/graph-layers 9.1.0-beta.8 → 9.2.0-beta.2
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/LICENSE +1 -1
- 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 +12 -11
- package/dist/core/graph-engine.d.ts.map +1 -1
- package/dist/core/graph-engine.js +22 -11
- package/dist/core/graph-engine.js.map +1 -1
- package/dist/core/graph-layout.d.ts +48 -21
- package/dist/core/graph-layout.d.ts.map +1 -1
- package/dist/core/graph-layout.js +91 -24
- package/dist/core/graph-layout.js.map +1 -1
- package/dist/core/interaction-manager.d.ts +6 -4
- package/dist/core/interaction-manager.d.ts.map +1 -1
- package/dist/core/interaction-manager.js +59 -17
- package/dist/core/interaction-manager.js.map +1 -1
- package/dist/graph/edge.d.ts +7 -7
- 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/graph.d.ts +2 -3
- package/dist/graph/graph.js +8 -9
- package/dist/graph/graph.js.map +1 -1
- package/dist/graph/node.d.ts +7 -8
- package/dist/graph/node.d.ts.map +1 -1
- package/dist/graph/node.js +3 -5
- package/dist/graph/node.js.map +1 -1
- 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 +2821 -549
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +28 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -21
- 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.js +0 -1
- 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 +230 -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 +22 -23
- package/dist/layers/graph-layer.d.ts.map +1 -1
- package/dist/layers/graph-layer.js +218 -62
- 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/d3-dag-layout.d.ts +117 -0
- package/dist/layouts/d3-dag/d3-dag-layout.d.ts.map +1 -0
- package/dist/layouts/d3-dag/d3-dag-layout.js +716 -0
- package/dist/layouts/d3-dag/d3-dag-layout.js.map +1 -0
- package/dist/layouts/d3-force/d3-force-layout.d.ts +4 -4
- package/dist/layouts/d3-force/d3-force-layout.d.ts.map +1 -1
- package/dist/layouts/d3-force/d3-force-layout.js +25 -10
- 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 +9 -8
- package/dist/layouts/experimental/force-multi-graph-layout.d.ts.map +1 -1
- package/dist/layouts/experimental/force-multi-graph-layout.js +15 -11
- package/dist/layouts/experimental/force-multi-graph-layout.js.map +1 -1
- package/dist/layouts/experimental/hive-plot-layout.d.ts +11 -8
- package/dist/layouts/experimental/hive-plot-layout.d.ts.map +1 -1
- package/dist/layouts/experimental/hive-plot-layout.js +12 -7
- package/dist/layouts/experimental/hive-plot-layout.js.map +1 -1
- package/dist/layouts/experimental/radial-layout.d.ts +10 -7
- package/dist/layouts/experimental/radial-layout.d.ts.map +1 -1
- package/dist/layouts/experimental/radial-layout.js +11 -6
- package/dist/layouts/experimental/radial-layout.js.map +1 -1
- package/dist/layouts/gpu-force/gpu-force-layout.d.ts +4 -4
- package/dist/layouts/gpu-force/gpu-force-layout.d.ts.map +1 -1
- package/dist/layouts/gpu-force/gpu-force-layout.js +18 -9
- 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 +19 -12
- package/dist/layouts/simple-layout.d.ts.map +1 -1
- package/dist/layouts/simple-layout.js +26 -15
- package/dist/layouts/simple-layout.js.map +1 -1
- package/dist/loaders/create-graph.d.ts +1 -2
- package/dist/loaders/create-graph.js +3 -4
- package/dist/loaders/edge-parsers.d.ts +1 -2
- package/dist/loaders/edge-parsers.js +2 -3
- package/dist/loaders/edge-parsers.js.map +1 -1
- package/dist/loaders/json-loader.d.ts +2 -3
- package/dist/loaders/json-loader.d.ts.map +1 -1
- package/dist/loaders/json-loader.js +5 -6
- package/dist/loaders/json-loader.js.map +1 -1
- package/dist/loaders/node-parsers.d.ts +1 -2
- package/dist/loaders/node-parsers.js +2 -3
- package/dist/loaders/node-parsers.js.map +1 -1
- package/dist/loaders/simple-json-graph-loader.d.ts +0 -1
- package/dist/loaders/simple-json-graph-loader.d.ts.map +1 -1
- package/dist/loaders/simple-json-graph-loader.js +5 -6
- package/dist/loaders/simple-json-graph-loader.js.map +1 -1
- package/dist/loaders/table-graph-loader.d.ts +3 -4
- package/dist/loaders/table-graph-loader.js +5 -6
- package/dist/loaders/table-graph-loader.js.map +1 -1
- 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 +10 -0
- package/dist/style/graph-style-engine.d.ts.map +1 -0
- package/dist/style/graph-style-engine.js +163 -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-engine.d.ts +33 -0
- package/dist/style/style-engine.d.ts.map +1 -0
- package/dist/style/style-engine.js +121 -0
- package/dist/style/style-engine.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/utils/collapsed-chains.d.ts +17 -0
- package/dist/utils/collapsed-chains.d.ts.map +1 -0
- package/dist/utils/collapsed-chains.js +197 -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/widgets/long-press-button.d.ts +0 -1
- package/dist/widgets/long-press-button.js +0 -1
- package/dist/widgets/view-control-widget.d.ts +4 -5
- package/dist/widgets/view-control-widget.d.ts.map +1 -1
- package/dist/widgets/view-control-widget.js +10 -8
- package/dist/widgets/view-control-widget.js.map +1 -1
- package/package.json +23 -7
- package/src/_deprecated/old-constants.ts +122 -0
- package/src/core/constants.ts +21 -43
- package/src/core/graph-engine.ts +24 -9
- package/src/core/graph-layout.ts +133 -28
- package/src/core/interaction-manager.ts +80 -20
- package/src/graph/edge.ts +6 -6
- package/src/graph/graph.ts +7 -7
- package/src/graph/node.ts +6 -6
- package/src/index.ts +31 -6
- package/src/layers/common-layers/marker-layer/marker-list.ts +62 -64
- package/src/layers/edge-attachment-helper.ts +355 -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 +304 -86
- package/src/layouts/d3-dag/d3-dag-layout.ts +969 -0
- package/src/layouts/d3-force/d3-force-layout.ts +33 -11
- package/src/layouts/experimental/force-multi-graph-layout.ts +22 -13
- package/src/layouts/experimental/hive-plot-layout.ts +22 -10
- package/src/layouts/experimental/radial-layout.ts +20 -8
- package/src/layouts/gpu-force/gpu-force-layout.ts +22 -10
- package/src/layouts/simple-layout.ts +48 -25
- package/src/loaders/edge-parsers.ts +2 -2
- package/src/loaders/json-loader.ts +2 -2
- package/src/loaders/node-parsers.ts +2 -2
- package/src/loaders/simple-json-graph-loader.ts +2 -2
- package/src/loaders/table-graph-loader.ts +2 -2
- 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 +229 -0
- package/src/style/graph-stylesheet.schema.ts +344 -0
- package/src/style/style-engine.ts +168 -0
- package/src/style/style-property.ts +314 -51
- package/src/utils/collapsed-chains.ts +261 -0
- package/src/utils/log.ts +15 -1
- package/src/utils/node-boundary.ts +238 -0
- package/src/widgets/view-control-widget.tsx +15 -13
- 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/src/style/style-sheet.ts +0 -277
|
@@ -3,7 +3,23 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
import Color from 'color';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
scaleLinear,
|
|
8
|
+
scaleLog,
|
|
9
|
+
scaleOrdinal,
|
|
10
|
+
scalePow,
|
|
11
|
+
scaleQuantile,
|
|
12
|
+
scaleQuantize,
|
|
13
|
+
scaleSqrt
|
|
14
|
+
} from 'd3-scale';
|
|
15
|
+
|
|
16
|
+
import {warn} from '../utils/log';
|
|
17
|
+
import type {
|
|
18
|
+
GraphStyleAttributeReference,
|
|
19
|
+
GraphStyleLeafValue,
|
|
20
|
+
GraphStyleScale,
|
|
21
|
+
GraphStyleScaleType
|
|
22
|
+
} from './graph-style-engine';
|
|
7
23
|
|
|
8
24
|
/* Utils for type check */
|
|
9
25
|
function getColor(value) {
|
|
@@ -133,29 +149,292 @@ const DEFAULT_STYLES = {
|
|
|
133
149
|
scaleWithZoom: true
|
|
134
150
|
};
|
|
135
151
|
|
|
136
|
-
|
|
137
|
-
|
|
152
|
+
/** Union of supported D3 scale implementations. */
|
|
153
|
+
type SupportedScale =
|
|
154
|
+
| ReturnType<typeof scaleLinear>
|
|
155
|
+
| ReturnType<typeof scaleLog>
|
|
156
|
+
| ReturnType<typeof scalePow>
|
|
157
|
+
|
|
158
|
+
| ReturnType<typeof scaleQuantize>
|
|
159
|
+
| ReturnType<typeof scaleQuantile>
|
|
160
|
+
| ReturnType<typeof scaleOrdinal>;
|
|
161
|
+
|
|
162
|
+
const SCALE_FACTORIES: Record<GraphStyleScaleType, () => SupportedScale> = {
|
|
163
|
+
linear: () => scaleLinear(),
|
|
164
|
+
log: () => scaleLog(),
|
|
165
|
+
pow: () => scalePow(),
|
|
166
|
+
sqrt: () => scaleSqrt(),
|
|
167
|
+
quantize: () => scaleQuantize(),
|
|
168
|
+
quantile: () => scaleQuantile(),
|
|
169
|
+
ordinal: () => scaleOrdinal()
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
/** Resolved attribute reference with guaranteed defaults. */
|
|
173
|
+
type NormalizedAttributeReference = {
|
|
174
|
+
attribute: string;
|
|
175
|
+
fallback: unknown;
|
|
176
|
+
scale?: (value: unknown) => unknown;
|
|
177
|
+
scaleConfig?: GraphStyleScale | ((value: unknown) => unknown);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
/** Create a D3 scale instance based on a declarative configuration. */
|
|
181
|
+
/* eslint-disable-next-line complexity */
|
|
182
|
+
function createScaleFromConfig(config: GraphStyleScale): SupportedScale {
|
|
183
|
+
const type = config.type ?? 'linear';
|
|
184
|
+
const factory = SCALE_FACTORIES[type];
|
|
185
|
+
if (!factory) {
|
|
186
|
+
warn(`Invalid scale type: ${type}`);
|
|
187
|
+
throw new Error(`Invalid scale type: ${type}`);
|
|
188
|
+
}
|
|
189
|
+
const scale = (factory as () => SupportedScale)();
|
|
190
|
+
const anyScale = scale as any;
|
|
191
|
+
if (config.domain && 'domain' in scale) {
|
|
192
|
+
anyScale.domain(config.domain as never);
|
|
193
|
+
}
|
|
194
|
+
if (config.range && 'range' in scale) {
|
|
195
|
+
anyScale.range(config.range as never);
|
|
196
|
+
}
|
|
197
|
+
if (typeof config.clamp === 'boolean' && 'clamp' in scale && typeof anyScale.clamp === 'function') {
|
|
198
|
+
anyScale.clamp(config.clamp);
|
|
199
|
+
}
|
|
200
|
+
if (typeof config.nice !== 'undefined' && 'nice' in scale && typeof anyScale.nice === 'function') {
|
|
201
|
+
anyScale.nice(config.nice as never);
|
|
202
|
+
}
|
|
203
|
+
if (
|
|
204
|
+
type === 'pow' &&
|
|
205
|
+
typeof config.exponent === 'number' &&
|
|
206
|
+
'exponent' in scale &&
|
|
207
|
+
typeof anyScale.exponent === 'function'
|
|
208
|
+
) {
|
|
209
|
+
anyScale.exponent(config.exponent);
|
|
210
|
+
}
|
|
211
|
+
if (
|
|
212
|
+
type === 'log' &&
|
|
213
|
+
typeof config.base === 'number' &&
|
|
214
|
+
'base' in scale &&
|
|
215
|
+
typeof anyScale.base === 'function'
|
|
216
|
+
) {
|
|
217
|
+
anyScale.base(config.base);
|
|
218
|
+
}
|
|
219
|
+
if (
|
|
220
|
+
typeof config.unknown !== 'undefined' &&
|
|
221
|
+
'unknown' in scale &&
|
|
222
|
+
typeof (scale as {unknown?: (value: unknown) => unknown}).unknown === 'function'
|
|
223
|
+
) {
|
|
224
|
+
(scale as {unknown: (value: unknown) => unknown}).unknown(config.unknown);
|
|
225
|
+
}
|
|
226
|
+
return scale;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** Normalize attribute reference definitions into a consistent structure. */
|
|
230
|
+
function normalizeAttributeReference(
|
|
231
|
+
key: string,
|
|
232
|
+
reference: GraphStyleAttributeReference
|
|
233
|
+
): NormalizedAttributeReference {
|
|
234
|
+
if (typeof reference === 'string') {
|
|
235
|
+
const attribute = reference.startsWith('@') ? reference.slice(1) : reference;
|
|
236
|
+
if (!attribute) {
|
|
237
|
+
throw new Error(`Invalid attribute reference for ${key}: ${reference}`);
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
attribute,
|
|
241
|
+
fallback: DEFAULT_STYLES[key]
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const {attribute, fallback = DEFAULT_STYLES[key], scale} = reference;
|
|
246
|
+
if (!attribute) {
|
|
247
|
+
throw new Error(`Invalid attribute reference for ${key}: ${JSON.stringify(reference)}`);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
let scaleFn: ((value: unknown) => unknown) | undefined;
|
|
251
|
+
let scaleConfig: GraphStyleScale | ((value: unknown) => unknown) | undefined;
|
|
252
|
+
|
|
253
|
+
if (scale) {
|
|
254
|
+
if (typeof scale === 'function') {
|
|
255
|
+
scaleFn = scale;
|
|
256
|
+
scaleConfig = scale;
|
|
257
|
+
} else {
|
|
258
|
+
scaleFn = createScaleFromConfig(scale);
|
|
259
|
+
scaleConfig = scale;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return {
|
|
264
|
+
attribute,
|
|
265
|
+
fallback,
|
|
266
|
+
scale: scaleFn,
|
|
267
|
+
scaleConfig
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** Determine whether a value points to a graph attribute reference. */
|
|
272
|
+
function isAttributeReference(value: unknown): value is GraphStyleAttributeReference {
|
|
273
|
+
if (typeof value === 'string') {
|
|
274
|
+
return value.startsWith('@');
|
|
275
|
+
}
|
|
276
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value) && 'attribute' in (value as Record<string, unknown>);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/** Determine whether a style value maps interaction states. */
|
|
280
|
+
function isStatefulValue(value: unknown): value is Record<string, GraphStyleLeafValue> {
|
|
281
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value) && !isAttributeReference(value);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/** Resolve an attribute from a datum or `Graph` entity. */
|
|
285
|
+
function getAttributeValue(datum: any, attribute: string) {
|
|
286
|
+
if (datum && typeof datum.getPropertyValue === 'function') {
|
|
287
|
+
return datum.getPropertyValue(attribute);
|
|
288
|
+
}
|
|
289
|
+
if (datum && typeof datum === 'object' && attribute in datum) {
|
|
290
|
+
return datum[attribute];
|
|
291
|
+
}
|
|
292
|
+
return undefined;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/** Combine Deck.gl update triggers while filtering falsey entries. */
|
|
296
|
+
function mergeUpdateTriggers(...triggers: unknown[]): unknown {
|
|
297
|
+
const filtered = triggers.filter(
|
|
298
|
+
(trigger) => !(trigger === false || trigger === undefined || trigger === null)
|
|
299
|
+
);
|
|
300
|
+
if (!filtered.length) {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
if (filtered.length === 1) {
|
|
304
|
+
return filtered[0];
|
|
305
|
+
}
|
|
306
|
+
return filtered;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/** Build an accessor that reads and optionally scales an attribute. */
|
|
310
|
+
function createAttributeAccessor(
|
|
311
|
+
key: string,
|
|
312
|
+
attributeRef: NormalizedAttributeReference,
|
|
313
|
+
formatter: (value: unknown) => unknown
|
|
314
|
+
) {
|
|
315
|
+
const accessor = (datum: any) => {
|
|
316
|
+
let raw = getAttributeValue(datum, attributeRef.attribute);
|
|
317
|
+
if (raw === undefined || raw === null) {
|
|
318
|
+
raw = attributeRef.fallback;
|
|
319
|
+
}
|
|
320
|
+
if (attributeRef.scale) {
|
|
321
|
+
raw = attributeRef.scale(raw);
|
|
322
|
+
}
|
|
323
|
+
const formatted = formatter(raw);
|
|
324
|
+
if (formatted === null) {
|
|
325
|
+
warn(`Invalid ${key} value: ${raw}`);
|
|
326
|
+
throw new Error(`Invalid ${key} value: ${raw}`);
|
|
327
|
+
}
|
|
328
|
+
return formatted;
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
const updateTrigger = {
|
|
332
|
+
attribute: attributeRef.attribute,
|
|
333
|
+
scale: attributeRef.scaleConfig ?? null
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
return {accessor, updateTrigger};
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/** Result of parsing a leaf style value. */
|
|
340
|
+
type LeafParseResult = {
|
|
341
|
+
value: any;
|
|
342
|
+
isAccessor: boolean;
|
|
343
|
+
updateTrigger: unknown;
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
function describeStyleValue(value: unknown): string {
|
|
347
|
+
if (typeof value === 'string') {
|
|
348
|
+
return value;
|
|
349
|
+
}
|
|
350
|
+
if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'undefined') {
|
|
351
|
+
return String(value);
|
|
352
|
+
}
|
|
353
|
+
if (value === null) {
|
|
354
|
+
return 'null';
|
|
355
|
+
}
|
|
356
|
+
if (typeof value === 'function') {
|
|
357
|
+
return value.name ? `[Function ${value.name}]` : '[Function]';
|
|
358
|
+
}
|
|
359
|
+
if (Array.isArray(value)) {
|
|
360
|
+
return `[${value.map((item) => describeStyleValue(item)).join(', ')}]`;
|
|
361
|
+
}
|
|
362
|
+
try {
|
|
363
|
+
return JSON.stringify(value);
|
|
364
|
+
} catch {
|
|
365
|
+
return String(value);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/** Parse a non-stateful style value into deck.gl compatible form. */
|
|
370
|
+
function parseLeafValue(key: string, value: GraphStyleLeafValue | undefined): LeafParseResult {
|
|
138
371
|
const formatter = PROPERTY_FORMATTERS[key] || IDENTITY;
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
return (node) => {
|
|
147
|
-
const statefulValue = valueMap[node.state];
|
|
148
|
-
if (!node.state || typeof statefulValue === 'undefined') {
|
|
149
|
-
return valueMap.default || DEFAULT_STYLES[key];
|
|
372
|
+
|
|
373
|
+
if (typeof value === 'undefined') {
|
|
374
|
+
const formatted = formatter(DEFAULT_STYLES[key]);
|
|
375
|
+
if (formatted === null) {
|
|
376
|
+
const description = describeStyleValue(value);
|
|
377
|
+
warn(`Invalid ${key} value: ${description}`);
|
|
378
|
+
throw new Error(`Invalid ${key} value: ${description}`);
|
|
150
379
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
380
|
+
return {value: formatted, isAccessor: false, updateTrigger: false};
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (isAttributeReference(value)) {
|
|
384
|
+
const normalized = normalizeAttributeReference(key, value);
|
|
385
|
+
const {accessor, updateTrigger} = createAttributeAccessor(key, normalized, formatter);
|
|
386
|
+
return {value: accessor, isAccessor: true, updateTrigger};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (typeof value === 'function') {
|
|
390
|
+
return {
|
|
391
|
+
value: (datum) => formatter(value(datum)),
|
|
392
|
+
isAccessor: true,
|
|
393
|
+
updateTrigger: value
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
const formatted = formatter(value);
|
|
398
|
+
if (formatted === null) {
|
|
399
|
+
const description = describeStyleValue(value);
|
|
400
|
+
warn(`Invalid ${key} value: ${description}`);
|
|
401
|
+
throw new Error(`Invalid ${key} value: ${description}`);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
return {value: formatted, isAccessor: false, updateTrigger: false};
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Create an accessor capable of handling interaction state overrides for a style property.
|
|
409
|
+
*/
|
|
410
|
+
function createStatefulAccessor(
|
|
411
|
+
key: string,
|
|
412
|
+
value: Record<string, GraphStyleLeafValue>,
|
|
413
|
+
stateUpdateTrigger: unknown
|
|
414
|
+
) {
|
|
415
|
+
const valueMap: Record<string, any> = {};
|
|
416
|
+
const attributeTriggers: unknown[] = [];
|
|
417
|
+
|
|
418
|
+
for (const state of Object.keys(value)) {
|
|
419
|
+
const parsed = parseLeafValue(key, value[state]);
|
|
420
|
+
valueMap[state] = parsed.value;
|
|
421
|
+
if (parsed.updateTrigger) {
|
|
422
|
+
attributeTriggers.push(parsed.updateTrigger);
|
|
155
423
|
}
|
|
156
|
-
|
|
157
|
-
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const defaultValue =
|
|
427
|
+
typeof valueMap.default !== 'undefined' ? valueMap.default : parseLeafValue(key, undefined).value;
|
|
428
|
+
|
|
429
|
+
const accessor = (datum: any) => {
|
|
430
|
+
const stateValue = datum?.state ? valueMap[datum.state] : undefined;
|
|
431
|
+
const candidate = typeof stateValue !== 'undefined' ? stateValue : defaultValue;
|
|
432
|
+
return typeof candidate === 'function' ? candidate(datum) : candidate;
|
|
158
433
|
};
|
|
434
|
+
|
|
435
|
+
const updateTrigger = mergeUpdateTriggers(stateUpdateTrigger, ...attributeTriggers);
|
|
436
|
+
|
|
437
|
+
return {accessor, updateTrigger};
|
|
159
438
|
}
|
|
160
439
|
|
|
161
440
|
const VALUE_TYPE = {
|
|
@@ -165,7 +444,7 @@ const VALUE_TYPE = {
|
|
|
165
444
|
|
|
166
445
|
export class StyleProperty {
|
|
167
446
|
key: any;
|
|
168
|
-
_updateTrigger:
|
|
447
|
+
_updateTrigger: unknown;
|
|
169
448
|
_value: any;
|
|
170
449
|
_valueType: any;
|
|
171
450
|
|
|
@@ -180,40 +459,24 @@ export class StyleProperty {
|
|
|
180
459
|
this.key = key;
|
|
181
460
|
this._updateTrigger = false;
|
|
182
461
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
462
|
+
if (isStatefulValue(value)) {
|
|
463
|
+
const {accessor, updateTrigger: triggers} = createStatefulAccessor(
|
|
464
|
+
key,
|
|
465
|
+
value,
|
|
466
|
+
updateTrigger
|
|
467
|
+
);
|
|
468
|
+
this._value = accessor;
|
|
189
469
|
this._valueType = VALUE_TYPE.ACCESSOR;
|
|
190
|
-
this._updateTrigger =
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
// the output of the function should be formated by
|
|
197
|
-
// the corresponding formatter again.
|
|
198
|
-
// Ex: colorAccessor might return '#f00', which needs to
|
|
199
|
-
// be formated as [255, 0, 0];
|
|
200
|
-
this._value = (d) => formatter(value(d));
|
|
201
|
-
this._valueType = VALUE_TYPE.ACCESSOR;
|
|
202
|
-
this._updateTrigger = value;
|
|
203
|
-
}
|
|
204
|
-
// default state property with plain value:
|
|
205
|
-
// fill: 'red'
|
|
206
|
-
else {
|
|
207
|
-
// format the value properly
|
|
208
|
-
const formatter = PROPERTY_FORMATTERS[key] || IDENTITY;
|
|
209
|
-
this._value = formatter(value);
|
|
210
|
-
this._valueType = VALUE_TYPE.PLAIN_VALUE;
|
|
211
|
-
this._updateTrigger = false;
|
|
470
|
+
this._updateTrigger = triggers;
|
|
471
|
+
} else {
|
|
472
|
+
const parsed = parseLeafValue(key, value as GraphStyleLeafValue | undefined);
|
|
473
|
+
this._value = parsed.value;
|
|
474
|
+
this._valueType = parsed.isAccessor ? VALUE_TYPE.ACCESSOR : VALUE_TYPE.PLAIN_VALUE;
|
|
475
|
+
this._updateTrigger = mergeUpdateTriggers(parsed.updateTrigger);
|
|
212
476
|
}
|
|
213
477
|
|
|
214
|
-
// sanity check
|
|
215
478
|
if (this._value === null) {
|
|
216
|
-
|
|
479
|
+
warn(`Invalid ${key} value: ${value}`);
|
|
217
480
|
throw new Error(`Invalid ${key} value: ${value}`);
|
|
218
481
|
}
|
|
219
482
|
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {GraphEngine} from '../core/graph-engine';
|
|
6
|
+
import type {Node} from '../graph/node';
|
|
7
|
+
|
|
8
|
+
const OUTLINE_PADDING = 24;
|
|
9
|
+
const OUTLINE_CORNER_RADIUS = 16;
|
|
10
|
+
const OUTLINE_CORNER_SEGMENTS = 6;
|
|
11
|
+
|
|
12
|
+
export type ChainInteractionSource =
|
|
13
|
+
| 'node'
|
|
14
|
+
| 'collapsed-marker'
|
|
15
|
+
| 'expanded-marker'
|
|
16
|
+
| 'collapsed-outline'
|
|
17
|
+
| 'expanded-outline';
|
|
18
|
+
|
|
19
|
+
function resolveLayerId(layer: any): string {
|
|
20
|
+
if (!layer) {
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
23
|
+
if (typeof layer.id === 'string') {
|
|
24
|
+
return layer.id;
|
|
25
|
+
}
|
|
26
|
+
if (typeof layer.props?.id === 'string') {
|
|
27
|
+
return layer.props.id;
|
|
28
|
+
}
|
|
29
|
+
return '';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function classifyChainLayer(layer: any): ChainInteractionSource | null {
|
|
33
|
+
let current = layer ?? null;
|
|
34
|
+
while (current) {
|
|
35
|
+
const layerId = resolveLayerId(current);
|
|
36
|
+
if (layerId.includes('collapsed-chain-markers')) {
|
|
37
|
+
return 'collapsed-marker';
|
|
38
|
+
}
|
|
39
|
+
if (layerId.includes('expanded-chain-markers')) {
|
|
40
|
+
return 'expanded-marker';
|
|
41
|
+
}
|
|
42
|
+
if (layerId.includes('collapsed-chain-outlines')) {
|
|
43
|
+
return 'collapsed-outline';
|
|
44
|
+
}
|
|
45
|
+
if (layerId.includes('expanded-chain-outlines')) {
|
|
46
|
+
return 'expanded-outline';
|
|
47
|
+
}
|
|
48
|
+
current = current.parent ?? null;
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function resolveChainInteractionSource(info: any): ChainInteractionSource {
|
|
54
|
+
if (!info) {
|
|
55
|
+
return 'node';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const layersToCheck = [] as any[];
|
|
59
|
+
if (info.layer || info.sourceLayer) {
|
|
60
|
+
if (info.layer) {
|
|
61
|
+
layersToCheck.push(info.layer);
|
|
62
|
+
}
|
|
63
|
+
if (info.sourceLayer && info.sourceLayer !== info.layer) {
|
|
64
|
+
layersToCheck.push(info.sourceLayer);
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
layersToCheck.push(info);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
for (const layer of layersToCheck) {
|
|
71
|
+
const classification = classifyChainLayer(layer);
|
|
72
|
+
if (classification) {
|
|
73
|
+
return classification;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return 'node';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function isChainRepresentative(node: Node): boolean {
|
|
81
|
+
const chainId = node.getPropertyValue('collapsedChainId');
|
|
82
|
+
const nodeIds = node.getPropertyValue('collapsedNodeIds');
|
|
83
|
+
const representativeId = node.getPropertyValue('collapsedChainRepresentativeId');
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
Boolean(chainId) &&
|
|
87
|
+
Array.isArray(nodeIds) &&
|
|
88
|
+
nodeIds.length > 1 &&
|
|
89
|
+
representativeId === node.getId()
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function getRepresentativeNodes(engine: GraphEngine | null | undefined): Node[] {
|
|
94
|
+
if (!engine) {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return engine.getNodes().filter((node) => isChainRepresentative(node));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export type ChainOutlineGetter = (node: Node) => [number, number][] | null;
|
|
102
|
+
|
|
103
|
+
export function createChainOutlineGetter(engine: GraphEngine | null | undefined): ChainOutlineGetter {
|
|
104
|
+
if (!engine) {
|
|
105
|
+
return () => null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const graph = engine.props.graph;
|
|
109
|
+
const cache = new Map<string, [number, number][] | null>();
|
|
110
|
+
|
|
111
|
+
// eslint-disable-next-line max-statements, complexity
|
|
112
|
+
return (node: Node): [number, number][] | null => {
|
|
113
|
+
const chainId = node.getPropertyValue('collapsedChainId');
|
|
114
|
+
if (!chainId) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const cacheKey = String(chainId);
|
|
119
|
+
if (cache.has(cacheKey)) {
|
|
120
|
+
return cache.get(cacheKey) ?? null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (!graph) {
|
|
124
|
+
cache.set(cacheKey, null);
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const collapsedNodeIds = node.getPropertyValue('collapsedNodeIds');
|
|
129
|
+
if (!Array.isArray(collapsedNodeIds) || collapsedNodeIds.length === 0) {
|
|
130
|
+
cache.set(cacheKey, null);
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
135
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
136
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
137
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
138
|
+
|
|
139
|
+
for (const nodeId of collapsedNodeIds) {
|
|
140
|
+
const chainNode = graph.findNode(nodeId);
|
|
141
|
+
if (chainNode) {
|
|
142
|
+
const position = engine.getNodePosition(chainNode);
|
|
143
|
+
if (position) {
|
|
144
|
+
const [x, y] = position;
|
|
145
|
+
minX = Math.min(minX, x);
|
|
146
|
+
maxX = Math.max(maxX, x);
|
|
147
|
+
minY = Math.min(minY, y);
|
|
148
|
+
maxY = Math.max(maxY, y);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (
|
|
154
|
+
!Number.isFinite(minX) ||
|
|
155
|
+
!Number.isFinite(maxX) ||
|
|
156
|
+
!Number.isFinite(minY) ||
|
|
157
|
+
!Number.isFinite(maxY)
|
|
158
|
+
) {
|
|
159
|
+
cache.set(cacheKey, null);
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const paddedMinX = minX - OUTLINE_PADDING;
|
|
164
|
+
const paddedMaxX = maxX + OUTLINE_PADDING;
|
|
165
|
+
const paddedMinY = minY - OUTLINE_PADDING;
|
|
166
|
+
const paddedMaxY = maxY + OUTLINE_PADDING;
|
|
167
|
+
|
|
168
|
+
const width = paddedMaxX - paddedMinX;
|
|
169
|
+
const height = paddedMaxY - paddedMinY;
|
|
170
|
+
|
|
171
|
+
if (width <= 0 || height <= 0) {
|
|
172
|
+
cache.set(cacheKey, null);
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const radius = Math.min(OUTLINE_CORNER_RADIUS, width / 2, height / 2);
|
|
177
|
+
|
|
178
|
+
if (radius <= 0) {
|
|
179
|
+
const polygon: [number, number][] = [
|
|
180
|
+
[paddedMinX, paddedMinY],
|
|
181
|
+
[paddedMinX, paddedMaxY],
|
|
182
|
+
[paddedMaxX, paddedMaxY],
|
|
183
|
+
[paddedMaxX, paddedMinY],
|
|
184
|
+
[paddedMinX, paddedMinY]
|
|
185
|
+
];
|
|
186
|
+
cache.set(cacheKey, polygon);
|
|
187
|
+
return polygon;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const left = paddedMinX;
|
|
191
|
+
const right = paddedMaxX;
|
|
192
|
+
const top = paddedMinY;
|
|
193
|
+
const bottom = paddedMaxY;
|
|
194
|
+
|
|
195
|
+
const polygon: [number, number][] = [];
|
|
196
|
+
const pushArc = (cx: number, cy: number, startAngle: number, endAngle: number) => {
|
|
197
|
+
const step = (endAngle - startAngle) / OUTLINE_CORNER_SEGMENTS;
|
|
198
|
+
for (let i = 1; i <= OUTLINE_CORNER_SEGMENTS; i++) {
|
|
199
|
+
const angle = startAngle + step * i;
|
|
200
|
+
polygon.push([cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
polygon.push([right - radius, top]);
|
|
205
|
+
pushArc(right - radius, top + radius, -Math.PI / 2, 0);
|
|
206
|
+
polygon.push([right, bottom - radius]);
|
|
207
|
+
pushArc(right - radius, bottom - radius, 0, Math.PI / 2);
|
|
208
|
+
polygon.push([left + radius, bottom]);
|
|
209
|
+
pushArc(left + radius, bottom - radius, Math.PI / 2, Math.PI);
|
|
210
|
+
polygon.push([left, top + radius]);
|
|
211
|
+
pushArc(left + radius, top + radius, Math.PI, (3 * Math.PI) / 2);
|
|
212
|
+
polygon.push(polygon[0]);
|
|
213
|
+
|
|
214
|
+
cache.set(cacheKey, polygon);
|
|
215
|
+
return polygon;
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export interface CollapsedChainLayerData {
|
|
220
|
+
representativeNodes: Node[];
|
|
221
|
+
collapsedNodes: Node[];
|
|
222
|
+
collapsedOutlineNodes: Node[];
|
|
223
|
+
expandedNodes: Node[];
|
|
224
|
+
expandedOutlineNodes: Node[];
|
|
225
|
+
getChainOutlinePolygon: ChainOutlineGetter;
|
|
226
|
+
outlineUpdateTrigger: string;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function buildCollapsedChainLayers(
|
|
230
|
+
engine: GraphEngine | null | undefined
|
|
231
|
+
): CollapsedChainLayerData | null {
|
|
232
|
+
if (!engine) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const representativeNodes = getRepresentativeNodes(engine);
|
|
237
|
+
if (representativeNodes.length === 0) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const getChainOutlinePolygon = createChainOutlineGetter(engine);
|
|
242
|
+
const outlineUpdateTrigger = [engine.getLayoutLastUpdate(), engine.getLayoutState()].join();
|
|
243
|
+
|
|
244
|
+
const collapsedNodes = representativeNodes.filter((node) =>
|
|
245
|
+
Boolean(node.getPropertyValue('isCollapsedChain'))
|
|
246
|
+
);
|
|
247
|
+
const collapsedOutlineNodes = collapsedNodes.filter((node) => getChainOutlinePolygon(node));
|
|
248
|
+
|
|
249
|
+
const expandedNodes = representativeNodes.filter((node) => !node.getPropertyValue('isCollapsedChain'));
|
|
250
|
+
const expandedOutlineNodes = expandedNodes.filter((node) => getChainOutlinePolygon(node));
|
|
251
|
+
|
|
252
|
+
return {
|
|
253
|
+
representativeNodes,
|
|
254
|
+
collapsedNodes,
|
|
255
|
+
collapsedOutlineNodes,
|
|
256
|
+
expandedNodes,
|
|
257
|
+
expandedOutlineNodes,
|
|
258
|
+
getChainOutlinePolygon,
|
|
259
|
+
outlineUpdateTrigger
|
|
260
|
+
};
|
|
261
|
+
}
|
package/src/utils/log.ts
CHANGED
|
@@ -6,4 +6,18 @@ import {Log, COLOR} from '@probe.gl/log';
|
|
|
6
6
|
|
|
7
7
|
export const log = new Log({id: 'graph-layers'}).enable();
|
|
8
8
|
|
|
9
|
-
log.log({color: COLOR.CYAN}, 'Initialize graph-layers logger.')
|
|
9
|
+
log.log({color: COLOR.CYAN}, 'Initialize graph-layers logger.');
|
|
10
|
+
|
|
11
|
+
function invokeLogFunction(result: unknown) {
|
|
12
|
+
if (typeof result === 'function') {
|
|
13
|
+
result();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function warn(message: string, ...args: unknown[]) {
|
|
18
|
+
invokeLogFunction(log.warn(message, ...args));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function error(message: string, ...args: unknown[]) {
|
|
22
|
+
invokeLogFunction(log.error(message, ...args));
|
|
23
|
+
}
|