data-navigator 2.3.1 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +118 -64
- package/dist/index.d.cts +265 -0
- package/dist/index.d.ts +265 -0
- package/dist/index.js +118 -64
- package/dist/structure.cjs +1 -1
- package/dist/structure.js +1 -1
- package/dist/text-chat.cjs +13 -13
- package/dist/text-chat.js +8 -8
- package/package.json +5 -5
- package/text-chat.css +2 -2
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
type StructureOptions = {
|
|
2
|
+
data: GenericDataset;
|
|
3
|
+
idKey: DynamicNodeIdKey;
|
|
4
|
+
renderIdKey?: DynamicRenderIdKey;
|
|
5
|
+
dimensions?: DimensionOptions;
|
|
6
|
+
genericEdges?: EdgeOptions;
|
|
7
|
+
useDirectedEdges?: boolean;
|
|
8
|
+
dataType?: DataType;
|
|
9
|
+
addIds?: boolean;
|
|
10
|
+
keysForIdGeneration?: KeyList;
|
|
11
|
+
navigationRules?: NavigationRules;
|
|
12
|
+
};
|
|
13
|
+
type InputOptions = {
|
|
14
|
+
structure: Structure;
|
|
15
|
+
navigationRules: NavigationRules;
|
|
16
|
+
entryPoint?: NodeId;
|
|
17
|
+
exitPoint?: RenderId;
|
|
18
|
+
};
|
|
19
|
+
type RenderingOptions = {
|
|
20
|
+
elementData: ElementData | Nodes;
|
|
21
|
+
suffixId: string;
|
|
22
|
+
root: RootObject;
|
|
23
|
+
defaults?: RenderObject;
|
|
24
|
+
entryButton?: EntryObject;
|
|
25
|
+
exitElement?: ExitObject;
|
|
26
|
+
};
|
|
27
|
+
type DimensionOptions = {
|
|
28
|
+
values: DimensionList;
|
|
29
|
+
parentOptions?: {
|
|
30
|
+
level1Options?: {
|
|
31
|
+
order: AddOrReferenceNodeList;
|
|
32
|
+
behavior?: Level1Behavior;
|
|
33
|
+
navigationRules?: DimensionNavigationRules;
|
|
34
|
+
};
|
|
35
|
+
addLevel0?: NodeObject;
|
|
36
|
+
};
|
|
37
|
+
adjustDimensions?: AdjustingFunction;
|
|
38
|
+
};
|
|
39
|
+
type Structure = {
|
|
40
|
+
nodes: Nodes;
|
|
41
|
+
edges: Edges;
|
|
42
|
+
dimensions?: Dimensions;
|
|
43
|
+
navigationRules?: NavigationRules;
|
|
44
|
+
elementData?: ElementData;
|
|
45
|
+
};
|
|
46
|
+
type Nodes = Record<NodeId, NodeObject>;
|
|
47
|
+
type Edges = Record<EdgeId, EdgeObject>;
|
|
48
|
+
type Dimensions = Record<DimensionKey, DimensionObject>;
|
|
49
|
+
type NavigationRules = Record<NavId, NavObject>;
|
|
50
|
+
type ElementData = Record<RenderId, RenderObject>;
|
|
51
|
+
type DimensionDivisions = Record<NodeId, DivisionObject>;
|
|
52
|
+
type AddOrReferenceNodeList = Array<NodeToAddOrReference>;
|
|
53
|
+
type EdgeList = Array<EdgeId>;
|
|
54
|
+
type GenericDataset = Array<DatumObject>;
|
|
55
|
+
type NavigationList = Array<NavId>;
|
|
56
|
+
type DimensionNavigationPair = [NavId, NavId];
|
|
57
|
+
type NumericalExtentsPair = [number, number];
|
|
58
|
+
type DimensionList = Array<DimensionDatum>;
|
|
59
|
+
type EdgeOptions = Array<EdgeDatum>;
|
|
60
|
+
type KeyList = Array<string>;
|
|
61
|
+
type Semantics = ((RenderObject?: any, DatumObject?: any) => SemanticsObject) | SemanticsObject;
|
|
62
|
+
type SpatialProperties = ((RenderObject?: any, DatumObject?: any) => SpatialObject) | SpatialObject;
|
|
63
|
+
type Attributes = ((RenderObject?: any, DatumObject?: any) => AttributesObject) | AttributesObject;
|
|
64
|
+
type NodeObject = {
|
|
65
|
+
id: NodeId;
|
|
66
|
+
edges: EdgeList;
|
|
67
|
+
renderId?: RenderId;
|
|
68
|
+
renderingStrategy?: RenderingStrategy;
|
|
69
|
+
derivedNode?: DerivedNode;
|
|
70
|
+
dimensionLevel?: DimensionLevel;
|
|
71
|
+
[key: string | number]: any;
|
|
72
|
+
};
|
|
73
|
+
type EdgeObject = {
|
|
74
|
+
source: ((d: DatumObject, currentFocus: NodeId) => NodeId) | NodeId;
|
|
75
|
+
target: ((d: DatumObject, currentFocus: NodeId) => NodeId) | NodeId;
|
|
76
|
+
navigationRules: NavigationList;
|
|
77
|
+
edgeId?: EdgeId;
|
|
78
|
+
};
|
|
79
|
+
type EdgeDatum = {
|
|
80
|
+
edgeId: EdgeId;
|
|
81
|
+
edge: EdgeObject;
|
|
82
|
+
conditional?: ConditionalFunction;
|
|
83
|
+
};
|
|
84
|
+
type DimensionObject = {
|
|
85
|
+
nodeId: NodeId;
|
|
86
|
+
dimensionKey: DimensionKey;
|
|
87
|
+
divisions: DimensionDivisions;
|
|
88
|
+
operations: {
|
|
89
|
+
compressSparseDivisions: boolean;
|
|
90
|
+
sortFunction?: SortingFunction;
|
|
91
|
+
};
|
|
92
|
+
behavior?: DimensionBehavior;
|
|
93
|
+
navigationRules?: DimensionNavigationRules;
|
|
94
|
+
type?: DimensionType;
|
|
95
|
+
numericalExtents?: NumericalExtentsPair;
|
|
96
|
+
subdivisions?: NumericallySubdivide;
|
|
97
|
+
divisionOptions?: DivisionOptions;
|
|
98
|
+
};
|
|
99
|
+
type DimensionDatum = {
|
|
100
|
+
dimensionKey: DimensionKey;
|
|
101
|
+
behavior?: DimensionBehavior;
|
|
102
|
+
navigationRules?: DimensionNavigationRules;
|
|
103
|
+
type?: DimensionType;
|
|
104
|
+
operations?: DimensionOperations;
|
|
105
|
+
nodeId?: DynamicDimensionId;
|
|
106
|
+
renderId?: DynamicDimensionRenderId;
|
|
107
|
+
renderingStrategy?: RenderingStrategy;
|
|
108
|
+
divisionOptions?: DivisionOptions;
|
|
109
|
+
};
|
|
110
|
+
type DimensionNavigationRules = {
|
|
111
|
+
sibling_sibling: DimensionNavigationPair;
|
|
112
|
+
parent_child: DimensionNavigationPair;
|
|
113
|
+
};
|
|
114
|
+
type DivisionOptions = {
|
|
115
|
+
sortFunction?: SortingFunction;
|
|
116
|
+
divisionNodeIds?: (dimensionKey: DimensionKey, keyValue: any, i: number) => string;
|
|
117
|
+
divisionRenderIds?: (dimensionKey: DimensionKey, keyValue: any, i: number) => string;
|
|
118
|
+
renderingStrategy?: RenderingStrategy;
|
|
119
|
+
};
|
|
120
|
+
type DimensionOperations = {
|
|
121
|
+
filterFunction?: FilteringFunction;
|
|
122
|
+
sortFunction?: SortingFunction;
|
|
123
|
+
createNumericalSubdivisions?: NumericallySubdivide;
|
|
124
|
+
compressSparseDivisions?: boolean;
|
|
125
|
+
};
|
|
126
|
+
type DivisionObject = {
|
|
127
|
+
id: NodeId;
|
|
128
|
+
values: Nodes;
|
|
129
|
+
sortFunction?: SortingFunction;
|
|
130
|
+
numericalExtents?: NumericalExtentsPair;
|
|
131
|
+
};
|
|
132
|
+
type NavObject = {
|
|
133
|
+
direction: Direction;
|
|
134
|
+
key?: string;
|
|
135
|
+
};
|
|
136
|
+
type RenderObject = {
|
|
137
|
+
cssClass?: DynamicString;
|
|
138
|
+
spatialProperties?: SpatialProperties;
|
|
139
|
+
semantics?: Semantics;
|
|
140
|
+
parentSemantics?: Semantics;
|
|
141
|
+
existingElement?: ExistingElement;
|
|
142
|
+
showText?: boolean;
|
|
143
|
+
};
|
|
144
|
+
type RootObject = {
|
|
145
|
+
id: string;
|
|
146
|
+
cssClass?: string;
|
|
147
|
+
description?: string;
|
|
148
|
+
width?: string | number;
|
|
149
|
+
height?: string | number;
|
|
150
|
+
};
|
|
151
|
+
type EntryObject = {
|
|
152
|
+
include: boolean;
|
|
153
|
+
callbacks?: EntryCallbacks;
|
|
154
|
+
};
|
|
155
|
+
type ExitObject = {
|
|
156
|
+
include: boolean;
|
|
157
|
+
callbacks?: ExitCallbacks;
|
|
158
|
+
};
|
|
159
|
+
type SemanticsObject = {
|
|
160
|
+
label?: DynamicString;
|
|
161
|
+
elementType?: DynamicString;
|
|
162
|
+
role?: DynamicString;
|
|
163
|
+
attributes?: Attributes;
|
|
164
|
+
};
|
|
165
|
+
type SpatialObject = {
|
|
166
|
+
x?: DynamicNumber;
|
|
167
|
+
y?: DynamicNumber;
|
|
168
|
+
width?: DynamicNumber;
|
|
169
|
+
height?: DynamicNumber;
|
|
170
|
+
path?: DynamicString;
|
|
171
|
+
};
|
|
172
|
+
type DimensionBehavior = {
|
|
173
|
+
extents: ExtentType;
|
|
174
|
+
customBridgePrevious?: NodeId;
|
|
175
|
+
customBridgePost?: NodeId;
|
|
176
|
+
childmostNavigation?: ChildmostNavigationStrategy;
|
|
177
|
+
childmostMatching?: ChildmostMatchingStrategy;
|
|
178
|
+
};
|
|
179
|
+
type Level1Behavior = {
|
|
180
|
+
extents: Level0ExtentType;
|
|
181
|
+
customBridgePrevious?: NodeId;
|
|
182
|
+
customBridgePost?: NodeId;
|
|
183
|
+
};
|
|
184
|
+
type DescriptionOptions = {
|
|
185
|
+
omitKeyNames?: boolean;
|
|
186
|
+
semanticLabel?: string;
|
|
187
|
+
};
|
|
188
|
+
type ExistingElement = {
|
|
189
|
+
useForSpatialProperties: boolean;
|
|
190
|
+
spatialProperties?: SpatialProperties;
|
|
191
|
+
};
|
|
192
|
+
type EntryCallbacks = {
|
|
193
|
+
focus?: Function;
|
|
194
|
+
click?: Function;
|
|
195
|
+
};
|
|
196
|
+
type ExitCallbacks = {
|
|
197
|
+
focus?: Function;
|
|
198
|
+
blur?: Function;
|
|
199
|
+
};
|
|
200
|
+
type DatumObject = {
|
|
201
|
+
[key: string | number]: any;
|
|
202
|
+
};
|
|
203
|
+
type AttributesObject = {
|
|
204
|
+
[key: string]: string;
|
|
205
|
+
};
|
|
206
|
+
type DynamicNumber = ((r?: RenderObject, d?: DatumObject) => number) | number;
|
|
207
|
+
type DynamicString = ((r?: RenderObject, d?: DatumObject) => string) | string;
|
|
208
|
+
type DynamicNodeId = ((d?: DatumObject, dim?: DimensionDatum) => NodeId) | NodeId;
|
|
209
|
+
type DynamicRenderId = ((d?: DatumObject) => RenderId) | RenderId;
|
|
210
|
+
type DynamicNodeIdKey = ((d?: DatumObject) => string) | string;
|
|
211
|
+
type DynamicRenderIdKey = ((d?: DatumObject) => string) | string;
|
|
212
|
+
type DynamicDimensionId = ((d?: DimensionDatum, a?: GenericDataset) => NodeId) | NodeId;
|
|
213
|
+
type DynamicDimensionRenderId = ((d?: DimensionDatum, a?: GenericDataset) => RenderId) | RenderId;
|
|
214
|
+
type NumericallySubdivide = ((d?: DimensionKey, n?: Nodes) => number) | number;
|
|
215
|
+
type ChildmostMatchingStrategy = (index?: number, currentDivisionChild?: DatumObject, currentDivision?: DivisionObject, nextDivision?: DivisionObject) => DatumObject | undefined;
|
|
216
|
+
type AdjustingFunction = (d: Dimensions) => Dimensions;
|
|
217
|
+
type SortingFunction = (a: DatumObject, b: DatumObject, c?: any) => number;
|
|
218
|
+
type FilteringFunction = (a: DatumObject, b?: any) => boolean;
|
|
219
|
+
type ConditionalFunction = (n: NodeObject, d: EdgeDatum) => boolean;
|
|
220
|
+
type NodeId = string;
|
|
221
|
+
type EdgeId = string;
|
|
222
|
+
type RenderId = string;
|
|
223
|
+
type NavId = string;
|
|
224
|
+
type DimensionId = string;
|
|
225
|
+
type DimensionKey = string;
|
|
226
|
+
type NodeToAddOrReference = NodeObject | NodeId;
|
|
227
|
+
type Direction = 'target' | 'source';
|
|
228
|
+
type RenderingStrategy = 'outlineEach' | 'convexHull' | 'singleSquare' | 'custom';
|
|
229
|
+
type DimensionType = 'numerical' | 'categorical';
|
|
230
|
+
type ExtentType = 'circular' | 'terminal' | 'bridgedCousins' | 'bridgedCustom';
|
|
231
|
+
type ChildmostNavigationStrategy = 'within' | 'across';
|
|
232
|
+
type Level0ExtentType = 'circular' | 'terminal' | 'bridgedCustom';
|
|
233
|
+
type DataType = 'vega-lite' | 'vl' | 'Vega-Lite' | 'generic' | 'default';
|
|
234
|
+
type DimensionLevel = 0 | 1 | 2 | 3;
|
|
235
|
+
type DerivedNode = string;
|
|
236
|
+
type LLMMessage = {
|
|
237
|
+
role: 'user' | 'assistant' | 'system';
|
|
238
|
+
content: string;
|
|
239
|
+
};
|
|
240
|
+
type TextChatOptions = {
|
|
241
|
+
structure: Structure;
|
|
242
|
+
container: string | HTMLElement;
|
|
243
|
+
entryPoint?: NodeId;
|
|
244
|
+
describeNode?: (node: NodeObject) => string;
|
|
245
|
+
commandLabels?: Record<string, string>;
|
|
246
|
+
onNavigate?: (node: NodeObject) => void;
|
|
247
|
+
onExit?: () => void;
|
|
248
|
+
onClick?: (node: NodeObject) => void;
|
|
249
|
+
onHover?: (node: NodeObject) => void;
|
|
250
|
+
llm?: (messages: LLMMessage[]) => Promise<string | null>;
|
|
251
|
+
data?: Record<string, unknown>[];
|
|
252
|
+
};
|
|
253
|
+
type TextChatInstance = {
|
|
254
|
+
destroy: () => void;
|
|
255
|
+
getCurrentNode: () => NodeObject | null;
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
declare const _default: {
|
|
259
|
+
structure: (options: StructureOptions) => Structure;
|
|
260
|
+
input: (options: InputOptions) => any;
|
|
261
|
+
rendering: (options: RenderingOptions) => any;
|
|
262
|
+
textChat: (options: TextChatOptions) => TextChatInstance;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
export { type AddOrReferenceNodeList, type AdjustingFunction, type Attributes, type AttributesObject, type ChildmostMatchingStrategy, type ChildmostNavigationStrategy, type ConditionalFunction, type DataType, type DatumObject, type DerivedNode, type DescriptionOptions, type DimensionBehavior, type DimensionDatum, type DimensionDivisions, type DimensionId, type DimensionKey, type DimensionLevel, type DimensionList, type DimensionNavigationPair, type DimensionNavigationRules, type DimensionObject, type DimensionOperations, type DimensionOptions, type DimensionType, type Dimensions, type Direction, type DivisionObject, type DivisionOptions, type DynamicDimensionId, type DynamicDimensionRenderId, type DynamicNodeId, type DynamicNodeIdKey, type DynamicNumber, type DynamicRenderId, type DynamicRenderIdKey, type DynamicString, type EdgeDatum, type EdgeId, type EdgeList, type EdgeObject, type EdgeOptions, type Edges, type ElementData, type EntryCallbacks, type EntryObject, type ExistingElement, type ExitCallbacks, type ExitObject, type ExtentType, type FilteringFunction, type GenericDataset, type InputOptions, type KeyList, type LLMMessage, type Level0ExtentType, type Level1Behavior, type NavId, type NavObject, type NavigationList, type NavigationRules, type NodeId, type NodeObject, type NodeToAddOrReference, type Nodes, type NumericalExtentsPair, type NumericallySubdivide, type RenderId, type RenderObject, type RenderingOptions, type RenderingStrategy, type RootObject, type Semantics, type SemanticsObject, type SortingFunction, type SpatialObject, type SpatialProperties, type Structure, type StructureOptions, type TextChatInstance, type TextChatOptions, _default as default };
|
package/dist/index.js
CHANGED
|
@@ -439,7 +439,7 @@ var buildNodes = (options) => {
|
|
|
439
439
|
return nodes;
|
|
440
440
|
};
|
|
441
441
|
var scaffoldDimensions = (options, nodes) => {
|
|
442
|
-
var _a, _b;
|
|
442
|
+
var _a, _b, _c;
|
|
443
443
|
let dimensions = {};
|
|
444
444
|
if ((_b = (_a = options.dimensions) == null ? void 0 : _a.parentOptions) == null ? void 0 : _b.addLevel0) {
|
|
445
445
|
let level0 = options.dimensions.parentOptions.addLevel0;
|
|
@@ -453,10 +453,11 @@ var scaffoldDimensions = (options, nodes) => {
|
|
|
453
453
|
dim.numericalExtents[1] = max > val ? max : val;
|
|
454
454
|
};
|
|
455
455
|
options.data.forEach((d) => {
|
|
456
|
-
|
|
456
|
+
var _a2;
|
|
457
|
+
let ods = ((_a2 = options.dimensions) == null ? void 0 : _a2.values) || [];
|
|
457
458
|
let i = 0;
|
|
458
459
|
ods.forEach((dim) => {
|
|
459
|
-
var
|
|
460
|
+
var _a3, _b2, _c2, _d, _e, _f, _g, _h;
|
|
460
461
|
if (!dim.dimensionKey) {
|
|
461
462
|
console.error(
|
|
462
463
|
`Building nodes, parsing dimensions. Each dimension in options.dimensions must contain a dimensionKey. This dimension has no key: ${JSON.stringify(
|
|
@@ -467,7 +468,7 @@ var scaffoldDimensions = (options, nodes) => {
|
|
|
467
468
|
}
|
|
468
469
|
if (dim.dimensionKey in d) {
|
|
469
470
|
let value = d[dim.dimensionKey];
|
|
470
|
-
let keepValue = typeof ((
|
|
471
|
+
let keepValue = typeof ((_a3 = dim.operations) == null ? void 0 : _a3.filterFunction) === "function" ? dim.operations.filterFunction(d, dim) : true;
|
|
471
472
|
if (value !== void 0 && keepValue) {
|
|
472
473
|
if (!dim.type) {
|
|
473
474
|
dim.type = typeof value === "bigint" || typeof value === "number" ? "numerical" : "categorical";
|
|
@@ -483,7 +484,7 @@ var scaffoldDimensions = (options, nodes) => {
|
|
|
483
484
|
type: dim.type,
|
|
484
485
|
operations: {
|
|
485
486
|
compressSparseDivisions: ((_b2 = dim.operations) == null ? void 0 : _b2.compressSparseDivisions) || false,
|
|
486
|
-
sortFunction: ((
|
|
487
|
+
sortFunction: ((_c2 = dim.operations) == null ? void 0 : _c2.sortFunction) || void 0
|
|
487
488
|
},
|
|
488
489
|
behavior: dim.behavior || {
|
|
489
490
|
extents: "circular"
|
|
@@ -557,7 +558,7 @@ var scaffoldDimensions = (options, nodes) => {
|
|
|
557
558
|
});
|
|
558
559
|
});
|
|
559
560
|
Object.keys(dimensions).forEach((s) => {
|
|
560
|
-
var _a2, _b2,
|
|
561
|
+
var _a2, _b2, _c2, _d, _e;
|
|
561
562
|
let dimension = dimensions[s];
|
|
562
563
|
let divisions = dimension.divisions;
|
|
563
564
|
if (dimension.type === "numerical") {
|
|
@@ -576,14 +577,18 @@ var scaffoldDimensions = (options, nodes) => {
|
|
|
576
577
|
let i = dimension.numericalExtents[0] + interval;
|
|
577
578
|
let divisionCount = 0;
|
|
578
579
|
let index = 0;
|
|
580
|
+
let lastDivisionId = null;
|
|
581
|
+
let prevBound = dimension.numericalExtents[0];
|
|
579
582
|
for (i = dimension.numericalExtents[0] + interval; i <= dimension.numericalExtents[1]; i += interval) {
|
|
580
|
-
let divisionId = typeof ((_a2 = dimension.divisionOptions) == null ? void 0 : _a2.divisionNodeIds) === "function" ? dimension.divisionOptions.divisionNodeIds(s, i, i) : dimension.nodeId + "_" + i;
|
|
583
|
+
let divisionId = typeof ((_a2 = dimension.divisionOptions) == null ? void 0 : _a2.divisionNodeIds) === "function" ? dimension.divisionOptions.divisionNodeIds(s, i, i) : createValidId(dimension.nodeId + "_" + i);
|
|
584
|
+
lastDivisionId = divisionId;
|
|
581
585
|
dimension.divisions[divisionId] = {
|
|
582
586
|
id: divisionId,
|
|
583
587
|
sortFunction: ((_b2 = dimension.divisionOptions) == null ? void 0 : _b2.sortFunction) || void 0,
|
|
584
|
-
values: {}
|
|
588
|
+
values: {},
|
|
589
|
+
numericalExtents: [prevBound, i]
|
|
585
590
|
};
|
|
586
|
-
let divisionRenderId = typeof ((
|
|
591
|
+
let divisionRenderId = typeof ((_c2 = dimension.divisionOptions) == null ? void 0 : _c2.divisionRenderIds) === "function" ? dimension.divisionOptions.divisionRenderIds(s, i, i) : divisionId;
|
|
587
592
|
nodes[divisionId] = {
|
|
588
593
|
id: divisionId,
|
|
589
594
|
renderId: divisionRenderId,
|
|
@@ -599,16 +604,25 @@ var scaffoldDimensions = (options, nodes) => {
|
|
|
599
604
|
let node = values[valueKeys[index]];
|
|
600
605
|
let value = node[s];
|
|
601
606
|
if (value <= i) {
|
|
602
|
-
|
|
607
|
+
const leafId = typeof options.idKey === "function" ? options.idKey(node) : node[options.idKey];
|
|
608
|
+
dimension.divisions[divisionId].values[leafId] = node;
|
|
609
|
+
index++;
|
|
603
610
|
} else {
|
|
604
|
-
i += interval;
|
|
605
611
|
limit = true;
|
|
606
612
|
}
|
|
607
|
-
index++;
|
|
608
613
|
}
|
|
614
|
+
prevBound = i;
|
|
609
615
|
divisionCount++;
|
|
610
616
|
}
|
|
611
|
-
|
|
617
|
+
if (lastDivisionId && index < valueKeys.length) {
|
|
618
|
+
while (index < valueKeys.length) {
|
|
619
|
+
let node = values[valueKeys[index]];
|
|
620
|
+
const leafId = typeof options.idKey === "function" ? options.idKey(node) : node[options.idKey];
|
|
621
|
+
dimension.divisions[lastDivisionId].values[leafId] = node;
|
|
622
|
+
index++;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
delete divisions[dimension.nodeId];
|
|
612
626
|
}
|
|
613
627
|
} else if (typeof ((_e = dimension.operations) == null ? void 0 : _e.sortFunction) === "function") {
|
|
614
628
|
dimension.divisions = Object.fromEntries(
|
|
@@ -659,7 +673,7 @@ var scaffoldDimensions = (options, nodes) => {
|
|
|
659
673
|
}
|
|
660
674
|
}
|
|
661
675
|
});
|
|
662
|
-
if (options.dimensions.adjustDimensions) {
|
|
676
|
+
if ((_c = options.dimensions) == null ? void 0 : _c.adjustDimensions) {
|
|
663
677
|
dimensions = options.dimensions.adjustDimensions(dimensions);
|
|
664
678
|
}
|
|
665
679
|
return dimensions;
|
|
@@ -774,6 +788,22 @@ var buildEdges = (options, nodes, dimensions) => {
|
|
|
774
788
|
"source"
|
|
775
789
|
);
|
|
776
790
|
}
|
|
791
|
+
const findNextNonEmptyDivIdx = (fromIdx) => {
|
|
792
|
+
for (let step = 1; step < divisionKeys.length; step++) {
|
|
793
|
+
const idx = (fromIdx + step) % divisionKeys.length;
|
|
794
|
+
if (Object.keys(dimension.divisions[divisionKeys[idx]].values).length > 0)
|
|
795
|
+
return idx;
|
|
796
|
+
}
|
|
797
|
+
return null;
|
|
798
|
+
};
|
|
799
|
+
const findPrevNonEmptyDivIdx = (fromIdx) => {
|
|
800
|
+
for (let step = 1; step < divisionKeys.length; step++) {
|
|
801
|
+
const idx = (fromIdx - step + divisionKeys.length) % divisionKeys.length;
|
|
802
|
+
if (Object.keys(dimension.divisions[divisionKeys[idx]].values).length > 0)
|
|
803
|
+
return idx;
|
|
804
|
+
}
|
|
805
|
+
return null;
|
|
806
|
+
};
|
|
777
807
|
let j = 0;
|
|
778
808
|
divisionKeys.forEach((d) => {
|
|
779
809
|
let division = dimension.divisions[d];
|
|
@@ -796,13 +826,15 @@ var buildEdges = (options, nodes, dimensions) => {
|
|
|
796
826
|
} else {
|
|
797
827
|
createEdge(division.id, dimension.nodeId, dimension.navigationRules.parent_child, "source");
|
|
798
828
|
}
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
829
|
+
if (valueKeys.length > 0) {
|
|
830
|
+
const firstChildId = typeof options.idKey === "function" ? options.idKey(division.values[valueKeys[0]]) : options.idKey;
|
|
831
|
+
createEdge(
|
|
832
|
+
division.id,
|
|
833
|
+
division.values[valueKeys[0]][firstChildId],
|
|
834
|
+
dimension.navigationRules.parent_child,
|
|
835
|
+
"source"
|
|
836
|
+
);
|
|
837
|
+
}
|
|
806
838
|
let i = 0;
|
|
807
839
|
if (valueKeys.length >= 1) {
|
|
808
840
|
valueKeys.forEach((vk) => {
|
|
@@ -823,22 +855,13 @@ var buildEdges = (options, nodes, dimensions) => {
|
|
|
823
855
|
dimension.navigationRules.sibling_sibling
|
|
824
856
|
);
|
|
825
857
|
} else if (i === valueKeys.length - 1 && extents2 === "bridgedCousins") {
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
dimension.navigationRules.sibling_sibling
|
|
834
|
-
);
|
|
835
|
-
} else {
|
|
836
|
-
const targetId = typeof options.idKey === "function" ? options.idKey(dimension.divisions[divisionKeys[0]].values[valueKeys[0]]) : options.idKey;
|
|
837
|
-
createEdge(
|
|
838
|
-
v[id],
|
|
839
|
-
dimension.divisions[divisionKeys[0]].values[valueKeys[0]][targetId],
|
|
840
|
-
dimension.navigationRules.sibling_sibling
|
|
841
|
-
);
|
|
858
|
+
const nextIdx = findNextNonEmptyDivIdx(j);
|
|
859
|
+
if (nextIdx !== null) {
|
|
860
|
+
const nextDivValues = dimension.divisions[divisionKeys[nextIdx]].values;
|
|
861
|
+
const nextDivValueKeys = Object.keys(nextDivValues);
|
|
862
|
+
const targetDatum = nextDivValues[nextDivValueKeys[0]];
|
|
863
|
+
const targetId = typeof options.idKey === "function" ? options.idKey(targetDatum) : options.idKey;
|
|
864
|
+
createEdge(v[id], targetDatum[targetId], dimension.navigationRules.sibling_sibling);
|
|
842
865
|
}
|
|
843
866
|
} else if (i === valueKeys.length - 1 && extents2 === "bridgedCustom") {
|
|
844
867
|
createEdge(
|
|
@@ -855,24 +878,13 @@ var buildEdges = (options, nodes, dimensions) => {
|
|
|
855
878
|
);
|
|
856
879
|
}
|
|
857
880
|
if (!i && extents2 === "bridgedCousins") {
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
dimension.navigationRules.sibling_sibling
|
|
866
|
-
);
|
|
867
|
-
} else {
|
|
868
|
-
const targetId = typeof options.idKey === "function" ? options.idKey(
|
|
869
|
-
dimension.divisions[divisionKeys[divisionKeys.length - 1]].values[valueKeys[valueKeys.length - 1]]
|
|
870
|
-
) : options.idKey;
|
|
871
|
-
createEdge(
|
|
872
|
-
dimension.divisions[divisionKeys[divisionKeys.length - 1]].values[valueKeys[valueKeys.length - 1]][targetId],
|
|
873
|
-
v[id],
|
|
874
|
-
dimension.navigationRules.sibling_sibling
|
|
875
|
-
);
|
|
881
|
+
const prevIdx = findPrevNonEmptyDivIdx(j);
|
|
882
|
+
if (prevIdx !== null) {
|
|
883
|
+
const prevDivValues = dimension.divisions[divisionKeys[prevIdx]].values;
|
|
884
|
+
const prevDivValueKeys = Object.keys(prevDivValues);
|
|
885
|
+
const targetDatum = prevDivValues[prevDivValueKeys[prevDivValueKeys.length - 1]];
|
|
886
|
+
const targetId = typeof options.idKey === "function" ? options.idKey(targetDatum) : options.idKey;
|
|
887
|
+
createEdge(targetDatum[targetId], v[id], dimension.navigationRules.sibling_sibling);
|
|
876
888
|
}
|
|
877
889
|
} else if (!i && extents2 === "bridgedCustom") {
|
|
878
890
|
createEdge(
|
|
@@ -1470,9 +1482,7 @@ var fuzzyMatch = (input, candidates, labels = {}) => {
|
|
|
1470
1482
|
const exactName = candidates.find((c) => c.toLowerCase() === lower);
|
|
1471
1483
|
if (exactName)
|
|
1472
1484
|
return { match: exactName, ambiguous: [] };
|
|
1473
|
-
const exactLabel = candidates.find(
|
|
1474
|
-
(c) => labels[c] && labels[c].toLowerCase() === lower
|
|
1475
|
-
);
|
|
1485
|
+
const exactLabel = candidates.find((c) => labels[c] && labels[c].toLowerCase() === lower);
|
|
1476
1486
|
if (exactLabel)
|
|
1477
1487
|
return { match: exactLabel, ambiguous: [] };
|
|
1478
1488
|
const namePrefix = candidates.filter((c) => c.toLowerCase().startsWith(lower));
|
|
@@ -1566,6 +1576,8 @@ var text_chat_default = (options) => {
|
|
|
1566
1576
|
commandLabels = {},
|
|
1567
1577
|
onNavigate,
|
|
1568
1578
|
onExit,
|
|
1579
|
+
onClick,
|
|
1580
|
+
onHover,
|
|
1569
1581
|
llm,
|
|
1570
1582
|
data
|
|
1571
1583
|
} = options;
|
|
@@ -1730,12 +1742,16 @@ var text_chat_default = (options) => {
|
|
|
1730
1742
|
}
|
|
1731
1743
|
});
|
|
1732
1744
|
if (llm) {
|
|
1733
|
-
addSystemMessage(
|
|
1734
|
-
|
|
1745
|
+
addSystemMessage(
|
|
1746
|
+
'Text navigation ready. Type "enter" to begin navigating, "help" for commands, or ask a question about the data.'
|
|
1747
|
+
);
|
|
1748
|
+
addSystemMessage(
|
|
1749
|
+
'Note: AI-generated answers may be inaccurate. You can ask the model to "verify" any answer \u2014 it will attempt to provide a Python script that checks the claim against the dataset. If a claim cannot be verified with code, it should be verified externally.'
|
|
1750
|
+
);
|
|
1735
1751
|
} else {
|
|
1736
1752
|
addSystemMessage('Text navigation ready. Type "enter" to begin or "help" for available commands.');
|
|
1737
1753
|
}
|
|
1738
|
-
const specialCommands = ["enter", "help", "more", "more help", "clear"];
|
|
1754
|
+
const specialCommands = ["enter", "help", "more", "more help", "clear", "click", "select", "hover", "inspect"];
|
|
1739
1755
|
const moveToNode = (nodeId) => {
|
|
1740
1756
|
const node = inputHandler.moveTo(nodeId);
|
|
1741
1757
|
if (node) {
|
|
@@ -1786,15 +1802,51 @@ var text_chat_default = (options) => {
|
|
|
1786
1802
|
}
|
|
1787
1803
|
if (lower === "help") {
|
|
1788
1804
|
const llmHint = llm ? " You can also type any question about the data." : "";
|
|
1805
|
+
const interactionHints = [];
|
|
1806
|
+
if (onClick)
|
|
1807
|
+
interactionHints.push('"click" or "select"');
|
|
1808
|
+
if (onHover)
|
|
1809
|
+
interactionHints.push('"hover" or "inspect"');
|
|
1810
|
+
const interactionSuffix = interactionHints.length ? ` Interaction: ${interactionHints.join(", ")}.` : "";
|
|
1789
1811
|
if (!currentNodeId) {
|
|
1790
1812
|
addResponse(
|
|
1791
|
-
'Not yet in the structure. Type "enter" to begin navigating, or "move to <search>" to jump to a node.' + llmHint
|
|
1813
|
+
'Not yet in the structure. Type "enter" to begin navigating, or "move to <search>" to jump to a node.' + interactionSuffix + llmHint
|
|
1792
1814
|
);
|
|
1793
1815
|
} else {
|
|
1794
1816
|
const node = structure.nodes[currentNodeId];
|
|
1795
1817
|
const available = getAvailableRules(currentNodeId, node, structure);
|
|
1796
1818
|
const formatted = available.map((r) => formatRule(r, commandLabels));
|
|
1797
|
-
addResponse(`Available: ${formatted.join(", ")}, move to <search>.` + llmHint);
|
|
1819
|
+
addResponse(`Available: ${formatted.join(", ")}, move to <search>.` + interactionSuffix + llmHint);
|
|
1820
|
+
}
|
|
1821
|
+
return;
|
|
1822
|
+
}
|
|
1823
|
+
if (lower === "click" || lower === "select") {
|
|
1824
|
+
if (!currentNodeId) {
|
|
1825
|
+
addResponse('Not in the structure. Type "enter" to begin.');
|
|
1826
|
+
return;
|
|
1827
|
+
}
|
|
1828
|
+
const node = structure.nodes[currentNodeId];
|
|
1829
|
+
if (onClick && node) {
|
|
1830
|
+
onClick(node);
|
|
1831
|
+
addResponse(`Clicked: ${describeNode2(node)}`);
|
|
1832
|
+
} else {
|
|
1833
|
+
addResponse(onClick ? "Nothing to click here." : "Click interaction is not enabled for this chart.");
|
|
1834
|
+
}
|
|
1835
|
+
return;
|
|
1836
|
+
}
|
|
1837
|
+
if (lower === "hover" || lower === "inspect") {
|
|
1838
|
+
if (!currentNodeId) {
|
|
1839
|
+
addResponse('Not in the structure. Type "enter" to begin.');
|
|
1840
|
+
return;
|
|
1841
|
+
}
|
|
1842
|
+
const node = structure.nodes[currentNodeId];
|
|
1843
|
+
if (onHover && node) {
|
|
1844
|
+
onHover(node);
|
|
1845
|
+
addResponse(`Hovering over: ${describeNode2(node)}`);
|
|
1846
|
+
} else {
|
|
1847
|
+
addResponse(
|
|
1848
|
+
onHover ? "Nothing to hover over here." : "Hover interaction is not enabled for this chart."
|
|
1849
|
+
);
|
|
1798
1850
|
}
|
|
1799
1851
|
return;
|
|
1800
1852
|
}
|
|
@@ -1831,7 +1883,9 @@ var text_chat_default = (options) => {
|
|
|
1831
1883
|
return;
|
|
1832
1884
|
}
|
|
1833
1885
|
const llmHint = llm ? " Enter an API key above to ask questions about the data." : "";
|
|
1834
|
-
addResponse(
|
|
1886
|
+
addResponse(
|
|
1887
|
+
'Type "enter" to begin navigating the structure, or "move to <search>" to jump to a node.' + llmHint
|
|
1888
|
+
);
|
|
1835
1889
|
return;
|
|
1836
1890
|
}
|
|
1837
1891
|
const allRules = getAllRuleNames(structure);
|