data-navigator 2.2.0 → 2.2.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/README.md +22 -53
- package/dist/chunk-MPFBSVCV.js +1 -0
- package/dist/{chunk-PEL3ZYDS.mjs → chunk-TZKH227U.js} +1 -1
- package/dist/consts.cjs +1 -0
- package/dist/consts.js +1 -1
- package/dist/examples/basic_list/bokeh.d.ts +1 -0
- package/dist/examples/bokeh.d.ts +1 -0
- package/dist/examples/docs.d.ts +1 -0
- package/dist/examples/force-graph.d.ts +3 -1
- package/dist/index.cjs +1453 -0
- package/dist/index.js +1262 -1375
- package/dist/input.cjs +1 -0
- package/dist/input.js +1 -1
- package/dist/rendering.cjs +1 -0
- package/dist/rendering.js +1 -1
- package/dist/structure.cjs +1 -0
- package/dist/structure.js +1 -1
- package/dist/utilities.cjs +1 -0
- package/dist/utilities.js +1 -1
- package/package.json +13 -18
- package/dist/chunk-2RRWU73A.mjs +0 -1
- package/dist/chunk-AJKFNWNF.mjs +0 -1
- package/dist/chunk-CCACYVYB.mjs +0 -1
- package/dist/chunk-CR5KNX3N.mjs +0 -1
- package/dist/chunk-FFVDZNCV.mjs +0 -1
- package/dist/chunk-GP5LYFFJ.mjs +0 -1
- package/dist/chunk-QTJ23SVE.mjs +0 -18
- package/dist/chunk-SQY245BV.mjs +0 -177
- package/dist/chunk-UIGW7IEM.mjs +0 -1
- package/dist/chunk-XICEDMQZ.mjs +0 -1
- package/dist/chunk-ZAQVAU5P.mjs +0 -1
- package/dist/consts.mjs +0 -1
- package/dist/index.mjs +0 -1339
- package/dist/input.mjs +0 -1
- package/dist/rendering.mjs +0 -1
- package/dist/structure.mjs +0 -1
- package/dist/utilities.mjs +0 -1
- /package/dist/{chunk-K476QBP2.mjs → chunk-YE5N6UCT.js} +0 -0
- /package/dist/{src/test-cases.d.ts → examples/basic_list/basic_list.d.ts} +0 -0
package/dist/index.mjs
DELETED
|
@@ -1,1339 +0,0 @@
|
|
|
1
|
-
// src/consts.ts
|
|
2
|
-
var SemanticKeys = {
|
|
3
|
-
Escape: true,
|
|
4
|
-
Enter: true,
|
|
5
|
-
Backspace: true,
|
|
6
|
-
ArrowLeft: true,
|
|
7
|
-
ArrowRight: true,
|
|
8
|
-
ArrowUp: true,
|
|
9
|
-
ArrowDown: true
|
|
10
|
-
};
|
|
11
|
-
var defaultKeyBindings = {
|
|
12
|
-
ArrowLeft: "left",
|
|
13
|
-
ArrowRight: "right",
|
|
14
|
-
ArrowUp: "up",
|
|
15
|
-
ArrowDown: "down",
|
|
16
|
-
Period: "forward",
|
|
17
|
-
Comma: "backward",
|
|
18
|
-
Escape: "parent",
|
|
19
|
-
Enter: "child"
|
|
20
|
-
};
|
|
21
|
-
var TypicallyUnreservedKeys = ["KeyW", "KeyJ", "LeftBracket", "RightBracket", "Slash", "Backslash"];
|
|
22
|
-
var TypicallyUnreservedKeyPairs = [
|
|
23
|
-
["LeftBracket", "RightBracket"],
|
|
24
|
-
["Slash", "Backslash"]
|
|
25
|
-
];
|
|
26
|
-
var GenericFullNavigationRules = {
|
|
27
|
-
left: {
|
|
28
|
-
key: "ArrowLeft",
|
|
29
|
-
direction: "source"
|
|
30
|
-
},
|
|
31
|
-
right: {
|
|
32
|
-
key: "ArrowRight",
|
|
33
|
-
direction: "target"
|
|
34
|
-
},
|
|
35
|
-
up: {
|
|
36
|
-
key: "ArrowUp",
|
|
37
|
-
direction: "source"
|
|
38
|
-
},
|
|
39
|
-
down: {
|
|
40
|
-
key: "ArrowDown",
|
|
41
|
-
direction: "target"
|
|
42
|
-
},
|
|
43
|
-
child: {
|
|
44
|
-
key: "Enter",
|
|
45
|
-
direction: "target"
|
|
46
|
-
},
|
|
47
|
-
parent: {
|
|
48
|
-
key: "Backspace",
|
|
49
|
-
direction: "source"
|
|
50
|
-
},
|
|
51
|
-
backward: {
|
|
52
|
-
key: "Comma",
|
|
53
|
-
direction: "source"
|
|
54
|
-
},
|
|
55
|
-
forward: {
|
|
56
|
-
key: "Period",
|
|
57
|
-
direction: "target"
|
|
58
|
-
},
|
|
59
|
-
previous: {
|
|
60
|
-
key: "Semicolon",
|
|
61
|
-
direction: "source"
|
|
62
|
-
},
|
|
63
|
-
next: {
|
|
64
|
-
key: "Quote",
|
|
65
|
-
direction: "target"
|
|
66
|
-
},
|
|
67
|
-
exit: {
|
|
68
|
-
key: "Escape",
|
|
69
|
-
direction: "target"
|
|
70
|
-
},
|
|
71
|
-
help: {
|
|
72
|
-
key: "KeyY",
|
|
73
|
-
direction: "target"
|
|
74
|
-
},
|
|
75
|
-
undo: {
|
|
76
|
-
key: "KeyZ",
|
|
77
|
-
direction: "target"
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
var GenericFullNavigationDimensions = [
|
|
81
|
-
["left", "right"],
|
|
82
|
-
["up", "down"],
|
|
83
|
-
["backward", "forward"],
|
|
84
|
-
["previous", "next"]
|
|
85
|
-
];
|
|
86
|
-
var GenericLimitedNavigationRules = {
|
|
87
|
-
right: {
|
|
88
|
-
key: "ArrowRight",
|
|
89
|
-
direction: "target"
|
|
90
|
-
},
|
|
91
|
-
left: {
|
|
92
|
-
key: "ArrowLeft",
|
|
93
|
-
direction: "source"
|
|
94
|
-
},
|
|
95
|
-
down: {
|
|
96
|
-
key: "ArrowDown",
|
|
97
|
-
direction: "target"
|
|
98
|
-
},
|
|
99
|
-
up: {
|
|
100
|
-
key: "ArrowUp",
|
|
101
|
-
direction: "source"
|
|
102
|
-
},
|
|
103
|
-
child: {
|
|
104
|
-
key: "Enter",
|
|
105
|
-
direction: "target"
|
|
106
|
-
},
|
|
107
|
-
parent: {
|
|
108
|
-
key: "Backspace",
|
|
109
|
-
direction: "source"
|
|
110
|
-
},
|
|
111
|
-
exit: {
|
|
112
|
-
key: "Escape",
|
|
113
|
-
direction: "target"
|
|
114
|
-
},
|
|
115
|
-
undo: {
|
|
116
|
-
key: "Period",
|
|
117
|
-
direction: "target"
|
|
118
|
-
},
|
|
119
|
-
legend: {
|
|
120
|
-
key: "KeyL",
|
|
121
|
-
direction: "target"
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
var NodeElementDefaults = {
|
|
125
|
-
cssClass: "",
|
|
126
|
-
spatialProperties: {
|
|
127
|
-
x: 0,
|
|
128
|
-
y: 0,
|
|
129
|
-
width: 0,
|
|
130
|
-
height: 0,
|
|
131
|
-
path: ""
|
|
132
|
-
},
|
|
133
|
-
semantics: {
|
|
134
|
-
label: "",
|
|
135
|
-
elementType: "div",
|
|
136
|
-
role: "image",
|
|
137
|
-
attributes: void 0
|
|
138
|
-
},
|
|
139
|
-
parentSemantics: {
|
|
140
|
-
label: "",
|
|
141
|
-
elementType: "figure",
|
|
142
|
-
role: "figure",
|
|
143
|
-
attributes: void 0
|
|
144
|
-
},
|
|
145
|
-
existingElement: {
|
|
146
|
-
useForSpatialProperties: false,
|
|
147
|
-
spatialProperties: void 0
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
// src/utilities.ts
|
|
152
|
-
var describeNode = (d, descriptionOptions) => {
|
|
153
|
-
const keys = Object.keys(d);
|
|
154
|
-
let description = "";
|
|
155
|
-
keys.forEach((key) => {
|
|
156
|
-
description += `${descriptionOptions && descriptionOptions.omitKeyNames ? "" : key + ": "}${d[key]}. `;
|
|
157
|
-
});
|
|
158
|
-
description += descriptionOptions && descriptionOptions.semanticLabel || "Data point.";
|
|
159
|
-
return description;
|
|
160
|
-
};
|
|
161
|
-
var createValidId = (s) => {
|
|
162
|
-
return "_" + s.replace(/[^a-zA-Z0-9_-]+/g, "_");
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
// src/structure.ts
|
|
166
|
-
var structure_default = (options) => {
|
|
167
|
-
if (options.dataType === "vega-lite" || options.dataType === "vl" || options.dataType === "Vega-Lite") {
|
|
168
|
-
return buildNodeStructureFromVegaLite(options);
|
|
169
|
-
} else {
|
|
170
|
-
return buildStructure(options);
|
|
171
|
-
}
|
|
172
|
-
};
|
|
173
|
-
var buildNodeStructureFromVegaLite = (options) => {
|
|
174
|
-
let navigationRules = GenericLimitedNavigationRules;
|
|
175
|
-
let nodes = {};
|
|
176
|
-
let edges = {};
|
|
177
|
-
let elementData = {};
|
|
178
|
-
let total = 0;
|
|
179
|
-
const includeGroup = options.groupInclusionCriteria ? options.groupInclusionCriteria : () => true;
|
|
180
|
-
const includeItem = options.itemInclusionCriteria ? options.itemInclusionCriteria : () => true;
|
|
181
|
-
const includeDataProperties = options.datumInclusionCriteria ? options.datumInclusionCriteria : () => true;
|
|
182
|
-
const offset = options.vegaLiteView._renderer._origin;
|
|
183
|
-
const groupParent = options.vegaLiteView._scenegraph.root.items[0].mark.items[0];
|
|
184
|
-
const idBuilder = (i2, level) => {
|
|
185
|
-
if (i2["data-navigator-id"]) {
|
|
186
|
-
return i2["data-navigator-id"];
|
|
187
|
-
}
|
|
188
|
-
const id = `dn-node-${level}-${total}`;
|
|
189
|
-
total++;
|
|
190
|
-
i2["data-navigator-id"] = id;
|
|
191
|
-
return id;
|
|
192
|
-
};
|
|
193
|
-
const edgeBuilder = (id) => {
|
|
194
|
-
const node = nodes[id];
|
|
195
|
-
const index = node.index;
|
|
196
|
-
const level = node.level;
|
|
197
|
-
const parent = node.parent;
|
|
198
|
-
const edgeList = [];
|
|
199
|
-
const previous = parent.items[index - 1];
|
|
200
|
-
if (previous) {
|
|
201
|
-
const previousId = idBuilder(previous, level);
|
|
202
|
-
if (nodes[previousId]) {
|
|
203
|
-
const previousEdge = `${previousId}-${node.id}`;
|
|
204
|
-
edgeList.push(previousEdge);
|
|
205
|
-
if (!edges[previousEdge]) {
|
|
206
|
-
edges[previousEdge] = {
|
|
207
|
-
source: previousId,
|
|
208
|
-
target: node.id,
|
|
209
|
-
navigationRules: ["left", "right"]
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
const next = parent.items[index + 1];
|
|
215
|
-
if (next) {
|
|
216
|
-
const nextId = idBuilder(next, level);
|
|
217
|
-
if (nodes[nextId]) {
|
|
218
|
-
const nextEdge = `${node.id}-${nextId}`;
|
|
219
|
-
edgeList.push(nextEdge);
|
|
220
|
-
if (!edges[nextEdge]) {
|
|
221
|
-
edges[nextEdge] = {
|
|
222
|
-
source: node.id,
|
|
223
|
-
target: nextId,
|
|
224
|
-
navigationRules: ["left", "right"]
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
if (level === "group" && parent.items[index].items) {
|
|
230
|
-
const g = parent.items[index].items[0].mark.items[0].items || parent.items[index].items;
|
|
231
|
-
const firstChild = g[0];
|
|
232
|
-
const firstChildId = idBuilder(firstChild, "item");
|
|
233
|
-
if (nodes[firstChildId]) {
|
|
234
|
-
const firstChildEdge = `${node.id}-${firstChildId}`;
|
|
235
|
-
edgeList.push(firstChildEdge);
|
|
236
|
-
if (!edges[firstChildEdge]) {
|
|
237
|
-
edges[firstChildEdge] = {
|
|
238
|
-
source: node.id,
|
|
239
|
-
target: firstChildId,
|
|
240
|
-
navigationRules: ["parent", "child"]
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
} else if (level === "item") {
|
|
245
|
-
const parentId = idBuilder(parent, "group");
|
|
246
|
-
if (nodes[parentId]) {
|
|
247
|
-
const parentEdge = `${parentId}-${node.id}`;
|
|
248
|
-
edgeList.push(parentEdge);
|
|
249
|
-
if (!edges[parentEdge]) {
|
|
250
|
-
edges[parentEdge] = {
|
|
251
|
-
source: parentId,
|
|
252
|
-
target: node.id,
|
|
253
|
-
navigationRules: ["parent", "child"]
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
if (options.exitFunction) {
|
|
259
|
-
edgeList.push("any-exit");
|
|
260
|
-
if (!edges["any-exit"]) {
|
|
261
|
-
edges["any-exit"] = {
|
|
262
|
-
source: options.getCurrent,
|
|
263
|
-
target: options.exitFunction,
|
|
264
|
-
navigationRules: ["exit"]
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
edgeList.push("any-undo");
|
|
269
|
-
if (!edges["any-undo"]) {
|
|
270
|
-
edges["any-undo"] = {
|
|
271
|
-
source: options.getCurrent,
|
|
272
|
-
target: options.getPrevious,
|
|
273
|
-
navigationRules: ["undo"]
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
return edgeList;
|
|
277
|
-
};
|
|
278
|
-
const nodeBuilder = (item, level, offset2, index, parent) => {
|
|
279
|
-
const id = idBuilder(item, level);
|
|
280
|
-
const renderId = "render-" + id;
|
|
281
|
-
const o = offset2 || [0, 0];
|
|
282
|
-
nodes[id] = {};
|
|
283
|
-
nodes[id].d = {};
|
|
284
|
-
nodes[id].id = id;
|
|
285
|
-
nodes[id].renderId = renderId;
|
|
286
|
-
nodes[id].index = index;
|
|
287
|
-
nodes[id].level = level;
|
|
288
|
-
nodes[id].parent = parent;
|
|
289
|
-
elementData[renderId] = {};
|
|
290
|
-
elementData[renderId].renderId = renderId;
|
|
291
|
-
elementData[renderId].spatialProperties = {};
|
|
292
|
-
elementData[renderId].spatialProperties.x = item.bounds.x1 + o[0];
|
|
293
|
-
elementData[renderId].spatialProperties.y = item.bounds.y1 + o[1];
|
|
294
|
-
elementData[renderId].spatialProperties.width = item.bounds.x2 - item.bounds.x1;
|
|
295
|
-
elementData[renderId].spatialProperties.height = item.bounds.y2 - item.bounds.y1;
|
|
296
|
-
elementData[renderId].cssClass = "dn-vega-lite-node";
|
|
297
|
-
if (item.datum) {
|
|
298
|
-
Object.keys(item.datum).forEach((key) => {
|
|
299
|
-
const value = item.datum[key];
|
|
300
|
-
if (includeDataProperties(key, value, item.datum, level, options.vegaLiteSpec)) {
|
|
301
|
-
nodes[id].d[options.keyRenamingHash && options.keyRenamingHash[key] ? options.keyRenamingHash[key] : key] = value;
|
|
302
|
-
}
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
elementData[renderId].semantics = {};
|
|
306
|
-
elementData[renderId].semantics.label = options.nodeDescriber ? options.nodeDescriber(nodes[id].d, item, level) : describeNode(nodes[id].d);
|
|
307
|
-
};
|
|
308
|
-
let i = 0;
|
|
309
|
-
const groups = groupParent.items;
|
|
310
|
-
groups.forEach((group) => {
|
|
311
|
-
if (includeGroup(group, i, options.vegaLiteSpec)) {
|
|
312
|
-
nodeBuilder(group, "group", offset, i, groupParent);
|
|
313
|
-
let j = 0;
|
|
314
|
-
const g = group.items[0].mark.items[0].items ? group.items[0].mark.items[0] : group;
|
|
315
|
-
g.items.forEach((item) => {
|
|
316
|
-
if (includeItem(item, j, group, options.vegaLiteSpec)) {
|
|
317
|
-
nodeBuilder(item, "item", offset, j, g);
|
|
318
|
-
}
|
|
319
|
-
j++;
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
i++;
|
|
323
|
-
});
|
|
324
|
-
Object.keys(nodes).forEach((n) => {
|
|
325
|
-
nodes[n].edges = edgeBuilder(n);
|
|
326
|
-
});
|
|
327
|
-
return {
|
|
328
|
-
nodes,
|
|
329
|
-
edges,
|
|
330
|
-
elementData,
|
|
331
|
-
navigationRules
|
|
332
|
-
};
|
|
333
|
-
};
|
|
334
|
-
var addSimpleDataIDs = (options) => {
|
|
335
|
-
let i = 0;
|
|
336
|
-
let keyCounter = {};
|
|
337
|
-
options.data.forEach((d) => {
|
|
338
|
-
const id = typeof options.idKey === "function" ? options.idKey(d) : options.idKey;
|
|
339
|
-
d[id] = "_" + i;
|
|
340
|
-
if (options.keysForIdGeneration) {
|
|
341
|
-
options.keysForIdGeneration.forEach((k) => {
|
|
342
|
-
if (k in d) {
|
|
343
|
-
if (typeof d[k] === "string") {
|
|
344
|
-
if (!keyCounter[k]) {
|
|
345
|
-
keyCounter[k] = 0;
|
|
346
|
-
}
|
|
347
|
-
if (!keyCounter[d[k]]) {
|
|
348
|
-
keyCounter[d[k]] = 0;
|
|
349
|
-
}
|
|
350
|
-
d[id] += "_" + k + keyCounter[k] + "_" + d[k] + keyCounter[d[k]];
|
|
351
|
-
keyCounter[k]++;
|
|
352
|
-
keyCounter[d[k]]++;
|
|
353
|
-
} else {
|
|
354
|
-
if (!keyCounter[k]) {
|
|
355
|
-
keyCounter[k] = 0;
|
|
356
|
-
}
|
|
357
|
-
d[id] += "_" + k + keyCounter[k];
|
|
358
|
-
keyCounter[k]++;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
i++;
|
|
364
|
-
});
|
|
365
|
-
};
|
|
366
|
-
var buildNodes = (options) => {
|
|
367
|
-
let nodes = {};
|
|
368
|
-
options.data.forEach((d) => {
|
|
369
|
-
if (!options.idKey) {
|
|
370
|
-
console.error(
|
|
371
|
-
`Building nodes. A key string must be supplied in options.idKey to specify the id keys of every node.`
|
|
372
|
-
);
|
|
373
|
-
}
|
|
374
|
-
const idKey = typeof options.idKey === "function" ? options.idKey(d) : options.idKey;
|
|
375
|
-
const id = d[idKey];
|
|
376
|
-
if (!id) {
|
|
377
|
-
console.error(
|
|
378
|
-
`Building nodes. Each datum in options.data must contain an id. When matching the id key string ${idKey}, this datum has no id: ${JSON.stringify(
|
|
379
|
-
d
|
|
380
|
-
)}.`
|
|
381
|
-
);
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
if (!nodes[id]) {
|
|
385
|
-
const renderIdKey = typeof options.renderIdKey === "function" ? options.renderIdKey(d) : options.renderIdKey;
|
|
386
|
-
nodes[id] = {
|
|
387
|
-
id,
|
|
388
|
-
edges: [],
|
|
389
|
-
renderId: renderIdKey ? d[renderIdKey] || "" : d.renderIdKey || "",
|
|
390
|
-
data: d
|
|
391
|
-
};
|
|
392
|
-
} else {
|
|
393
|
-
console.error(
|
|
394
|
-
`Building nodes. Each id for data in options.data must be unique. This id is not unique: ${id}.`
|
|
395
|
-
);
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
});
|
|
399
|
-
return nodes;
|
|
400
|
-
};
|
|
401
|
-
var scaffoldDimensions = (options, nodes) => {
|
|
402
|
-
let dimensions = {};
|
|
403
|
-
if (options.dimensions?.parentOptions?.addLevel0) {
|
|
404
|
-
let level0 = options.dimensions.parentOptions.addLevel0;
|
|
405
|
-
nodes[level0.id] = { ...level0, dimensionLevel: 0 };
|
|
406
|
-
}
|
|
407
|
-
let rules = [...GenericFullNavigationDimensions];
|
|
408
|
-
const setExtents = (val, dim) => {
|
|
409
|
-
let min = dim.numericalExtents[0];
|
|
410
|
-
let max = dim.numericalExtents[1];
|
|
411
|
-
dim.numericalExtents[0] = min < val ? min : val;
|
|
412
|
-
dim.numericalExtents[1] = max > val ? max : val;
|
|
413
|
-
};
|
|
414
|
-
options.data.forEach((d) => {
|
|
415
|
-
let ods = options.dimensions.values || [];
|
|
416
|
-
let i = 0;
|
|
417
|
-
ods.forEach((dim) => {
|
|
418
|
-
if (!dim.dimensionKey) {
|
|
419
|
-
console.error(
|
|
420
|
-
`Building nodes, parsing dimensions. Each dimension in options.dimensions must contain a dimensionKey. This dimension has no key: ${JSON.stringify(
|
|
421
|
-
dim
|
|
422
|
-
)}.`
|
|
423
|
-
);
|
|
424
|
-
return;
|
|
425
|
-
}
|
|
426
|
-
if (dim.dimensionKey in d) {
|
|
427
|
-
let value = d[dim.dimensionKey];
|
|
428
|
-
let keepValue = typeof dim.operations?.filterFunction === "function" ? dim.operations.filterFunction(d, dim) : true;
|
|
429
|
-
if (value !== void 0 && keepValue) {
|
|
430
|
-
if (!dim.type) {
|
|
431
|
-
dim.type = typeof value === "bigint" || typeof value === "number" ? "numerical" : "categorical";
|
|
432
|
-
}
|
|
433
|
-
if (!dimensions[dim.dimensionKey]) {
|
|
434
|
-
let id2 = typeof dim.nodeId === "function" ? dim.nodeId(dim, options.data) : dim.nodeId || createValidId(dim.dimensionKey);
|
|
435
|
-
let renderId = typeof dim.renderId === "function" ? dim.renderId(dim, options.data) : dim.renderId || id2;
|
|
436
|
-
dimensions[dim.dimensionKey] = {
|
|
437
|
-
dimensionKey: dim.dimensionKey,
|
|
438
|
-
nodeId: id2,
|
|
439
|
-
divisions: {},
|
|
440
|
-
numericalExtents: [Infinity, -Infinity],
|
|
441
|
-
type: dim.type,
|
|
442
|
-
operations: {
|
|
443
|
-
compressSparseDivisions: dim.operations?.compressSparseDivisions || false,
|
|
444
|
-
sortFunction: dim.operations?.sortFunction || void 0
|
|
445
|
-
},
|
|
446
|
-
behavior: dim.behavior || {
|
|
447
|
-
extents: "circular"
|
|
448
|
-
},
|
|
449
|
-
navigationRules: dim.navigationRules || {
|
|
450
|
-
sibling_sibling: rules.length ? [...rules.shift()] : ["previous_" + dim.dimensionKey, "next_" + dim.dimensionKey],
|
|
451
|
-
parent_child: ["parent_" + dim.dimensionKey, "child"]
|
|
452
|
-
}
|
|
453
|
-
};
|
|
454
|
-
nodes[id2] = {
|
|
455
|
-
id: id2,
|
|
456
|
-
renderId,
|
|
457
|
-
derivedNode: dim.dimensionKey,
|
|
458
|
-
edges: [],
|
|
459
|
-
dimensionLevel: 1,
|
|
460
|
-
data: dimensions[dim.dimensionKey],
|
|
461
|
-
renderingStrategy: dim.renderingStrategy || "singleSquare"
|
|
462
|
-
// not sure what defaults we want yet
|
|
463
|
-
};
|
|
464
|
-
}
|
|
465
|
-
let dimension = dimensions[dim.dimensionKey];
|
|
466
|
-
let targetDivision = null;
|
|
467
|
-
if (dim.type === "categorical") {
|
|
468
|
-
let divisionId = typeof dim.divisionOptions?.divisionNodeIds === "function" ? dim.divisionOptions.divisionNodeIds(dim.dimensionKey, value, i) : createValidId(dimension.nodeId + "_" + value);
|
|
469
|
-
targetDivision = dimension.divisions[divisionId];
|
|
470
|
-
if (!targetDivision) {
|
|
471
|
-
targetDivision = dimension.divisions[divisionId] = {
|
|
472
|
-
id: divisionId,
|
|
473
|
-
sortFunction: dim.divisionOptions?.sortFunction || void 0,
|
|
474
|
-
values: {}
|
|
475
|
-
};
|
|
476
|
-
let divisionRenderId = typeof dim.divisionOptions?.divisionRenderIds === "function" ? dim.divisionOptions.divisionRenderIds(dim.dimensionKey, value, i) : divisionId;
|
|
477
|
-
nodes[divisionId] = {
|
|
478
|
-
id: divisionId,
|
|
479
|
-
renderId: divisionRenderId,
|
|
480
|
-
derivedNode: dim.dimensionKey,
|
|
481
|
-
edges: [],
|
|
482
|
-
dimensionLevel: 2,
|
|
483
|
-
data: { ...targetDivision },
|
|
484
|
-
renderingStrategy: dim.divisionOptions?.renderingStrategy || "singleSquare"
|
|
485
|
-
// not sure what defaults we want yet
|
|
486
|
-
};
|
|
487
|
-
nodes[divisionId].data[dim.dimensionKey] = value;
|
|
488
|
-
}
|
|
489
|
-
} else {
|
|
490
|
-
targetDivision = dimension.divisions[dimension.nodeId];
|
|
491
|
-
if (!targetDivision) {
|
|
492
|
-
targetDivision = dimension.divisions[dimension.nodeId] = {
|
|
493
|
-
id: dimension.nodeId,
|
|
494
|
-
sortFunction: dim.divisionOptions?.sortFunction || void 0,
|
|
495
|
-
values: {}
|
|
496
|
-
};
|
|
497
|
-
}
|
|
498
|
-
if (!dim.operations) {
|
|
499
|
-
dim.operations = {};
|
|
500
|
-
}
|
|
501
|
-
let subdivs = dim.operations.createNumericalSubdivisions;
|
|
502
|
-
dimension.subdivisions = typeof subdivs === "number" && subdivs < 1 ? 1 : subdivs || 1;
|
|
503
|
-
if (subdivs !== 1) {
|
|
504
|
-
if (!dimension.divisionOptions) {
|
|
505
|
-
dimension.divisionOptions = dim.divisionOptions;
|
|
506
|
-
}
|
|
507
|
-
setExtents(value, dimension);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
const id = typeof options.idKey === "function" ? options.idKey(d) : options.idKey;
|
|
511
|
-
targetDivision.values[d[id]] = d;
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
i++;
|
|
515
|
-
});
|
|
516
|
-
});
|
|
517
|
-
Object.keys(dimensions).forEach((s) => {
|
|
518
|
-
let dimension = dimensions[s];
|
|
519
|
-
let divisions = dimension.divisions;
|
|
520
|
-
if (dimension.type === "numerical") {
|
|
521
|
-
divisions[dimension.nodeId].values = Object.fromEntries(
|
|
522
|
-
Object.entries(divisions[dimension.nodeId].values).sort((a, b) => {
|
|
523
|
-
return typeof dimension.operations?.sortFunction === "function" ? dimension.operations.sortFunction(a[1], b[1], dimension) : a[1][s] - b[1][s];
|
|
524
|
-
})
|
|
525
|
-
);
|
|
526
|
-
let values = divisions[dimension.nodeId].values;
|
|
527
|
-
if (dimension.numericalExtents[0] !== Infinity && dimension.subdivisions !== 1) {
|
|
528
|
-
let valueKeys = Object.keys(values);
|
|
529
|
-
let subDivisions = typeof dimension.subdivisions === "function" ? dimension.subdivisions(s, values) : dimension.subdivisions;
|
|
530
|
-
let range = dimension.numericalExtents[1] - dimension.numericalExtents[0];
|
|
531
|
-
let interval = range / subDivisions;
|
|
532
|
-
let i = dimension.numericalExtents[0] + interval;
|
|
533
|
-
let divisionCount = 0;
|
|
534
|
-
let index = 0;
|
|
535
|
-
for (i = dimension.numericalExtents[0] + interval; i <= dimension.numericalExtents[1]; i += interval) {
|
|
536
|
-
let divisionId = typeof dimension.divisionOptions?.divisionNodeIds === "function" ? dimension.divisionOptions.divisionNodeIds(s, i, i) : dimension.nodeId + "_" + i;
|
|
537
|
-
dimension.divisions[divisionId] = {
|
|
538
|
-
id: divisionId,
|
|
539
|
-
sortFunction: dimension.divisionOptions?.sortFunction || void 0,
|
|
540
|
-
values: {}
|
|
541
|
-
};
|
|
542
|
-
let divisionRenderId = typeof dimension.divisionOptions?.divisionRenderIds === "function" ? dimension.divisionOptions.divisionRenderIds(s, i, i) : divisionId;
|
|
543
|
-
nodes[divisionId] = {
|
|
544
|
-
id: divisionId,
|
|
545
|
-
renderId: divisionRenderId,
|
|
546
|
-
derivedNode: s,
|
|
547
|
-
edges: [],
|
|
548
|
-
data: dimension.divisions[divisionId],
|
|
549
|
-
dimensionLevel: 2,
|
|
550
|
-
renderingStrategy: dimension.divisionOptions?.renderingStrategy || "singleSquare"
|
|
551
|
-
// not sure what defaults we want yet
|
|
552
|
-
};
|
|
553
|
-
let limit = false;
|
|
554
|
-
while (!limit && index < valueKeys.length) {
|
|
555
|
-
let node = values[valueKeys[index]];
|
|
556
|
-
let value = node[s];
|
|
557
|
-
if (value <= i) {
|
|
558
|
-
dimension.divisions[divisionId].values[node.id] = node;
|
|
559
|
-
} else {
|
|
560
|
-
i += interval;
|
|
561
|
-
limit = true;
|
|
562
|
-
}
|
|
563
|
-
index++;
|
|
564
|
-
}
|
|
565
|
-
divisionCount++;
|
|
566
|
-
}
|
|
567
|
-
delete divisions[s];
|
|
568
|
-
}
|
|
569
|
-
} else if (typeof dimension.operations?.sortFunction === "function") {
|
|
570
|
-
dimension.divisions = Object.fromEntries(
|
|
571
|
-
Object.entries(divisions).sort((a, b) => {
|
|
572
|
-
return dimension.operations.sortFunction(a[1], b[1], dimension);
|
|
573
|
-
})
|
|
574
|
-
);
|
|
575
|
-
}
|
|
576
|
-
let divisionKeys = Object.keys(dimension.divisions);
|
|
577
|
-
divisionKeys.forEach((d) => {
|
|
578
|
-
let division = dimension.divisions[d];
|
|
579
|
-
if (typeof division.sortFunction === "function") {
|
|
580
|
-
division.values = Object.fromEntries(
|
|
581
|
-
Object.entries(division.values).sort((a, b) => {
|
|
582
|
-
return division.sortFunction(a[1], b[1], division);
|
|
583
|
-
})
|
|
584
|
-
);
|
|
585
|
-
}
|
|
586
|
-
});
|
|
587
|
-
});
|
|
588
|
-
Object.keys(dimensions).forEach((s) => {
|
|
589
|
-
let dimension = dimensions[s];
|
|
590
|
-
if (dimension.operations.compressSparseDivisions) {
|
|
591
|
-
const divisionKeys = Object.keys(dimension.divisions);
|
|
592
|
-
const values = {};
|
|
593
|
-
let sparse = true;
|
|
594
|
-
divisionKeys.forEach((d) => {
|
|
595
|
-
const division = dimension.divisions[d];
|
|
596
|
-
const valueKeys = Object.keys(division.values);
|
|
597
|
-
if (valueKeys.length <= 1) {
|
|
598
|
-
valueKeys.forEach((vk) => {
|
|
599
|
-
values[vk] = { ...division.values[vk] };
|
|
600
|
-
});
|
|
601
|
-
} else {
|
|
602
|
-
sparse = false;
|
|
603
|
-
}
|
|
604
|
-
});
|
|
605
|
-
if (sparse) {
|
|
606
|
-
const newDivision = {
|
|
607
|
-
id: dimension.nodeId,
|
|
608
|
-
values
|
|
609
|
-
};
|
|
610
|
-
divisionKeys.forEach((d) => {
|
|
611
|
-
delete nodes[d];
|
|
612
|
-
});
|
|
613
|
-
dimension.divisions = {};
|
|
614
|
-
dimension.divisions[dimension.nodeId] = newDivision;
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
});
|
|
618
|
-
if (options.dimensions.adjustDimensions) {
|
|
619
|
-
dimensions = options.dimensions.adjustDimensions(dimensions);
|
|
620
|
-
}
|
|
621
|
-
return dimensions;
|
|
622
|
-
};
|
|
623
|
-
var buildEdges = (options, nodes, dimensions) => {
|
|
624
|
-
let edges = {};
|
|
625
|
-
const addEdgeToNode = (nodeId, edgeId) => {
|
|
626
|
-
if (nodes[nodeId].edges.indexOf(edgeId) === -1) {
|
|
627
|
-
nodes[nodeId].edges.push(edgeId);
|
|
628
|
-
}
|
|
629
|
-
};
|
|
630
|
-
const createEdge = (source, target, rules, addTo) => {
|
|
631
|
-
const id = `${source}-${target}`;
|
|
632
|
-
let targetId = !options.useDirectedEdges ? id : `${target}-${id}`;
|
|
633
|
-
let addToSource = !addTo || addTo === "source";
|
|
634
|
-
let addToTarget = !addTo || addTo === "target";
|
|
635
|
-
const checkEdgeRules = (eId) => {
|
|
636
|
-
if (edges[eId]) {
|
|
637
|
-
edges[eId].navigationRules.push(...rules || []);
|
|
638
|
-
} else {
|
|
639
|
-
edges[eId] = {
|
|
640
|
-
source,
|
|
641
|
-
target,
|
|
642
|
-
navigationRules: rules ? [...rules] : []
|
|
643
|
-
};
|
|
644
|
-
}
|
|
645
|
-
};
|
|
646
|
-
checkEdgeRules(id);
|
|
647
|
-
if (options.useDirectedEdges && addToTarget) {
|
|
648
|
-
checkEdgeRules(targetId);
|
|
649
|
-
}
|
|
650
|
-
if (addToSource) {
|
|
651
|
-
addEdgeToNode(source, id);
|
|
652
|
-
}
|
|
653
|
-
if (addToTarget) {
|
|
654
|
-
addEdgeToNode(target, targetId);
|
|
655
|
-
}
|
|
656
|
-
};
|
|
657
|
-
if (dimensions && Object.keys(dimensions).length) {
|
|
658
|
-
const dimensionKeys = Object.keys(dimensions);
|
|
659
|
-
const hasOrder = options.dimensions?.parentOptions?.level1Options?.order;
|
|
660
|
-
let order = hasOrder || dimensionKeys;
|
|
661
|
-
let l = 0;
|
|
662
|
-
let po = options.dimensions?.parentOptions || {};
|
|
663
|
-
let extents = po.level1Options?.behavior?.extents || "terminal";
|
|
664
|
-
let level0 = po.addLevel0;
|
|
665
|
-
let parentRules = level0 ? po.level1Options?.navigationRules?.parent_child || ["parent", "child"] : [];
|
|
666
|
-
let siblingRules = po.level1Options?.navigationRules?.sibling_sibling || ["left", "right"];
|
|
667
|
-
let firstLevel1Node = typeof order[0] === "string" ? hasOrder ? nodes[order[0]] : nodes[dimensions[order[0]].nodeId] : order[0];
|
|
668
|
-
if (level0) {
|
|
669
|
-
createEdge(level0.id, firstLevel1Node.id, parentRules, "source");
|
|
670
|
-
}
|
|
671
|
-
order.forEach((n) => {
|
|
672
|
-
let level1Node = typeof n === "string" ? hasOrder ? nodes[n] : nodes[dimensions[n].nodeId] : n;
|
|
673
|
-
if (level1Node === n && !nodes[level1Node.id]) {
|
|
674
|
-
nodes[level1Node.id] = level1Node;
|
|
675
|
-
}
|
|
676
|
-
if (level0) {
|
|
677
|
-
if (!options.useDirectedEdges) {
|
|
678
|
-
createEdge(level0.id, level1Node.id, parentRules, "target");
|
|
679
|
-
} else {
|
|
680
|
-
createEdge(level1Node.id, level0.id, parentRules, "source");
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
if (l === order.length - 1 && extents === "circular") {
|
|
684
|
-
createEdge(level1Node.id, firstLevel1Node.id, siblingRules);
|
|
685
|
-
} else if (l === order.length - 1 && extents === "bridgedCustom") {
|
|
686
|
-
createEdge(level1Node.id, po.level1Options.behavior.customBridgePost, siblingRules);
|
|
687
|
-
} else if (l < order.length - 1) {
|
|
688
|
-
let nextLevel1Node = typeof order[l + 1] === "string" ? hasOrder ? (
|
|
689
|
-
// @ts-ignore: for some reason the same use of conditional check works above for order[0] (firstLevel1Node) but not for l+1 here
|
|
690
|
-
nodes[order[l + 1]]
|
|
691
|
-
) : (
|
|
692
|
-
// @ts-ignore: for some reason the same use of conditional check works above for order[0] (firstLevel1Node) but not for l+1 here
|
|
693
|
-
nodes[dimensions[order[l + 1]].nodeId]
|
|
694
|
-
) : order[l + 1];
|
|
695
|
-
createEdge(level1Node.id, nextLevel1Node.id, siblingRules);
|
|
696
|
-
}
|
|
697
|
-
if (!l && extents === "bridgedCustom") {
|
|
698
|
-
createEdge(po.level1Options.behavior.customBridgePost, level1Node.id, siblingRules);
|
|
699
|
-
}
|
|
700
|
-
l++;
|
|
701
|
-
});
|
|
702
|
-
dimensionKeys.forEach((s) => {
|
|
703
|
-
const dimension = dimensions[s];
|
|
704
|
-
const strat = dimension.behavior?.childmostNavigation || "within";
|
|
705
|
-
const matchByIndex = (i, _a, _b, c) => {
|
|
706
|
-
return c.values[Object.keys(c.values)[i]] || void 0;
|
|
707
|
-
};
|
|
708
|
-
const match = strat === "across" && dimension.behavior?.childmostMatching ? dimension.behavior?.childmostMatching : matchByIndex;
|
|
709
|
-
let extents2 = dimension.behavior?.extents || "circular";
|
|
710
|
-
if (!dimension.divisions) {
|
|
711
|
-
console.error(
|
|
712
|
-
`Parsing dimensions. The dimension using the key ${s} is missing the divisions property. dimension.divisions should be supplied. ${JSON.stringify(
|
|
713
|
-
dimension
|
|
714
|
-
)}.`
|
|
715
|
-
);
|
|
716
|
-
}
|
|
717
|
-
let divisionKeys = Object.keys(dimension.divisions);
|
|
718
|
-
const firstDivision = dimension.divisions[divisionKeys[0]];
|
|
719
|
-
if (divisionKeys.length !== 1) {
|
|
720
|
-
createEdge(dimension.nodeId, firstDivision.id, dimension.navigationRules.parent_child, "source");
|
|
721
|
-
} else {
|
|
722
|
-
let valueKeys = Object.keys(firstDivision.values);
|
|
723
|
-
let firstChildId = typeof options.idKey === "function" ? options.idKey(firstDivision.values[valueKeys[0]]) : options.idKey;
|
|
724
|
-
createEdge(
|
|
725
|
-
dimension.nodeId,
|
|
726
|
-
firstDivision.values[valueKeys[0]][firstChildId],
|
|
727
|
-
dimension.navigationRules.parent_child,
|
|
728
|
-
"source"
|
|
729
|
-
);
|
|
730
|
-
}
|
|
731
|
-
let j = 0;
|
|
732
|
-
divisionKeys.forEach((d) => {
|
|
733
|
-
let division = dimension.divisions[d];
|
|
734
|
-
if (j === divisionKeys.length - 1 && (extents2 === "circular" || extents2 === "bridgedCousins" || extents2 === "bridgedCustom")) {
|
|
735
|
-
createEdge(
|
|
736
|
-
division.id,
|
|
737
|
-
dimension.divisions[divisionKeys[0]].id,
|
|
738
|
-
dimension.navigationRules.sibling_sibling
|
|
739
|
-
);
|
|
740
|
-
} else if (j < divisionKeys.length - 1) {
|
|
741
|
-
createEdge(
|
|
742
|
-
division.id,
|
|
743
|
-
dimension.divisions[divisionKeys[j + 1]].id,
|
|
744
|
-
dimension.navigationRules.sibling_sibling
|
|
745
|
-
);
|
|
746
|
-
}
|
|
747
|
-
let valueKeys = Object.keys(division.values);
|
|
748
|
-
if (!options.useDirectedEdges) {
|
|
749
|
-
createEdge(dimension.nodeId, division.id, dimension.navigationRules.parent_child, "target");
|
|
750
|
-
} else {
|
|
751
|
-
createEdge(division.id, dimension.nodeId, dimension.navigationRules.parent_child, "source");
|
|
752
|
-
}
|
|
753
|
-
const firstChildId = typeof options.idKey === "function" ? options.idKey(division.values[valueKeys[0]]) : options.idKey;
|
|
754
|
-
createEdge(
|
|
755
|
-
division.id,
|
|
756
|
-
division.values[valueKeys[0]][firstChildId],
|
|
757
|
-
dimension.navigationRules.parent_child,
|
|
758
|
-
"source"
|
|
759
|
-
);
|
|
760
|
-
let i = 0;
|
|
761
|
-
if (valueKeys.length > 1) {
|
|
762
|
-
valueKeys.forEach((vk) => {
|
|
763
|
-
let v = division.values[vk];
|
|
764
|
-
const id = typeof options.idKey === "function" ? options.idKey(v) : options.idKey;
|
|
765
|
-
let parentId = divisionKeys.length !== 1 ? division.id : dimension.nodeId;
|
|
766
|
-
if (!options.useDirectedEdges) {
|
|
767
|
-
createEdge(parentId, v[id], dimension.navigationRules.parent_child, "target");
|
|
768
|
-
} else {
|
|
769
|
-
createEdge(v[id], parentId, dimension.navigationRules.parent_child, "source");
|
|
770
|
-
}
|
|
771
|
-
if (strat === "within") {
|
|
772
|
-
if (i === valueKeys.length - 1 && extents2 === "circular") {
|
|
773
|
-
const targetId = typeof options.idKey === "function" ? options.idKey(division.values[valueKeys[0]]) : options.idKey;
|
|
774
|
-
createEdge(
|
|
775
|
-
v[id],
|
|
776
|
-
division.values[valueKeys[0]][targetId],
|
|
777
|
-
dimension.navigationRules.sibling_sibling
|
|
778
|
-
);
|
|
779
|
-
} else if (i === valueKeys.length - 1 && extents2 === "bridgedCousins") {
|
|
780
|
-
if (j !== divisionKeys.length - 1) {
|
|
781
|
-
const targetId = typeof options.idKey === "function" ? options.idKey(
|
|
782
|
-
dimension.divisions[divisionKeys[j + 1]].values[valueKeys[0]]
|
|
783
|
-
) : options.idKey;
|
|
784
|
-
createEdge(
|
|
785
|
-
v[id],
|
|
786
|
-
dimension.divisions[divisionKeys[j + 1]].values[valueKeys[0]][targetId],
|
|
787
|
-
dimension.navigationRules.sibling_sibling
|
|
788
|
-
);
|
|
789
|
-
} else {
|
|
790
|
-
const targetId = typeof options.idKey === "function" ? options.idKey(dimension.divisions[divisionKeys[0]].values[valueKeys[0]]) : options.idKey;
|
|
791
|
-
createEdge(
|
|
792
|
-
v[id],
|
|
793
|
-
dimension.divisions[divisionKeys[0]].values[valueKeys[0]][targetId],
|
|
794
|
-
dimension.navigationRules.sibling_sibling
|
|
795
|
-
);
|
|
796
|
-
}
|
|
797
|
-
} else if (i === valueKeys.length - 1 && extents2 === "bridgedCustom") {
|
|
798
|
-
createEdge(
|
|
799
|
-
v[id],
|
|
800
|
-
dimension.behavior.customBridgePost,
|
|
801
|
-
dimension.navigationRules.sibling_sibling
|
|
802
|
-
);
|
|
803
|
-
} else if (i < valueKeys.length - 1) {
|
|
804
|
-
const targetId = typeof options.idKey === "function" ? options.idKey(division.values[valueKeys[i + 1]]) : options.idKey;
|
|
805
|
-
createEdge(
|
|
806
|
-
v[id],
|
|
807
|
-
division.values[valueKeys[i + 1]][targetId],
|
|
808
|
-
dimension.navigationRules.sibling_sibling
|
|
809
|
-
);
|
|
810
|
-
}
|
|
811
|
-
if (!i && extents2 === "bridgedCousins") {
|
|
812
|
-
if (j !== 0) {
|
|
813
|
-
const targetId = typeof options.idKey === "function" ? options.idKey(
|
|
814
|
-
dimension.divisions[divisionKeys[j - 1]].values[valueKeys[valueKeys.length - 1]]
|
|
815
|
-
) : options.idKey;
|
|
816
|
-
createEdge(
|
|
817
|
-
dimension.divisions[divisionKeys[j - 1]].values[valueKeys[valueKeys.length - 1]][targetId],
|
|
818
|
-
v[id],
|
|
819
|
-
dimension.navigationRules.sibling_sibling
|
|
820
|
-
);
|
|
821
|
-
} else {
|
|
822
|
-
const targetId = typeof options.idKey === "function" ? options.idKey(
|
|
823
|
-
dimension.divisions[divisionKeys[divisionKeys.length - 1]].values[valueKeys[valueKeys.length - 1]]
|
|
824
|
-
) : options.idKey;
|
|
825
|
-
createEdge(
|
|
826
|
-
dimension.divisions[divisionKeys[divisionKeys.length - 1]].values[valueKeys[valueKeys.length - 1]][targetId],
|
|
827
|
-
v[id],
|
|
828
|
-
dimension.navigationRules.sibling_sibling
|
|
829
|
-
);
|
|
830
|
-
}
|
|
831
|
-
} else if (!i && extents2 === "bridgedCustom") {
|
|
832
|
-
createEdge(
|
|
833
|
-
dimension.behavior.customBridgePrevious,
|
|
834
|
-
v[id],
|
|
835
|
-
dimension.navigationRules.sibling_sibling
|
|
836
|
-
);
|
|
837
|
-
}
|
|
838
|
-
} else {
|
|
839
|
-
if (j === divisionKeys.length - 1 && extents2 === "bridgedCustom") {
|
|
840
|
-
createEdge(
|
|
841
|
-
v[id],
|
|
842
|
-
dimension.behavior.customBridgePost,
|
|
843
|
-
dimension.navigationRules.sibling_sibling
|
|
844
|
-
);
|
|
845
|
-
} else if (!j && extents2 === "bridgedCustom") {
|
|
846
|
-
createEdge(
|
|
847
|
-
dimension.behavior.customBridgePrevious,
|
|
848
|
-
v[id],
|
|
849
|
-
dimension.navigationRules.sibling_sibling
|
|
850
|
-
);
|
|
851
|
-
} else {
|
|
852
|
-
const targetDivision = j === divisionKeys.length - 1 && extents2 === "circular" ? dimension.divisions[divisionKeys[0]] : dimension.divisions[divisionKeys[j + 1]];
|
|
853
|
-
if (targetDivision) {
|
|
854
|
-
const target = match(i, v[id], division, targetDivision);
|
|
855
|
-
if (target) {
|
|
856
|
-
const targetId = typeof options.idKey === "function" ? options.idKey(target) : options.idKey;
|
|
857
|
-
createEdge(v[id], target[targetId], dimension.navigationRules.sibling_sibling);
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
i++;
|
|
863
|
-
});
|
|
864
|
-
}
|
|
865
|
-
j++;
|
|
866
|
-
});
|
|
867
|
-
});
|
|
868
|
-
}
|
|
869
|
-
Object.keys(nodes).forEach((nodeKey) => {
|
|
870
|
-
const node = nodes[nodeKey];
|
|
871
|
-
if (options.genericEdges?.length) {
|
|
872
|
-
options.genericEdges.forEach((e) => {
|
|
873
|
-
if (!edges[e.edgeId]) {
|
|
874
|
-
edges[e.edgeId] = e.edge;
|
|
875
|
-
}
|
|
876
|
-
if (!e.conditional || e.conditional && e.conditional(node, e)) {
|
|
877
|
-
node.edges.push(e.edgeId);
|
|
878
|
-
}
|
|
879
|
-
});
|
|
880
|
-
}
|
|
881
|
-
});
|
|
882
|
-
return edges;
|
|
883
|
-
};
|
|
884
|
-
var buildRules = (options, edges, dimensions) => {
|
|
885
|
-
let rules = options.navigationRules;
|
|
886
|
-
if (!rules) {
|
|
887
|
-
let dimKeys = Object.keys(dimensions || {});
|
|
888
|
-
if (dimKeys.length > 6) {
|
|
889
|
-
console.error(
|
|
890
|
-
`Building navigationRules. Dimension count is too high to automatically generate key commands. It is recommend you reduce your dimensions to 6 or fewer for end-user experience. If not, you must provide your own navigation rules in options.navigationRules. Details: Count is ${dimKeys.length}. Dimensions counted: ${dimKeys.join(", ")}.`
|
|
891
|
-
);
|
|
892
|
-
}
|
|
893
|
-
let importedRules = {};
|
|
894
|
-
let used = {};
|
|
895
|
-
let needsKeys = {};
|
|
896
|
-
let sparePairs = [...TypicallyUnreservedKeyPairs];
|
|
897
|
-
let spareKeys = [...TypicallyUnreservedKeys];
|
|
898
|
-
const checkKeys = (k1, k2) => {
|
|
899
|
-
let isPair = k1 && k2;
|
|
900
|
-
let k1Assigned = false;
|
|
901
|
-
let k2Assigned = false;
|
|
902
|
-
if (importedRules[k1] || used[k1]) {
|
|
903
|
-
used[k1] = { ...importedRules[k1] };
|
|
904
|
-
k1Assigned = true;
|
|
905
|
-
}
|
|
906
|
-
if (k2 && (importedRules[k2] || used[k2])) {
|
|
907
|
-
used[k2] = { ...importedRules[k2] };
|
|
908
|
-
k2Assigned = true;
|
|
909
|
-
}
|
|
910
|
-
if (isPair && !k1Assigned && !k2Assigned) {
|
|
911
|
-
if (!sparePairs.length) {
|
|
912
|
-
console.error(
|
|
913
|
-
`Building navigationRules. Dimension count is too high to automatically generate key commands, we have run out of keyboard key pairs to assign. You must either provide your own navigation rules in options.navigationRules, provide rules when generating dimensions, or reduce dimension count.`
|
|
914
|
-
);
|
|
915
|
-
}
|
|
916
|
-
let pair = [...sparePairs.shift()];
|
|
917
|
-
spareKeys.splice(spareKeys.indexOf(pair[0]), 1);
|
|
918
|
-
spareKeys.splice(spareKeys.indexOf(pair[1]), 1);
|
|
919
|
-
used[k1] = {
|
|
920
|
-
direction: options.useDirectedEdges ? "target" : "source",
|
|
921
|
-
key: pair[0]
|
|
922
|
-
};
|
|
923
|
-
used[k2] = {
|
|
924
|
-
direction: "target",
|
|
925
|
-
key: pair[1]
|
|
926
|
-
};
|
|
927
|
-
} else {
|
|
928
|
-
if (!used[k1] && spareKeys.length) {
|
|
929
|
-
let key = spareKeys.shift();
|
|
930
|
-
let newPairs = [];
|
|
931
|
-
sparePairs.forEach((p) => {
|
|
932
|
-
if (key !== p[0] && key !== p[1]) {
|
|
933
|
-
newPairs.push(p);
|
|
934
|
-
}
|
|
935
|
-
});
|
|
936
|
-
sparePairs = newPairs;
|
|
937
|
-
used[k1] = {
|
|
938
|
-
direction: options.useDirectedEdges ? "target" : "source",
|
|
939
|
-
key
|
|
940
|
-
};
|
|
941
|
-
}
|
|
942
|
-
if (k2 && !used[k2] && spareKeys.length) {
|
|
943
|
-
let key = spareKeys.shift();
|
|
944
|
-
let newPairs = [];
|
|
945
|
-
sparePairs.forEach((p) => {
|
|
946
|
-
if (key !== p[0] && key !== p[1]) {
|
|
947
|
-
newPairs.push(p);
|
|
948
|
-
}
|
|
949
|
-
});
|
|
950
|
-
sparePairs = newPairs;
|
|
951
|
-
used[k2] = {
|
|
952
|
-
direction: "target",
|
|
953
|
-
key
|
|
954
|
-
};
|
|
955
|
-
}
|
|
956
|
-
if (!spareKeys.length) {
|
|
957
|
-
if (!used[k1]) {
|
|
958
|
-
needsKeys[k1] = k1;
|
|
959
|
-
}
|
|
960
|
-
if (k2 && !used[k2]) {
|
|
961
|
-
needsKeys[k2] = k2;
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
};
|
|
966
|
-
Object.keys(GenericFullNavigationRules).forEach((r) => {
|
|
967
|
-
let rule = { ...GenericFullNavigationRules[r] };
|
|
968
|
-
if (options.useDirectedEdges) {
|
|
969
|
-
rule.direction = "target";
|
|
970
|
-
}
|
|
971
|
-
importedRules[r] = rule;
|
|
972
|
-
});
|
|
973
|
-
if (dimKeys.length) {
|
|
974
|
-
if (options.dimensions?.parentOptions?.addLevel0) {
|
|
975
|
-
let rules2 = options.dimensions.parentOptions.level1Options?.navigationRules?.parent_child || [
|
|
976
|
-
"parent",
|
|
977
|
-
"child"
|
|
978
|
-
];
|
|
979
|
-
checkKeys(rules2[0], rules2[1]);
|
|
980
|
-
}
|
|
981
|
-
dimKeys.forEach((d) => {
|
|
982
|
-
let pc = dimensions[d].navigationRules.parent_child;
|
|
983
|
-
let ss = dimensions[d].navigationRules.sibling_sibling;
|
|
984
|
-
checkKeys(pc[0], pc[1]);
|
|
985
|
-
checkKeys(ss[0], ss[1]);
|
|
986
|
-
});
|
|
987
|
-
}
|
|
988
|
-
Object.keys(edges).forEach((e) => {
|
|
989
|
-
edges[e].navigationRules.forEach((rule) => {
|
|
990
|
-
if (!used[rule]) {
|
|
991
|
-
checkKeys(rule);
|
|
992
|
-
}
|
|
993
|
-
});
|
|
994
|
-
});
|
|
995
|
-
if (Object.keys(needsKeys).length) {
|
|
996
|
-
let usedKeys = {};
|
|
997
|
-
Object.keys(used).forEach((k) => {
|
|
998
|
-
usedKeys[used[k].key] = used[k].key;
|
|
999
|
-
});
|
|
1000
|
-
Object.keys(importedRules).forEach((r) => {
|
|
1001
|
-
if (!usedKeys[importedRules[r].key] && !SemanticKeys[importedRules[r].key]) {
|
|
1002
|
-
spareKeys.push(importedRules[r].key);
|
|
1003
|
-
}
|
|
1004
|
-
});
|
|
1005
|
-
let recheckKeys = { ...needsKeys };
|
|
1006
|
-
needsKeys = {};
|
|
1007
|
-
Object.keys(recheckKeys).forEach((key) => {
|
|
1008
|
-
checkKeys(key);
|
|
1009
|
-
});
|
|
1010
|
-
if (Object.keys(needsKeys).length) {
|
|
1011
|
-
console.error(
|
|
1012
|
-
`Building navigationRules. There are no more keys left to assign automatically. Recommended fixes: use fewer dimensions, use fewer GenericEdges, or build your own navigationRules. Rules remaining without keyboard keys: ${Object.keys(
|
|
1013
|
-
needsKeys
|
|
1014
|
-
).join(", ")}.`
|
|
1015
|
-
);
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
rules = used;
|
|
1019
|
-
}
|
|
1020
|
-
return rules;
|
|
1021
|
-
};
|
|
1022
|
-
var buildStructure = (options) => {
|
|
1023
|
-
if (options.addIds) {
|
|
1024
|
-
addSimpleDataIDs(options);
|
|
1025
|
-
}
|
|
1026
|
-
let nodes = buildNodes(options);
|
|
1027
|
-
let dimensions = scaffoldDimensions(options, nodes);
|
|
1028
|
-
let edges = buildEdges(options, nodes, dimensions);
|
|
1029
|
-
let navigationRules = buildRules(options, edges, dimensions);
|
|
1030
|
-
return {
|
|
1031
|
-
nodes,
|
|
1032
|
-
edges,
|
|
1033
|
-
dimensions,
|
|
1034
|
-
navigationRules
|
|
1035
|
-
};
|
|
1036
|
-
};
|
|
1037
|
-
|
|
1038
|
-
// src/input.ts
|
|
1039
|
-
var input_default = (options) => {
|
|
1040
|
-
let inputHandler = {};
|
|
1041
|
-
let keyBindings = defaultKeyBindings;
|
|
1042
|
-
let directions = GenericFullNavigationRules;
|
|
1043
|
-
inputHandler.moveTo = (id) => {
|
|
1044
|
-
const target = options.structure.nodes[id];
|
|
1045
|
-
if (target) {
|
|
1046
|
-
return target;
|
|
1047
|
-
}
|
|
1048
|
-
return;
|
|
1049
|
-
};
|
|
1050
|
-
inputHandler.move = (currentFocus, direction) => {
|
|
1051
|
-
if (currentFocus) {
|
|
1052
|
-
const d = options.structure.nodes[currentFocus];
|
|
1053
|
-
if (d.edges) {
|
|
1054
|
-
let target = null;
|
|
1055
|
-
let i = 0;
|
|
1056
|
-
const navRule = directions[direction];
|
|
1057
|
-
if (!navRule) {
|
|
1058
|
-
return;
|
|
1059
|
-
}
|
|
1060
|
-
const findTarget = (rule, edge) => {
|
|
1061
|
-
if (!(rule === direction)) {
|
|
1062
|
-
return null;
|
|
1063
|
-
}
|
|
1064
|
-
let resolvedNodes = {
|
|
1065
|
-
target: typeof edge.target === "string" ? edge.target : edge.target(d, currentFocus),
|
|
1066
|
-
source: typeof edge.source === "string" ? edge.source : edge.source(d, currentFocus)
|
|
1067
|
-
};
|
|
1068
|
-
return !(resolvedNodes[navRule.direction] === currentFocus) ? resolvedNodes[navRule.direction] : null;
|
|
1069
|
-
};
|
|
1070
|
-
for (i = 0; i < d.edges.length; i++) {
|
|
1071
|
-
const edge = options.structure.edges[d.edges[i]];
|
|
1072
|
-
edge.navigationRules.forEach((rule) => {
|
|
1073
|
-
if (!target) {
|
|
1074
|
-
target = findTarget(rule, edge);
|
|
1075
|
-
}
|
|
1076
|
-
});
|
|
1077
|
-
if (target) {
|
|
1078
|
-
break;
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
if (target) {
|
|
1082
|
-
return inputHandler.moveTo(target);
|
|
1083
|
-
}
|
|
1084
|
-
return void 0;
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
};
|
|
1088
|
-
inputHandler.enter = () => {
|
|
1089
|
-
if (options.entryPoint) {
|
|
1090
|
-
return inputHandler.moveTo(options.entryPoint);
|
|
1091
|
-
} else {
|
|
1092
|
-
console.error("No entry point was specified in InputOptions, returning undefined");
|
|
1093
|
-
return;
|
|
1094
|
-
}
|
|
1095
|
-
};
|
|
1096
|
-
inputHandler.exit = () => {
|
|
1097
|
-
if (options.exitPoint) {
|
|
1098
|
-
return options.exitPoint;
|
|
1099
|
-
} else {
|
|
1100
|
-
console.error("No exit point was specified in InputOptions, returning undefined");
|
|
1101
|
-
return;
|
|
1102
|
-
}
|
|
1103
|
-
};
|
|
1104
|
-
inputHandler.keydownValidator = (e) => {
|
|
1105
|
-
const direction = keyBindings[e.code];
|
|
1106
|
-
if (direction) {
|
|
1107
|
-
return direction;
|
|
1108
|
-
}
|
|
1109
|
-
};
|
|
1110
|
-
inputHandler.focus = (renderId) => {
|
|
1111
|
-
const node = document.getElementById(renderId);
|
|
1112
|
-
if (node) {
|
|
1113
|
-
node.focus();
|
|
1114
|
-
}
|
|
1115
|
-
};
|
|
1116
|
-
inputHandler.setNavigationKeyBindings = (navKeyBindings) => {
|
|
1117
|
-
if (!navKeyBindings) {
|
|
1118
|
-
keyBindings = defaultKeyBindings;
|
|
1119
|
-
directions = GenericFullNavigationRules;
|
|
1120
|
-
} else {
|
|
1121
|
-
keyBindings = {};
|
|
1122
|
-
directions = navKeyBindings;
|
|
1123
|
-
Object.keys(navKeyBindings).forEach((direction) => {
|
|
1124
|
-
const navOption = navKeyBindings[direction];
|
|
1125
|
-
keyBindings[navOption.key] = direction;
|
|
1126
|
-
});
|
|
1127
|
-
}
|
|
1128
|
-
};
|
|
1129
|
-
inputHandler.setNavigationKeyBindings(options.navigationRules);
|
|
1130
|
-
return inputHandler;
|
|
1131
|
-
};
|
|
1132
|
-
|
|
1133
|
-
// src/rendering.ts
|
|
1134
|
-
var rendering_default = (options) => {
|
|
1135
|
-
const setActiveDescendant = (e) => {
|
|
1136
|
-
renderer.wrapper.setAttribute("aria-activedescendant", e.srcElement.id);
|
|
1137
|
-
};
|
|
1138
|
-
const removeActiveDescendant = () => {
|
|
1139
|
-
renderer.wrapper.setAttribute("aria-activedescendant", "");
|
|
1140
|
-
};
|
|
1141
|
-
let renderer = {};
|
|
1142
|
-
let initialized = false;
|
|
1143
|
-
let defaults = {
|
|
1144
|
-
cssClass: NodeElementDefaults.cssClass,
|
|
1145
|
-
spatialProperties: { ...NodeElementDefaults.spatialProperties },
|
|
1146
|
-
semantics: { ...NodeElementDefaults.semantics },
|
|
1147
|
-
parentSemantics: { ...NodeElementDefaults.parentSemantics },
|
|
1148
|
-
existingElement: { ...NodeElementDefaults.existingElement }
|
|
1149
|
-
};
|
|
1150
|
-
if (options.defaults) {
|
|
1151
|
-
defaults.cssClass = options.defaults.cssClass || defaults.cssClass;
|
|
1152
|
-
defaults.spatialProperties = options.defaults.spatialProperties ? { ...defaults.spatialProperties, ...options.defaults.spatialProperties } : defaults.spatialProperties;
|
|
1153
|
-
defaults.semantics = options.defaults.semantics ? { ...defaults.semantics, ...options.defaults.semantics } : defaults.semantics;
|
|
1154
|
-
defaults.parentSemantics = options.defaults.parentSemantics ? { ...defaults.parentSemantics, ...options.defaults.parentSemantics } : defaults.parentSemantics;
|
|
1155
|
-
defaults.existingElement = options.defaults.existingElement ? { ...defaults.existingElement, ...options.defaults.existingElement } : defaults.existingElement;
|
|
1156
|
-
}
|
|
1157
|
-
renderer.initialize = () => {
|
|
1158
|
-
if (initialized) {
|
|
1159
|
-
console.error(
|
|
1160
|
-
`The renderer wrapper has already been initialized successfully, RenderingOptions.suffixId is: ${options.suffixId}. No further action was taken.`
|
|
1161
|
-
);
|
|
1162
|
-
return;
|
|
1163
|
-
}
|
|
1164
|
-
if (options.root && document.getElementById(options.root.id)) {
|
|
1165
|
-
renderer.root = document.getElementById(options.root.id);
|
|
1166
|
-
} else {
|
|
1167
|
-
console.error(
|
|
1168
|
-
"No root element found, cannot build: RenderingOptions.root.id must reference an existing DOM element in order to render children."
|
|
1169
|
-
);
|
|
1170
|
-
return;
|
|
1171
|
-
}
|
|
1172
|
-
renderer.root.style.position = "relative";
|
|
1173
|
-
renderer.root.classList.add("dn-root");
|
|
1174
|
-
if (!options.suffixId) {
|
|
1175
|
-
console.error("No suffix id found: options.suffixId must be specified.");
|
|
1176
|
-
return;
|
|
1177
|
-
}
|
|
1178
|
-
renderer.wrapper = document.createElement("div");
|
|
1179
|
-
renderer.wrapper.id = "dn-wrapper-" + options.suffixId;
|
|
1180
|
-
renderer.wrapper.setAttribute("role", "application");
|
|
1181
|
-
renderer.wrapper.setAttribute("aria-label", options.root.description || "Data navigation structure");
|
|
1182
|
-
renderer.wrapper.setAttribute("aria-activedescendant", "");
|
|
1183
|
-
renderer.wrapper.classList.add("dn-wrapper");
|
|
1184
|
-
renderer.wrapper.style.width = options.root && options.root.width ? options.root.width : "100%";
|
|
1185
|
-
if (options.root && options.root.height) {
|
|
1186
|
-
renderer.wrapper.style.height = options.root.height;
|
|
1187
|
-
}
|
|
1188
|
-
if (options.entryButton && options.entryButton.include) {
|
|
1189
|
-
renderer.entryButton = document.createElement("button");
|
|
1190
|
-
renderer.entryButton.id = "dn-entry-button-" + options.suffixId;
|
|
1191
|
-
renderer.entryButton.classList.add("dn-entry-button");
|
|
1192
|
-
renderer.entryButton.innerText = `Enter navigation area`;
|
|
1193
|
-
if (options.entryButton.callbacks && options.entryButton.callbacks.click) {
|
|
1194
|
-
renderer.entryButton.addEventListener("click", options.entryButton.callbacks.click);
|
|
1195
|
-
}
|
|
1196
|
-
if (options.entryButton.callbacks && options.entryButton.callbacks.focus) {
|
|
1197
|
-
renderer.entryButton.addEventListener("focus", options.entryButton.callbacks.focus);
|
|
1198
|
-
}
|
|
1199
|
-
renderer.wrapper.appendChild(renderer.entryButton);
|
|
1200
|
-
}
|
|
1201
|
-
renderer.root.appendChild(renderer.wrapper);
|
|
1202
|
-
if (options.exitElement?.include) {
|
|
1203
|
-
renderer.exitElement = document.createElement("div");
|
|
1204
|
-
renderer.exitElement.id = "dn-exit-" + options.suffixId;
|
|
1205
|
-
renderer.exitElement.classList.add("dn-exit-position");
|
|
1206
|
-
renderer.exitElement.innerText = `End of data structure.`;
|
|
1207
|
-
renderer.exitElement.setAttribute("aria-label", `End of data structure.`);
|
|
1208
|
-
renderer.exitElement.setAttribute("role", "note");
|
|
1209
|
-
renderer.exitElement.setAttribute("tabindex", "-1");
|
|
1210
|
-
renderer.exitElement.style.display = "none";
|
|
1211
|
-
renderer.exitElement.addEventListener("focus", (e) => {
|
|
1212
|
-
renderer.exitElement.style.display = "block";
|
|
1213
|
-
renderer.clearStructure();
|
|
1214
|
-
if (options.exitElement?.callbacks?.focus) {
|
|
1215
|
-
options.exitElement.callbacks.focus(e);
|
|
1216
|
-
}
|
|
1217
|
-
});
|
|
1218
|
-
renderer.exitElement.addEventListener("blur", (e) => {
|
|
1219
|
-
renderer.exitElement.style.display = "none";
|
|
1220
|
-
if (options.exitElement?.callbacks?.blur) {
|
|
1221
|
-
options.exitElement.callbacks.blur(e);
|
|
1222
|
-
}
|
|
1223
|
-
});
|
|
1224
|
-
renderer.root.appendChild(renderer.exitElement);
|
|
1225
|
-
}
|
|
1226
|
-
initialized = true;
|
|
1227
|
-
return renderer.root;
|
|
1228
|
-
};
|
|
1229
|
-
renderer.render = (nodeData) => {
|
|
1230
|
-
const id = nodeData.renderId + "";
|
|
1231
|
-
let d = options.elementData[id];
|
|
1232
|
-
if (!d) {
|
|
1233
|
-
console.warn(`Render data not found with renderId: ${id}. Failed to render.`);
|
|
1234
|
-
return;
|
|
1235
|
-
}
|
|
1236
|
-
if (!initialized) {
|
|
1237
|
-
console.error("render() was called before initialize(), renderer must be initialized first.");
|
|
1238
|
-
return;
|
|
1239
|
-
}
|
|
1240
|
-
let useExisting = false;
|
|
1241
|
-
let existingSpatialProperties = {};
|
|
1242
|
-
const resolveProp = (prop, subprop, checkExisting) => {
|
|
1243
|
-
const p1 = d[prop] || defaults[prop];
|
|
1244
|
-
const s1 = !(checkExisting && useExisting) ? p1[subprop] : existingSpatialProperties[subprop];
|
|
1245
|
-
const s2 = defaults[prop][subprop];
|
|
1246
|
-
return typeof p1 === "function" ? p1(d, nodeData.datum) : typeof s1 === "function" ? s1(d, nodeData.datum) : s1 || s2 || (!subprop ? p1 : void 0);
|
|
1247
|
-
};
|
|
1248
|
-
useExisting = resolveProp("existingElement", "useForSpatialProperties");
|
|
1249
|
-
existingSpatialProperties = resolveProp("existingElement", "spatialProperties");
|
|
1250
|
-
const width = parseFloat(resolveProp("spatialProperties", "width", true) || 0);
|
|
1251
|
-
const height = parseFloat(resolveProp("spatialProperties", "height", true) || 0);
|
|
1252
|
-
const x = parseFloat(resolveProp("spatialProperties", "x", true) || 0);
|
|
1253
|
-
const y = parseFloat(resolveProp("spatialProperties", "y", true) || 0);
|
|
1254
|
-
const node = document.createElement(resolveProp("parentSemantics", "elementType"));
|
|
1255
|
-
const wrapperAttrs = resolveProp("parentSemantics", "attributes");
|
|
1256
|
-
if (typeof wrapperAttrs === "object") {
|
|
1257
|
-
Object.keys(wrapperAttrs).forEach((wrapperAttr) => {
|
|
1258
|
-
node.setAttribute(wrapperAttr, wrapperAttrs[wrapperAttr]);
|
|
1259
|
-
});
|
|
1260
|
-
}
|
|
1261
|
-
node.setAttribute("role", resolveProp("parentSemantics", "role"));
|
|
1262
|
-
node.id = id;
|
|
1263
|
-
node.classList.add("dn-node");
|
|
1264
|
-
node.classList.add(resolveProp("cssClass"));
|
|
1265
|
-
node.style.width = width + "px";
|
|
1266
|
-
node.style.height = height + "px";
|
|
1267
|
-
node.style.left = x + "px";
|
|
1268
|
-
node.style.top = y + "px";
|
|
1269
|
-
node.setAttribute("tabindex", "0");
|
|
1270
|
-
node.addEventListener("focus", setActiveDescendant);
|
|
1271
|
-
node.addEventListener("blur", removeActiveDescendant);
|
|
1272
|
-
const nodeText = document.createElement(resolveProp("semantics", "elementType"));
|
|
1273
|
-
const attributes = resolveProp("semantics", "attributes");
|
|
1274
|
-
if (typeof attributes === "object") {
|
|
1275
|
-
Object.keys(attributes).forEach((attribute) => {
|
|
1276
|
-
node.setAttribute(attribute, attributes[attribute]);
|
|
1277
|
-
});
|
|
1278
|
-
}
|
|
1279
|
-
nodeText.setAttribute("role", resolveProp("semantics", "role"));
|
|
1280
|
-
nodeText.classList.add("dn-node-text");
|
|
1281
|
-
if (d.showText) {
|
|
1282
|
-
nodeText.innerText = d.semantics.label;
|
|
1283
|
-
}
|
|
1284
|
-
const label = resolveProp("semantics", "label");
|
|
1285
|
-
if (!label) {
|
|
1286
|
-
console.error(
|
|
1287
|
-
"Accessibility error: a label must be supplied to every rendered element using semantics.label."
|
|
1288
|
-
);
|
|
1289
|
-
}
|
|
1290
|
-
nodeText.setAttribute("aria-label", label);
|
|
1291
|
-
node.appendChild(nodeText);
|
|
1292
|
-
const hasPath = resolveProp("spatialProperties", "path");
|
|
1293
|
-
if (hasPath) {
|
|
1294
|
-
const totalWidth = width + x + 10;
|
|
1295
|
-
const totalHeight = height + y + 10;
|
|
1296
|
-
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
1297
|
-
svg.setAttribute("width", totalWidth + "");
|
|
1298
|
-
svg.setAttribute("height", totalHeight + "");
|
|
1299
|
-
svg.setAttribute("viewBox", `0 0 ${totalWidth} ${totalHeight}`);
|
|
1300
|
-
svg.style.left = -x + "px";
|
|
1301
|
-
svg.style.top = -y + "px";
|
|
1302
|
-
svg.classList.add("dn-node-svg");
|
|
1303
|
-
svg.setAttribute("role", "presentation");
|
|
1304
|
-
svg.setAttribute("focusable", "false");
|
|
1305
|
-
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
1306
|
-
path.setAttribute("d", hasPath);
|
|
1307
|
-
path.classList.add("dn-node-path");
|
|
1308
|
-
svg.appendChild(path);
|
|
1309
|
-
node.appendChild(svg);
|
|
1310
|
-
}
|
|
1311
|
-
renderer.wrapper.appendChild(node);
|
|
1312
|
-
return node;
|
|
1313
|
-
};
|
|
1314
|
-
renderer.remove = (renderId) => {
|
|
1315
|
-
const node = document.getElementById(renderId);
|
|
1316
|
-
if (renderer.wrapper.getAttribute("aria-activedescendant") === renderId) {
|
|
1317
|
-
renderer.wrapper.setAttribute("aria-activedescendant", "");
|
|
1318
|
-
}
|
|
1319
|
-
if (node) {
|
|
1320
|
-
node.removeEventListener("focus", setActiveDescendant);
|
|
1321
|
-
node.removeEventListener("blur", removeActiveDescendant);
|
|
1322
|
-
node.remove();
|
|
1323
|
-
}
|
|
1324
|
-
};
|
|
1325
|
-
renderer.clearStructure = () => {
|
|
1326
|
-
[...renderer.wrapper.children].forEach((child) => {
|
|
1327
|
-
if (!(renderer.entryButton && renderer.entryButton === child)) {
|
|
1328
|
-
renderer.remove(child.id);
|
|
1329
|
-
}
|
|
1330
|
-
});
|
|
1331
|
-
};
|
|
1332
|
-
return renderer;
|
|
1333
|
-
};
|
|
1334
|
-
|
|
1335
|
-
// src/index.ts
|
|
1336
|
-
var src_default = { structure: structure_default, input: input_default, rendering: rendering_default };
|
|
1337
|
-
export {
|
|
1338
|
-
src_default as default
|
|
1339
|
-
};
|