@deck.gl-community/graph-layers 9.2.0-beta.8 → 9.2.8
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/README.md +3 -0
- package/dist/_deprecated/old-constants.d.ts.map +1 -1
- package/dist/_deprecated/old-constants.js.map +1 -1
- package/dist/core/graph-layout.d.ts.map +1 -1
- package/dist/core/graph-layout.js.map +1 -1
- package/dist/core/interaction-manager.d.ts.map +1 -1
- package/dist/core/interaction-manager.js.map +1 -1
- package/dist/graph/arrow-graph.d.ts.map +1 -1
- package/dist/graph/arrow-graph.js.map +1 -1
- package/dist/graph/classic-graph.d.ts.map +1 -1
- package/dist/graph/classic-graph.js +1 -3
- package/dist/graph/classic-graph.js.map +1 -1
- package/dist/graph/functions/arrow-utils.d.ts.map +1 -1
- package/dist/graph/functions/arrow-utils.js +5 -3
- package/dist/graph/functions/arrow-utils.js.map +1 -1
- package/dist/graph/functions/create-graph-from-data.d.ts.map +1 -1
- package/dist/graph/functions/create-graph-from-data.js.map +1 -1
- package/dist/graph/graph-normalization.d.ts.map +1 -1
- package/dist/graph/graph-normalization.js.map +1 -1
- package/dist/graph-data/arrow-graph-data-builder.d.ts.map +1 -1
- package/dist/graph-data/arrow-graph-data-builder.js.map +1 -1
- package/dist/graph-data/graph-data-builder.d.ts.map +1 -1
- package/dist/graph-data/plain-graph-data-builder.d.ts.map +1 -1
- package/dist/graph-style-schema.cdn.js +1 -1
- package/dist/graph-style-schema.json +1 -1
- package/dist/index.cjs +42 -39
- package/dist/index.cjs.map +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/layers/common-layers/grid-layer/grid-layer.d.ts.map +1 -1
- package/dist/layers/common-layers/grid-layer/grid-layer.js +6 -16
- package/dist/layers/common-layers/grid-layer/grid-layer.js.map +1 -1
- package/dist/layers/edge-attachment-helper.d.ts.map +1 -1
- package/dist/layers/edge-attachment-helper.js +1 -3
- package/dist/layers/edge-attachment-helper.js.map +1 -1
- package/dist/layers/edge-layer.js +4 -4
- package/dist/layers/edge-layer.js.map +1 -1
- package/dist/layers/edge-layers/arrow-2d-geometry.js +1 -8
- package/dist/layers/edge-layers/arrow-2d-geometry.js.map +1 -1
- package/dist/layers/graph-layer.d.ts.map +1 -1
- package/dist/layers/graph-layer.js +9 -11
- package/dist/layers/graph-layer.js.map +1 -1
- package/dist/layouts/d3-dag/collapsable-d3-dag-layout.d.ts.map +1 -1
- package/dist/layouts/d3-dag/collapsable-d3-dag-layout.js.map +1 -1
- package/dist/layouts/d3-dag/d3-dag-layout.d.ts.map +1 -1
- package/dist/layouts/d3-dag/d3-dag-layout.js +9 -2
- package/dist/layouts/d3-dag/d3-dag-layout.js.map +1 -1
- package/dist/layouts/experimental/radial-layout.d.ts.map +1 -1
- package/dist/layouts/experimental/radial-layout.js.map +1 -1
- package/dist/layouts/simple-layout.d.ts.map +1 -1
- package/dist/layouts/simple-layout.js +4 -1
- package/dist/layouts/simple-layout.js.map +1 -1
- package/dist/loaders/dot-graph-loader.d.ts.map +1 -1
- package/dist/loaders/dot-graph-loader.js +10 -3
- package/dist/loaders/dot-graph-loader.js.map +1 -1
- package/dist/loaders/json-graph-loader.d.ts.map +1 -1
- package/dist/loaders/json-graph-loader.js +2 -2
- package/dist/loaders/json-graph-loader.js.map +1 -1
- package/dist/loaders/parsers/parse-json-graph.js +2 -1
- package/dist/loaders/parsers/parse-json-graph.js.map +1 -1
- package/dist/style/graph-layer-stylesheet.d.ts.map +1 -1
- package/dist/style/graph-layer-stylesheet.js +7 -7
- package/dist/style/graph-layer-stylesheet.js.map +1 -1
- package/dist/style/graph-style-engine.js +3 -1
- package/dist/style/graph-style-engine.js.map +1 -1
- package/dist/style/graph-stylesheet-schema.d.ts.map +1 -1
- package/dist/style/graph-stylesheet-schema.js +9 -17
- package/dist/style/graph-stylesheet-schema.js.map +1 -1
- package/dist/style/style-property.d.ts.map +1 -1
- package/dist/style/style-property.js +17 -5
- package/dist/style/style-property.js.map +1 -1
- package/dist/style/stylesheet-engine.d.ts.map +1 -1
- package/dist/style/stylesheet-engine.js +1 -1
- package/dist/style/stylesheet-engine.js.map +1 -1
- package/dist/utils/collapsed-chains.d.ts.map +1 -1
- package/dist/utils/collapsed-chains.js.map +1 -1
- package/dist/utils/node-boundary.d.ts.map +1 -1
- package/dist/utils/node-boundary.js +1 -1
- package/dist/utils/node-boundary.js.map +1 -1
- package/dist/utils/rank-grid.d.ts.map +1 -1
- package/dist/utils/rank-grid.js +5 -2
- package/dist/utils/rank-grid.js.map +1 -1
- package/package.json +8 -8
- package/src/_deprecated/old-constants.ts +12 -6
- package/src/core/graph-layout.ts +2 -6
- package/src/core/interaction-manager.ts +2 -1
- package/src/graph/arrow-graph.ts +17 -10
- package/src/graph/classic-graph.ts +8 -5
- package/src/graph/functions/arrow-utils.ts +8 -4
- package/src/graph/functions/create-graph-from-data.ts +2 -2
- package/src/graph/graph-normalization.ts +8 -2
- package/src/graph-data/arrow-graph-data-builder.ts +6 -3
- package/src/graph-data/graph-data-builder.ts +1 -1
- package/src/graph-data/plain-graph-data-builder.ts +1 -1
- package/src/index.ts +33 -16
- package/src/layers/common-layers/grid-layer/grid-layer.ts +26 -19
- package/src/layers/edge-attachment-helper.ts +53 -41
- package/src/layers/edge-layer.ts +4 -4
- package/src/layers/edge-layers/arrow-2d-geometry.ts +1 -8
- package/src/layers/graph-layer.ts +86 -82
- package/src/layouts/d3-dag/collapsable-d3-dag-layout.ts +14 -7
- package/src/layouts/d3-dag/d3-dag-layout.ts +31 -19
- package/src/layouts/experimental/radial-layout.ts +4 -1
- package/src/layouts/simple-layout.ts +6 -4
- package/src/loaders/dot-graph-loader.ts +19 -7
- package/src/loaders/json-graph-loader.ts +3 -5
- package/src/loaders/parsers/parse-json-graph.ts +2 -1
- package/src/style/graph-layer-stylesheet.ts +15 -15
- package/src/style/graph-style-engine.ts +9 -4
- package/src/style/graph-stylesheet-schema.ts +32 -80
- package/src/style/style-property.ts +26 -11
- package/src/style/stylesheet-engine.ts +44 -29
- package/src/utils/collapsed-chains.ts +6 -2
- package/src/utils/node-boundary.ts +2 -3
- package/src/utils/rank-grid.ts +31 -17
|
@@ -153,7 +153,9 @@ function isEdgeInterface(value: unknown): value is EdgeInterface {
|
|
|
153
153
|
/**
|
|
154
154
|
* Layout that orchestrates d3-dag operators from declarative options.
|
|
155
155
|
*/
|
|
156
|
-
export class D3DagLayout<
|
|
156
|
+
export class D3DagLayout<
|
|
157
|
+
PropsT extends D3DagLayoutProps = D3DagLayoutProps
|
|
158
|
+
> extends GraphLayout<PropsT> {
|
|
157
159
|
static defaultProps: Readonly<Required<D3DagLayoutProps>> = {
|
|
158
160
|
...GraphLayout.defaultProps,
|
|
159
161
|
layout: 'sugiyama',
|
|
@@ -213,7 +215,6 @@ export class D3DagLayout<PropsT extends D3DagLayoutProps = D3DagLayoutProps> ext
|
|
|
213
215
|
}
|
|
214
216
|
}
|
|
215
217
|
|
|
216
|
-
|
|
217
218
|
initializeGraph(graph: Graph): void {
|
|
218
219
|
this.updateGraph(graph);
|
|
219
220
|
}
|
|
@@ -277,14 +278,12 @@ export class D3DagLayout<PropsT extends D3DagLayoutProps = D3DagLayoutProps> ext
|
|
|
277
278
|
return this._nodePositions.get(mappedId) || null;
|
|
278
279
|
}
|
|
279
280
|
|
|
280
|
-
getEdgePosition(edge: EdgeInterface):
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
287
|
-
| null {
|
|
281
|
+
getEdgePosition(edge: EdgeInterface): {
|
|
282
|
+
type: string;
|
|
283
|
+
sourcePosition: [number, number];
|
|
284
|
+
targetPosition: [number, number];
|
|
285
|
+
controlPoints: [number, number][];
|
|
286
|
+
} | null {
|
|
288
287
|
const mappedSourceId = this._mapNodeId(edge.getSourceNodeId());
|
|
289
288
|
const mappedTargetId = this._mapNodeId(edge.getTargetNodeId());
|
|
290
289
|
if (mappedSourceId === mappedTargetId) {
|
|
@@ -407,7 +406,9 @@ export class D3DagLayout<PropsT extends D3DagLayoutProps = D3DagLayoutProps> ext
|
|
|
407
406
|
const connect = graphConnect()
|
|
408
407
|
.sourceId(({source}: ConnectDatum): string => source)
|
|
409
408
|
.targetId(({target}: ConnectDatum): string => target)
|
|
410
|
-
.nodeDatum(
|
|
409
|
+
.nodeDatum(
|
|
410
|
+
(id: string): NodeInterface => this._nodeLookup.get(this._fromDagId(id)) ?? new Node({id})
|
|
411
|
+
)
|
|
411
412
|
.single(true);
|
|
412
413
|
|
|
413
414
|
const edges = Array.from(this._graph.getEdges());
|
|
@@ -508,7 +509,9 @@ export class D3DagLayout<PropsT extends D3DagLayoutProps = D3DagLayoutProps> ext
|
|
|
508
509
|
.filter((edge) => edge.isDirected() && edge.getSourceNodeId() === nodeId);
|
|
509
510
|
}
|
|
510
511
|
|
|
511
|
-
private _ensureEdgeData<T>(
|
|
512
|
+
private _ensureEdgeData<T>(
|
|
513
|
+
dag: MutGraph<NodeInterface, T>
|
|
514
|
+
): MutGraph<NodeInterface, EdgeInterface> {
|
|
512
515
|
for (const link of dag.links()) {
|
|
513
516
|
if (isEdgeInterface(link.data)) {
|
|
514
517
|
continue;
|
|
@@ -551,7 +554,10 @@ export class D3DagLayout<PropsT extends D3DagLayoutProps = D3DagLayoutProps> ext
|
|
|
551
554
|
// @ts-expect-error TS2345 - Argument of type '(dagNode: MutGraphNode<NodeInterface, EdgeInterface>) => number | undefined' is not assignable to parameter of type '(dagNode: MutGraphNode<NodeInterface, EdgeInterface>) => number'.
|
|
552
555
|
layeringOperator = layeringOperator.rank((dagNode) => {
|
|
553
556
|
const node = dagNode.data as NodeInterface;
|
|
554
|
-
const rank =
|
|
557
|
+
const rank =
|
|
558
|
+
typeof nodeRank === 'function'
|
|
559
|
+
? nodeRank?.(node)
|
|
560
|
+
: node?.getPropertyValue(nodeRank) || undefined;
|
|
555
561
|
// if (rank !== undefined) {
|
|
556
562
|
// console.log(`Node ${node.getId()} assigned to rank ${rank}`);
|
|
557
563
|
// }
|
|
@@ -644,8 +650,17 @@ export class D3DagLayout<PropsT extends D3DagLayoutProps = D3DagLayoutProps> ext
|
|
|
644
650
|
if (!edge) {
|
|
645
651
|
continue;
|
|
646
652
|
}
|
|
647
|
-
const points =
|
|
648
|
-
|
|
653
|
+
const points =
|
|
654
|
+
link.points && link.points.length
|
|
655
|
+
? link.points
|
|
656
|
+
: [
|
|
657
|
+
[link.source.x ?? 0, link.source.y ?? 0],
|
|
658
|
+
[link.target.x ?? 0, link.target.y ?? 0]
|
|
659
|
+
];
|
|
660
|
+
this._rawEdgePoints.set(
|
|
661
|
+
edge.getId(),
|
|
662
|
+
points.map((point) => [...point] as [number, number])
|
|
663
|
+
);
|
|
649
664
|
}
|
|
650
665
|
|
|
651
666
|
this._updateTransformedGeometry();
|
|
@@ -687,10 +702,7 @@ export class D3DagLayout<PropsT extends D3DagLayoutProps = D3DagLayoutProps> ext
|
|
|
687
702
|
for (const [edgeId, points] of this._rawEdgePoints) {
|
|
688
703
|
const transformed = points.map(([x, y]) => transform(x, y));
|
|
689
704
|
this._edgePoints.set(edgeId, transformed);
|
|
690
|
-
this._edgeControlPoints.set(
|
|
691
|
-
edgeId,
|
|
692
|
-
transformed.length > 2 ? transformed.slice(1, -1) : []
|
|
693
|
-
);
|
|
705
|
+
this._edgeControlPoints.set(edgeId, transformed.length > 2 ? transformed.slice(1, -1) : []);
|
|
694
706
|
}
|
|
695
707
|
|
|
696
708
|
for (const [id, position] of this._lockedNodePositions) {
|
|
@@ -10,7 +10,10 @@ export type RadialLayoutProps = GraphLayoutProps & {
|
|
|
10
10
|
tree?: any;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
const getTreeNode = (
|
|
13
|
+
const getTreeNode = (
|
|
14
|
+
nodeId: string,
|
|
15
|
+
nodeMap: Record<string, {children?: string[]; isLeaf?: boolean}>
|
|
16
|
+
) => {
|
|
14
17
|
const node = nodeMap[nodeId];
|
|
15
18
|
if (node) {
|
|
16
19
|
return node;
|
|
@@ -35,7 +35,7 @@ export class SimpleLayout extends GraphLayout<SimpleLayoutProps> {
|
|
|
35
35
|
this._notifyLayoutComplete();
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
stop()
|
|
38
|
+
stop(): void {}
|
|
39
39
|
|
|
40
40
|
update(): void {
|
|
41
41
|
this._notifyLayoutComplete();
|
|
@@ -50,7 +50,10 @@ export class SimpleLayout extends GraphLayout<SimpleLayoutProps> {
|
|
|
50
50
|
const nodes = Array.from(graph.getNodes());
|
|
51
51
|
this._nodeMap = new Map(nodes.map((node) => [node.getId(), node]));
|
|
52
52
|
this._nodePositionMap = new Map(
|
|
53
|
-
nodes.map((node) => [
|
|
53
|
+
nodes.map((node) => [
|
|
54
|
+
node.getId(),
|
|
55
|
+
this._normalizePosition(this.props.nodePositionAccessor(node))
|
|
56
|
+
])
|
|
54
57
|
);
|
|
55
58
|
}
|
|
56
59
|
|
|
@@ -63,7 +66,7 @@ export class SimpleLayout extends GraphLayout<SimpleLayoutProps> {
|
|
|
63
66
|
return [0, 0] as [number, number];
|
|
64
67
|
}
|
|
65
68
|
const position = this._nodePositionMap.get(node.getId());
|
|
66
|
-
return position ?? [0, 0] as [number, number];
|
|
69
|
+
return position ?? ([0, 0] as [number, number]);
|
|
67
70
|
};
|
|
68
71
|
|
|
69
72
|
getEdgePosition = (edge: EdgeInterface) => {
|
|
@@ -91,7 +94,6 @@ export class SimpleLayout extends GraphLayout<SimpleLayoutProps> {
|
|
|
91
94
|
this._onLayoutDone();
|
|
92
95
|
}
|
|
93
96
|
|
|
94
|
-
|
|
95
97
|
protected override _updateBounds(): void {
|
|
96
98
|
const positions = Array.from(this._nodePositionMap.values(), (position) =>
|
|
97
99
|
this._normalizePosition(position)
|
|
@@ -55,13 +55,12 @@ export type DOTGraphLoaderMetadata = {
|
|
|
55
55
|
|
|
56
56
|
export type DOTGraphLoaderOptions = LoaderOptions & {
|
|
57
57
|
dot?: {
|
|
58
|
-
|
|
58
|
+
version?: number;
|
|
59
59
|
};
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
export type DOTGraphParserOptions = NonNullable<DOTGraphLoaderOptions['dot']>;
|
|
63
63
|
|
|
64
|
-
|
|
65
64
|
export const DOTGraphLoader = {
|
|
66
65
|
dataType: null as unknown as ArrowGraphData,
|
|
67
66
|
batchType: null as never,
|
|
@@ -89,7 +88,6 @@ export const DOTGraphLoader = {
|
|
|
89
88
|
}
|
|
90
89
|
} as const satisfies LoaderWithParser<ArrowGraphData, never, DOTGraphLoaderOptions>;
|
|
91
90
|
|
|
92
|
-
|
|
93
91
|
export function loadDOTGraph(dot: string, options: DOTGraphParserOptions = {}): ArrowGraphData {
|
|
94
92
|
const parsed = parseDOT(dot);
|
|
95
93
|
return buildArrowGraphData(parsed, options);
|
|
@@ -121,7 +119,9 @@ function buildArrowGraphData(
|
|
|
121
119
|
for (const node of parsed.nodes.values()) {
|
|
122
120
|
const attributes: DOTAttributeMap = {...node.attributes};
|
|
123
121
|
if (node.subgraphs.size > 0) {
|
|
124
|
-
attributes.subgraphs = Array.from(node.subgraphs, (id) =>
|
|
122
|
+
attributes.subgraphs = Array.from(node.subgraphs, (id) =>
|
|
123
|
+
describeSubgraph(id, subgraphDescriptors)
|
|
124
|
+
);
|
|
125
125
|
}
|
|
126
126
|
builder.addNode({
|
|
127
127
|
id: node.id,
|
|
@@ -428,7 +428,11 @@ class DOTParser {
|
|
|
428
428
|
graphAttributes: {}
|
|
429
429
|
};
|
|
430
430
|
this.scopes.push(context);
|
|
431
|
-
this.result.subgraphs.set(subgraphId, {
|
|
431
|
+
this.result.subgraphs.set(subgraphId, {
|
|
432
|
+
id: subgraphId,
|
|
433
|
+
attributes: context.graphAttributes,
|
|
434
|
+
parentId
|
|
435
|
+
});
|
|
432
436
|
|
|
433
437
|
let shouldContinue = true;
|
|
434
438
|
while (shouldContinue) {
|
|
@@ -702,7 +706,10 @@ function readQuotedString(input: string, startIndex: number): {value: string; ne
|
|
|
702
706
|
throw new Error('Unterminated string literal in DOT source.');
|
|
703
707
|
}
|
|
704
708
|
|
|
705
|
-
function readEscapedCharacter(
|
|
709
|
+
function readEscapedCharacter(
|
|
710
|
+
input: string,
|
|
711
|
+
startIndex: number
|
|
712
|
+
): {value: string; nextIndex: number} {
|
|
706
713
|
const next = input[startIndex];
|
|
707
714
|
switch (next) {
|
|
708
715
|
case 'n':
|
|
@@ -807,7 +814,12 @@ function isIdentifierLike(token: Token): boolean {
|
|
|
807
814
|
}
|
|
808
815
|
|
|
809
816
|
function isStructuralToken(token: Token): boolean {
|
|
810
|
-
return
|
|
817
|
+
return (
|
|
818
|
+
token.type === 'lbrace' ||
|
|
819
|
+
token.type === 'rbrace' ||
|
|
820
|
+
token.type === 'lbrack' ||
|
|
821
|
+
token.type === 'rbrack'
|
|
822
|
+
);
|
|
811
823
|
}
|
|
812
824
|
|
|
813
825
|
function parseIdentifierValue(token: Token): string {
|
|
@@ -12,8 +12,7 @@ import type {PlainGraphData} from '../graph-data/graph-data';
|
|
|
12
12
|
const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
|
|
13
13
|
|
|
14
14
|
export type JSONGraphLoaderOptions = LoaderOptions & {
|
|
15
|
-
jsongraph?: {
|
|
16
|
-
};
|
|
15
|
+
jsongraph?: {};
|
|
17
16
|
};
|
|
18
17
|
|
|
19
18
|
export type JSONGraphParserOptions = NonNullable<JSONGraphLoaderOptions['jsongraph']>;
|
|
@@ -31,15 +30,14 @@ export const JSONGraphLoader = {
|
|
|
31
30
|
mimeTypes: ['application/json'],
|
|
32
31
|
text: true,
|
|
33
32
|
options: {
|
|
34
|
-
|
|
35
|
-
}
|
|
33
|
+
jsongraph: {}
|
|
36
34
|
},
|
|
37
35
|
|
|
38
36
|
parse: async (arrayBuffer: ArrayBuffer, options?: JSONGraphLoaderOptions) => {
|
|
39
37
|
const text = new TextDecoder().decode(arrayBuffer);
|
|
40
38
|
return Promise.resolve(JSONGraphLoader.parseTextSync(text, options));
|
|
41
39
|
},
|
|
42
|
-
|
|
40
|
+
|
|
43
41
|
parseTextSync: (text: string, options?: JSONGraphLoaderOptions) => {
|
|
44
42
|
// const parseOptions = {...JSONGraphLoader.options.jsongraph, ...options?.jsongraph};
|
|
45
43
|
throw new Error('JSONGraphLoader.parseTextSync not implemented');
|
|
@@ -84,7 +84,8 @@ function parseNodes(
|
|
|
84
84
|
state: parsed.state ?? (attributes.state as NodeState | undefined),
|
|
85
85
|
selectable: parsed.selectable ?? (attributes.selectable as boolean | undefined),
|
|
86
86
|
highlightConnectedEdges:
|
|
87
|
-
parsed.highlightConnectedEdges ??
|
|
87
|
+
parsed.highlightConnectedEdges ??
|
|
88
|
+
(attributes.highlightConnectedEdges as boolean | undefined),
|
|
88
89
|
label: parsed.label ?? (attributes.label as string | undefined),
|
|
89
90
|
weight: parsed.weight ?? (attributes.weight as number | undefined),
|
|
90
91
|
attributes
|
|
@@ -44,11 +44,13 @@ export type NormalizedGraphLayerStylesheet = {
|
|
|
44
44
|
|
|
45
45
|
export const DEFAULT_GRAPH_LAYER_STYLESHEET_INPUT: GraphLayerStylesheet = {
|
|
46
46
|
nodes: [],
|
|
47
|
-
edges: [
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
edges: [
|
|
48
|
+
{
|
|
49
|
+
type: 'edge',
|
|
50
|
+
stroke: 'black',
|
|
51
|
+
strokeWidth: 1
|
|
52
|
+
}
|
|
53
|
+
]
|
|
52
54
|
};
|
|
53
55
|
|
|
54
56
|
const DEFAULT_EDGE_STYLE: GraphLayerEdgeStyle = {
|
|
@@ -86,16 +88,14 @@ export function normalizeGraphLayerStylesheet({
|
|
|
86
88
|
const edgeEntries = Array.isArray(resolvedEdgeStyles)
|
|
87
89
|
? resolvedEdgeStyles
|
|
88
90
|
: resolvedEdgeStyles
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const edges: GraphLayerEdgeStyle[] = (
|
|
93
|
-
|
|
94
|
-
.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
decorators: (edgeStyleEntry).decorators ?? []
|
|
98
|
-
})) as GraphLayerEdgeStyle[];
|
|
91
|
+
? [resolvedEdgeStyles]
|
|
92
|
+
: DEFAULT_GRAPH_LAYER_STYLESHEET.edges;
|
|
93
|
+
|
|
94
|
+
const edges: GraphLayerEdgeStyle[] = edgeEntries.filter(Boolean).map((edgeStyleEntry) => ({
|
|
95
|
+
...edgeStyleEntry,
|
|
96
|
+
type: edgeStyleEntry.type ?? 'edge',
|
|
97
|
+
decorators: edgeStyleEntry.decorators ?? []
|
|
98
|
+
})) as GraphLayerEdgeStyle[];
|
|
99
99
|
|
|
100
100
|
return {
|
|
101
101
|
nodes,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
/* eslint-disable no-continue */
|
|
5
|
+
/* eslint-disable no-continue */
|
|
6
6
|
|
|
7
7
|
import {ZodError, type ZodIssue} from 'zod';
|
|
8
8
|
|
|
@@ -103,7 +103,9 @@ function sanitizeStylesheet(
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
const fallbackTypeCandidate =
|
|
106
|
-
typeof (style as {type?: unknown}).type === 'string'
|
|
106
|
+
typeof (style as {type?: unknown}).type === 'string'
|
|
107
|
+
? (style as {type: string}).type
|
|
108
|
+
: undefined;
|
|
107
109
|
const fallbackCandidates = Array.from(
|
|
108
110
|
new Set(
|
|
109
111
|
[fallbackTypeCandidate, 'edge'].filter(
|
|
@@ -134,7 +136,7 @@ function sanitizeStylesheet(
|
|
|
134
136
|
if (rootKey === undefined || rootKey === 'type') {
|
|
135
137
|
continue;
|
|
136
138
|
}
|
|
137
|
-
|
|
139
|
+
|
|
138
140
|
if (typeof rootKey === 'string' && rootKey.startsWith(':')) {
|
|
139
141
|
removeNestedProperty(sanitized, path);
|
|
140
142
|
continue;
|
|
@@ -178,7 +180,10 @@ function cloneValue<T>(value: T): T {
|
|
|
178
180
|
}
|
|
179
181
|
|
|
180
182
|
// eslint-disable-next-line max-statements, complexity
|
|
181
|
-
function removeNestedProperty(
|
|
183
|
+
function removeNestedProperty(
|
|
184
|
+
target: Record<string, unknown> | unknown[],
|
|
185
|
+
path: (string | number)[]
|
|
186
|
+
) {
|
|
182
187
|
if (path.length === 0) {
|
|
183
188
|
return;
|
|
184
189
|
}
|
|
@@ -71,7 +71,10 @@ export type GraphStyleScale = z.infer<typeof GraphStyleScaleSchema>;
|
|
|
71
71
|
export const GraphStyleAttributeReferenceSchema = z.union([
|
|
72
72
|
z
|
|
73
73
|
.string()
|
|
74
|
-
.regex(
|
|
74
|
+
.regex(
|
|
75
|
+
/^@.+/,
|
|
76
|
+
'Attribute reference strings must start with "@" and include an attribute name.'
|
|
77
|
+
),
|
|
75
78
|
z
|
|
76
79
|
.object({
|
|
77
80
|
attribute: z.string().min(1, 'Attribute name is required.'),
|
|
@@ -116,17 +119,13 @@ export const GraphStyleStateMapSchema = z.record(
|
|
|
116
119
|
/**
|
|
117
120
|
* Style value that may be either a simple leaf value or a keyed map of overrides.
|
|
118
121
|
*/
|
|
119
|
-
export const GraphStyleValueSchema = z.union([
|
|
120
|
-
GraphStyleLeafValueSchema,
|
|
121
|
-
GraphStyleStateMapSchema
|
|
122
|
-
]);
|
|
122
|
+
export const GraphStyleValueSchema = z.union([GraphStyleLeafValueSchema, GraphStyleStateMapSchema]);
|
|
123
123
|
|
|
124
124
|
/**
|
|
125
125
|
* Parsed style property value that may include state overrides.
|
|
126
126
|
*/
|
|
127
127
|
export type GraphStyleValue = z.infer<typeof GraphStyleValueSchema>;
|
|
128
128
|
|
|
129
|
-
|
|
130
129
|
export type GraphStyleType = keyof typeof GRAPH_DECKGL_ACCESSOR_MAP;
|
|
131
130
|
|
|
132
131
|
/**
|
|
@@ -136,10 +135,7 @@ export type GraphStyleSelector = `:${string}`;
|
|
|
136
135
|
|
|
137
136
|
const GraphStyleSelectorKeySchema = z.string().regex(/^:[^\s]+/, 'Selectors must start with ":".');
|
|
138
137
|
|
|
139
|
-
function createSelectorRefinement(
|
|
140
|
-
allowedKeys: readonly string[],
|
|
141
|
-
propertiesSchema: ZodTypeAny
|
|
142
|
-
) {
|
|
138
|
+
function createSelectorRefinement(allowedKeys: readonly string[], propertiesSchema: ZodTypeAny) {
|
|
143
139
|
const allowedKeySet = new Set<string>(allowedKeys);
|
|
144
140
|
|
|
145
141
|
return (value: unknown, ctx: z.RefinementCtx) => {
|
|
@@ -201,9 +197,7 @@ const CircleStylesheetSchema = z
|
|
|
201
197
|
...CircleShape
|
|
202
198
|
})
|
|
203
199
|
.catchall(z.unknown())
|
|
204
|
-
.superRefine(
|
|
205
|
-
createSelectorRefinement(Object.keys(CircleShape), CirclePropertiesSchema)
|
|
206
|
-
);
|
|
200
|
+
.superRefine(createSelectorRefinement(Object.keys(CircleShape), CirclePropertiesSchema));
|
|
207
201
|
|
|
208
202
|
const RectangleShape = {
|
|
209
203
|
offset: GraphStyleValueSchema.optional(),
|
|
@@ -223,12 +217,7 @@ const RectangleStylesheetSchema = z
|
|
|
223
217
|
...RectangleShape
|
|
224
218
|
})
|
|
225
219
|
.catchall(z.unknown())
|
|
226
|
-
.superRefine(
|
|
227
|
-
createSelectorRefinement(
|
|
228
|
-
Object.keys(RectangleShape),
|
|
229
|
-
RectanglePropertiesSchema
|
|
230
|
-
)
|
|
231
|
-
);
|
|
220
|
+
.superRefine(createSelectorRefinement(Object.keys(RectangleShape), RectanglePropertiesSchema));
|
|
232
221
|
|
|
233
222
|
const RoundedRectangleShape = {
|
|
234
223
|
offset: GraphStyleValueSchema.optional(),
|
|
@@ -242,10 +231,7 @@ const RoundedRectangleShape = {
|
|
|
242
231
|
strokeWidth: GraphStyleValueSchema.optional()
|
|
243
232
|
} as const;
|
|
244
233
|
|
|
245
|
-
const RoundedRectanglePropertiesSchema = z
|
|
246
|
-
.object(RoundedRectangleShape)
|
|
247
|
-
.partial()
|
|
248
|
-
.strict();
|
|
234
|
+
const RoundedRectanglePropertiesSchema = z.object(RoundedRectangleShape).partial().strict();
|
|
249
235
|
|
|
250
236
|
const RoundedRectangleStylesheetSchema = z
|
|
251
237
|
.object({
|
|
@@ -254,10 +240,7 @@ const RoundedRectangleStylesheetSchema = z
|
|
|
254
240
|
})
|
|
255
241
|
.catchall(z.unknown())
|
|
256
242
|
.superRefine(
|
|
257
|
-
createSelectorRefinement(
|
|
258
|
-
Object.keys(RoundedRectangleShape),
|
|
259
|
-
RoundedRectanglePropertiesSchema
|
|
260
|
-
)
|
|
243
|
+
createSelectorRefinement(Object.keys(RoundedRectangleShape), RoundedRectanglePropertiesSchema)
|
|
261
244
|
);
|
|
262
245
|
|
|
263
246
|
const PathRoundedRectangleShape = {
|
|
@@ -271,10 +254,7 @@ const PathRoundedRectangleShape = {
|
|
|
271
254
|
cornerRadius: GraphStyleValueSchema.optional()
|
|
272
255
|
} as const;
|
|
273
256
|
|
|
274
|
-
const PathRoundedRectanglePropertiesSchema = z
|
|
275
|
-
.object(PathRoundedRectangleShape)
|
|
276
|
-
.partial()
|
|
277
|
-
.strict();
|
|
257
|
+
const PathRoundedRectanglePropertiesSchema = z.object(PathRoundedRectangleShape).partial().strict();
|
|
278
258
|
|
|
279
259
|
const PathRoundedRectangleStylesheetSchema = z
|
|
280
260
|
.object({
|
|
@@ -312,9 +292,7 @@ const LabelStylesheetSchema = z
|
|
|
312
292
|
...LabelShape
|
|
313
293
|
})
|
|
314
294
|
.catchall(z.unknown())
|
|
315
|
-
.superRefine(
|
|
316
|
-
createSelectorRefinement(Object.keys(LabelShape), LabelPropertiesSchema)
|
|
317
|
-
);
|
|
295
|
+
.superRefine(createSelectorRefinement(Object.keys(LabelShape), LabelPropertiesSchema));
|
|
318
296
|
|
|
319
297
|
const MarkerShape = {
|
|
320
298
|
offset: GraphStyleValueSchema.optional(),
|
|
@@ -333,9 +311,7 @@ const MarkerStylesheetSchema = z
|
|
|
333
311
|
...MarkerShape
|
|
334
312
|
})
|
|
335
313
|
.catchall(z.unknown())
|
|
336
|
-
.superRefine(
|
|
337
|
-
createSelectorRefinement(Object.keys(MarkerShape), MarkerPropertiesSchema)
|
|
338
|
-
);
|
|
314
|
+
.superRefine(createSelectorRefinement(Object.keys(MarkerShape), MarkerPropertiesSchema));
|
|
339
315
|
|
|
340
316
|
const EdgeUpperShape = {
|
|
341
317
|
stroke: GraphStyleValueSchema.optional(),
|
|
@@ -350,12 +326,7 @@ const EdgeUpperStylesheetSchema = z
|
|
|
350
326
|
...EdgeUpperShape
|
|
351
327
|
})
|
|
352
328
|
.catchall(z.unknown())
|
|
353
|
-
.superRefine(
|
|
354
|
-
createSelectorRefinement(
|
|
355
|
-
Object.keys(EdgeUpperShape),
|
|
356
|
-
EdgeUpperPropertiesSchema
|
|
357
|
-
)
|
|
358
|
-
);
|
|
329
|
+
.superRefine(createSelectorRefinement(Object.keys(EdgeUpperShape), EdgeUpperPropertiesSchema));
|
|
359
330
|
|
|
360
331
|
const EdgeLowerShape = {
|
|
361
332
|
stroke: GraphStyleValueSchema.optional(),
|
|
@@ -370,12 +341,7 @@ const EdgeLowerStylesheetSchema = z
|
|
|
370
341
|
...EdgeLowerShape
|
|
371
342
|
})
|
|
372
343
|
.catchall(z.unknown())
|
|
373
|
-
.superRefine(
|
|
374
|
-
createSelectorRefinement(
|
|
375
|
-
Object.keys(EdgeLowerShape),
|
|
376
|
-
EdgeLowerPropertiesSchema
|
|
377
|
-
)
|
|
378
|
-
);
|
|
344
|
+
.superRefine(createSelectorRefinement(Object.keys(EdgeLowerShape), EdgeLowerPropertiesSchema));
|
|
379
345
|
|
|
380
346
|
const EdgeLabelShape = {
|
|
381
347
|
color: GraphStyleValueSchema.optional(),
|
|
@@ -397,12 +363,7 @@ const EdgeLabelStylesheetSchema = z
|
|
|
397
363
|
...EdgeLabelShape
|
|
398
364
|
})
|
|
399
365
|
.catchall(z.unknown())
|
|
400
|
-
.superRefine(
|
|
401
|
-
createSelectorRefinement(
|
|
402
|
-
Object.keys(EdgeLabelShape),
|
|
403
|
-
EdgeLabelPropertiesSchema
|
|
404
|
-
)
|
|
405
|
-
);
|
|
366
|
+
.superRefine(createSelectorRefinement(Object.keys(EdgeLabelShape), EdgeLabelPropertiesSchema));
|
|
406
367
|
|
|
407
368
|
const FlowShape = {
|
|
408
369
|
color: GraphStyleValueSchema.optional(),
|
|
@@ -419,9 +380,7 @@ const FlowStylesheetSchema = z
|
|
|
419
380
|
...FlowShape
|
|
420
381
|
})
|
|
421
382
|
.catchall(z.unknown())
|
|
422
|
-
.superRefine(
|
|
423
|
-
createSelectorRefinement(Object.keys(FlowShape), FlowPropertiesSchema)
|
|
424
|
-
);
|
|
383
|
+
.superRefine(createSelectorRefinement(Object.keys(FlowShape), FlowPropertiesSchema));
|
|
425
384
|
|
|
426
385
|
const ArrowShape = {
|
|
427
386
|
color: GraphStyleValueSchema.optional(),
|
|
@@ -437,9 +396,7 @@ const ArrowStylesheetSchema = z
|
|
|
437
396
|
...ArrowShape
|
|
438
397
|
})
|
|
439
398
|
.catchall(z.unknown())
|
|
440
|
-
.superRefine(
|
|
441
|
-
createSelectorRefinement(Object.keys(ArrowShape), ArrowPropertiesSchema)
|
|
442
|
-
);
|
|
399
|
+
.superRefine(createSelectorRefinement(Object.keys(ArrowShape), ArrowPropertiesSchema));
|
|
443
400
|
|
|
444
401
|
const GraphNodeStylesheetVariants = [
|
|
445
402
|
CircleStylesheetSchema,
|
|
@@ -458,10 +415,7 @@ const GraphEdgeStylesheetVariants = [
|
|
|
458
415
|
ArrowStylesheetSchema
|
|
459
416
|
];
|
|
460
417
|
|
|
461
|
-
const GraphStyleRuleVariants = [
|
|
462
|
-
...GraphNodeStylesheetVariants,
|
|
463
|
-
...GraphEdgeStylesheetVariants
|
|
464
|
-
];
|
|
418
|
+
const GraphStyleRuleVariants = [...GraphNodeStylesheetVariants, ...GraphEdgeStylesheetVariants];
|
|
465
419
|
|
|
466
420
|
type GraphStyleRuleVariantSchema = (typeof GraphStyleRuleVariants)[number];
|
|
467
421
|
|
|
@@ -470,10 +424,7 @@ type GraphStyleRuleVariantSchema = (typeof GraphStyleRuleVariants)[number];
|
|
|
470
424
|
*/
|
|
471
425
|
export const GraphStyleRuleSchema = z.discriminatedUnion(
|
|
472
426
|
'type',
|
|
473
|
-
GraphStyleRuleVariants as [
|
|
474
|
-
GraphStyleRuleVariantSchema,
|
|
475
|
-
...GraphStyleRuleVariantSchema[]
|
|
476
|
-
]
|
|
427
|
+
GraphStyleRuleVariants as [GraphStyleRuleVariantSchema, ...GraphStyleRuleVariantSchema[]]
|
|
477
428
|
);
|
|
478
429
|
|
|
479
430
|
/**
|
|
@@ -493,17 +444,18 @@ const GraphNodeStyleRuleSchema = z.discriminatedUnion(
|
|
|
493
444
|
]
|
|
494
445
|
);
|
|
495
446
|
|
|
496
|
-
const GraphEdgeDecoratorRuleSchema = z.discriminatedUnion(
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
447
|
+
const GraphEdgeDecoratorRuleSchema = z.discriminatedUnion('type', [
|
|
448
|
+
EdgeLabelStylesheetSchema,
|
|
449
|
+
FlowStylesheetSchema,
|
|
450
|
+
ArrowStylesheetSchema
|
|
451
|
+
] as [
|
|
452
|
+
typeof EdgeLabelStylesheetSchema,
|
|
453
|
+
typeof FlowStylesheetSchema,
|
|
454
|
+
typeof ArrowStylesheetSchema,
|
|
455
|
+
...Array<
|
|
456
|
+
typeof EdgeLabelStylesheetSchema | typeof FlowStylesheetSchema | typeof ArrowStylesheetSchema
|
|
457
|
+
>
|
|
458
|
+
]);
|
|
507
459
|
|
|
508
460
|
const EdgeUpperWithDecoratorsSchema = EdgeUpperStylesheetSchema.safeExtend({
|
|
509
461
|
decorators: z.array(GraphEdgeDecoratorRuleSchema).optional()
|
|
@@ -154,7 +154,6 @@ type SupportedScale =
|
|
|
154
154
|
| ReturnType<typeof scaleLinear>
|
|
155
155
|
| ReturnType<typeof scaleLog>
|
|
156
156
|
| ReturnType<typeof scalePow>
|
|
157
|
-
|
|
158
157
|
| ReturnType<typeof scaleQuantize>
|
|
159
158
|
| ReturnType<typeof scaleQuantile>
|
|
160
159
|
| ReturnType<typeof scaleOrdinal>;
|
|
@@ -194,10 +193,18 @@ function createScaleFromConfig(config: GraphStyleScale): SupportedScale {
|
|
|
194
193
|
if (config.range && 'range' in scale) {
|
|
195
194
|
anyScale.range(config.range as never);
|
|
196
195
|
}
|
|
197
|
-
if (
|
|
196
|
+
if (
|
|
197
|
+
typeof config.clamp === 'boolean' &&
|
|
198
|
+
'clamp' in scale &&
|
|
199
|
+
typeof anyScale.clamp === 'function'
|
|
200
|
+
) {
|
|
198
201
|
anyScale.clamp(config.clamp);
|
|
199
202
|
}
|
|
200
|
-
if (
|
|
203
|
+
if (
|
|
204
|
+
typeof config.nice !== 'undefined' &&
|
|
205
|
+
'nice' in scale &&
|
|
206
|
+
typeof anyScale.nice === 'function'
|
|
207
|
+
) {
|
|
201
208
|
anyScale.nice(config.nice as never);
|
|
202
209
|
}
|
|
203
210
|
if (
|
|
@@ -273,12 +280,22 @@ function isAttributeReference(value: unknown): value is GraphStyleAttributeRefer
|
|
|
273
280
|
if (typeof value === 'string') {
|
|
274
281
|
return value.startsWith('@');
|
|
275
282
|
}
|
|
276
|
-
return
|
|
283
|
+
return (
|
|
284
|
+
Boolean(value) &&
|
|
285
|
+
typeof value === 'object' &&
|
|
286
|
+
!Array.isArray(value) &&
|
|
287
|
+
'attribute' in (value as Record<string, unknown>)
|
|
288
|
+
);
|
|
277
289
|
}
|
|
278
290
|
|
|
279
291
|
/** Determine whether a style value maps interaction states. */
|
|
280
292
|
function isStatefulValue(value: unknown): value is Record<string, GraphStyleLeafValue> {
|
|
281
|
-
return
|
|
293
|
+
return (
|
|
294
|
+
Boolean(value) &&
|
|
295
|
+
typeof value === 'object' &&
|
|
296
|
+
!Array.isArray(value) &&
|
|
297
|
+
!isAttributeReference(value)
|
|
298
|
+
);
|
|
282
299
|
}
|
|
283
300
|
|
|
284
301
|
/** Resolve an attribute from a datum or `Graph` entity. */
|
|
@@ -424,7 +441,9 @@ function createStatefulAccessor(
|
|
|
424
441
|
}
|
|
425
442
|
|
|
426
443
|
const defaultValue =
|
|
427
|
-
typeof valueMap.default !== 'undefined'
|
|
444
|
+
typeof valueMap.default !== 'undefined'
|
|
445
|
+
? valueMap.default
|
|
446
|
+
: parseLeafValue(key, undefined).value;
|
|
428
447
|
|
|
429
448
|
const accessor = (datum: any) => {
|
|
430
449
|
const stateValue = datum?.state ? valueMap[datum.state] : undefined;
|
|
@@ -460,11 +479,7 @@ export class StyleProperty {
|
|
|
460
479
|
this._updateTrigger = false;
|
|
461
480
|
|
|
462
481
|
if (isStatefulValue(value)) {
|
|
463
|
-
const {accessor, updateTrigger: triggers} = createStatefulAccessor(
|
|
464
|
-
key,
|
|
465
|
-
value,
|
|
466
|
-
updateTrigger
|
|
467
|
-
);
|
|
482
|
+
const {accessor, updateTrigger: triggers} = createStatefulAccessor(key, value, updateTrigger);
|
|
468
483
|
this._value = accessor;
|
|
469
484
|
this._valueType = VALUE_TYPE.ACCESSOR;
|
|
470
485
|
this._updateTrigger = triggers;
|