@visactor/vbi 0.4.19 → 0.4.20

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.
Files changed (52) hide show
  1. package/dist/builder/adapters/vquery-vseed/build-vquery.d.ts +2 -2
  2. package/dist/builder/adapters/vquery-vseed/build-vseed.d.ts +2 -2
  3. package/dist/builder/adapters/vquery-vseed/index.d.ts +3 -3
  4. package/dist/builder/builder.d.ts +6 -6
  5. package/dist/builder/features/chart-type/chart-type-builder.d.ts +20 -1
  6. package/dist/builder/features/chart-type/dimension-encoding.d.ts +4 -0
  7. package/dist/builder/features/chart-type/measure-encoding.d.ts +4 -0
  8. package/dist/builder/features/chart-type/reapply-dimension-encodings.d.ts +2 -0
  9. package/dist/builder/features/chart-type/reapply-measure-encodings.d.ts +2 -0
  10. package/dist/builder/features/dimensions/dim-builder.d.ts +3 -2
  11. package/dist/builder/features/dimensions/dim-node-builder.d.ts +32 -1
  12. package/dist/builder/features/havingFilter/having-builder.d.ts +2 -2
  13. package/dist/builder/features/measures/mea-builder.d.ts +3 -2
  14. package/dist/builder/features/measures/mea-node-builder.d.ts +33 -3
  15. package/dist/builder/features/whereFilter/where-builder.d.ts +2 -2
  16. package/dist/builder/features/whereFilter/where-node-builder.d.ts +11 -2
  17. package/dist/builder/index.d.ts +1 -1
  18. package/dist/builder/modules/build.d.ts +2 -2
  19. package/dist/builder/modules/index.d.ts +2 -2
  20. package/dist/builder/modules/is-empty.d.ts +1 -1
  21. package/dist/index.cjs +1497 -387
  22. package/dist/index.d.ts +2 -2
  23. package/dist/index.js +1489 -379
  24. package/dist/pipeline/vqueryDSL/aggregateMap.d.ts +23 -3
  25. package/dist/pipeline/vqueryDSL/buildOrderBy.d.ts +2 -0
  26. package/dist/pipeline/vqueryDSL/index.d.ts +2 -2
  27. package/dist/pipeline/vqueryDSL/resolveDatePredicate.d.ts +7 -0
  28. package/dist/pipeline/vqueryDSL/types.d.ts +6 -5
  29. package/dist/types/builder/VBIInterface.d.ts +5 -4
  30. package/dist/types/builder/adapter.d.ts +15 -13
  31. package/dist/types/builder/build-vseed.d.ts +3 -0
  32. package/dist/types/builder/context.d.ts +2 -2
  33. package/dist/types/builder/index.d.ts +4 -3
  34. package/dist/types/builder/observe.d.ts +2 -1
  35. package/dist/types/connector/query.d.ts +1 -0
  36. package/dist/types/dsl/dimensions/aggregate.d.ts +15 -0
  37. package/dist/types/dsl/dimensions/dimensions.d.ts +62 -0
  38. package/dist/types/dsl/encoding.d.ts +2 -2
  39. package/dist/types/dsl/havingFilter/having.d.ts +3 -3
  40. package/dist/types/dsl/index.d.ts +5 -3
  41. package/dist/types/dsl/measures/measures.d.ts +151 -4
  42. package/dist/types/dsl/sort.d.ts +13 -0
  43. package/dist/types/dsl/vbi/vbi.d.ts +90 -5
  44. package/dist/types/dsl/whereFilter/date.d.ts +95 -0
  45. package/dist/types/dsl/whereFilter/filters.d.ts +142 -5
  46. package/dist/utils/filter-guards.d.ts +2 -2
  47. package/dist/vbi/create-vbi.d.ts +6 -7
  48. package/dist/vbi/from/from-vbi-dsl-input.d.ts +3 -3
  49. package/dist/vbi/from/set-base-dsl-fields.d.ts +2 -2
  50. package/dist/vbi/generate-empty-dsl.d.ts +2 -2
  51. package/dist/vbi/normalize/types.d.ts +3 -3
  52. package/package.json +5 -5
package/dist/index.cjs CHANGED
@@ -27,19 +27,19 @@ __webpack_require__.d(__webpack_exports__, {
27
27
  HavingFilterBuilder: ()=>HavingFilterBuilder,
28
28
  WhereFilterBuilder: ()=>WhereFilterBuilder,
29
29
  isVBIHavingGroup: ()=>isVBIHavingGroup,
30
- resolveVBIBuilderAdapters: ()=>resolveVBIBuilderAdapters,
31
- VBIBuilder: ()=>VBIBuilder,
30
+ resolveVBIChartBuilderAdapters: ()=>resolveVBIChartBuilderAdapters,
32
31
  VBI: ()=>VBI,
33
32
  isVBIHavingFilter: ()=>isVBIHavingFilter,
34
33
  ThemeBuilder: ()=>ThemeBuilder,
35
34
  findTreeNodesBy: ()=>vseed_namespaceObject.findTreeNodesBy,
36
35
  id: ()=>id_id,
37
36
  createVBI: ()=>createVBI,
38
- defaultVBIBuilderAdapters: ()=>defaultVBIBuilderAdapters,
39
37
  MeasuresBuilder: ()=>MeasuresBuilder,
40
38
  LimitBuilder: ()=>LimitBuilder,
41
39
  DimensionsBuilder: ()=>DimensionsBuilder,
42
40
  ChartTypeBuilder: ()=>ChartTypeBuilder,
41
+ VBIChartBuilder: ()=>VBIChartBuilder,
42
+ defaultVBIChartBuilderAdapters: ()=>defaultVBIChartBuilderAdapters,
43
43
  isVBIFilter: ()=>isVBIFilter,
44
44
  isVBIWhereGroup: ()=>isVBIWhereGroup,
45
45
  preorderTraverse: ()=>vseed_namespaceObject.preorderTraverse,
@@ -59,250 +59,6 @@ const getConnector = async (id)=>{
59
59
  };
60
60
  const external_yjs_namespaceObject = require("yjs");
61
61
  const external_remeda_namespaceObject = require("remeda");
62
- const VBI_TO_VQUERY_AGGR_FUNC_MAP = {
63
- count: 'count',
64
- countDistinct: 'count_distinct',
65
- sum: 'sum',
66
- avg: 'avg',
67
- min: 'min',
68
- max: 'max',
69
- variance: 'variance',
70
- variancePop: 'variance_pop',
71
- stddev: 'stddev',
72
- median: 'median',
73
- quantile: 'quantile'
74
- };
75
- const mapAggregateForVQuery = (aggregate)=>{
76
- if (!aggregate) return aggregate;
77
- const mappedFunc = VBI_TO_VQUERY_AGGR_FUNC_MAP[aggregate.func] ?? aggregate.func;
78
- return {
79
- ...aggregate,
80
- func: mappedFunc
81
- };
82
- };
83
- const buildSelect = (queryDSL, context)=>{
84
- const { vbiDSL } = context;
85
- const measures = vbiDSL.measures;
86
- const dimensions = vbiDSL.dimensions;
87
- const result = {
88
- ...queryDSL
89
- };
90
- const measureNodes = measures.filter((measure)=>MeasuresBuilder.isMeasureNode(measure));
91
- const measureSelects = measureNodes.map((measure)=>({
92
- field: measure.field,
93
- alias: measure.alias,
94
- aggr: mapAggregateForVQuery(measure.aggregate)
95
- }));
96
- const dimensionNodes = dimensions.filter((dimension)=>DimensionsBuilder.isDimensionNode(dimension));
97
- const dimensionSelects = dimensionNodes.map((dimension)=>({
98
- field: dimension.field,
99
- alias: dimension.alias
100
- }));
101
- result.select = [
102
- ...measureSelects,
103
- ...dimensionSelects
104
- ];
105
- return result;
106
- };
107
- const buildGroupBy = (queryDSL, context)=>{
108
- const result = {
109
- ...queryDSL
110
- };
111
- const { vbiDSL } = context;
112
- const dimensions = vbiDSL.dimensions;
113
- const dimensionNodes = dimensions.filter((dimension)=>DimensionsBuilder.isDimensionNode(dimension));
114
- result.groupBy = dimensionNodes.map((dimension)=>dimension.field);
115
- return result;
116
- };
117
- const buildWhere = (queryDSL, context)=>{
118
- const { vbiDSL } = context;
119
- const whereFilter = vbiDSL.whereFilter;
120
- if (!whereFilter || 0 === whereFilter.conditions.length) return queryDSL;
121
- const result = {
122
- ...queryDSL
123
- };
124
- result.where = mapGroupToCondition(whereFilter);
125
- return result;
126
- };
127
- function isWhereGroup(clause) {
128
- return 'op' in clause && 'conditions' in clause;
129
- }
130
- function mapClauseToCondition(clause) {
131
- if (isWhereGroup(clause)) return [
132
- mapGroupToCondition(clause)
133
- ];
134
- return mapFilterToCondition(clause);
135
- }
136
- function mapGroupToCondition(group) {
137
- return {
138
- op: group.op,
139
- conditions: group.conditions.flatMap(mapClauseToCondition)
140
- };
141
- }
142
- function mapFilterToCondition(filter) {
143
- if ('between' === filter.op || 'not between' === filter.op) return handleBetweenFilter(filter);
144
- return handleSimpleFilter(filter);
145
- }
146
- function handleBetweenFilter(filter) {
147
- const value = normalizeBetweenValue(filter.value);
148
- const lowerCondition = void 0 !== value.min && null !== value.min && '' !== value.min ? {
149
- field: filter.field,
150
- op: '<' === value.leftOp ? '>' : '>=',
151
- value: value.min
152
- } : void 0;
153
- const upperCondition = void 0 !== value.max && null !== value.max && '' !== value.max ? {
154
- field: filter.field,
155
- op: '<' === value.rightOp ? '<' : '<=',
156
- value: value.max
157
- } : void 0;
158
- if ('not between' === filter.op) {
159
- const outsideConditions = [
160
- lowerCondition && invertLowerBound(lowerCondition),
161
- upperCondition && invertUpperBound(upperCondition)
162
- ].filter(Boolean);
163
- if (outsideConditions.length <= 1) return outsideConditions;
164
- return [
165
- {
166
- op: 'or',
167
- conditions: outsideConditions
168
- }
169
- ];
170
- }
171
- return [
172
- lowerCondition,
173
- upperCondition
174
- ].filter(Boolean);
175
- }
176
- function normalizeBetweenValue(value) {
177
- if (Array.isArray(value)) return {
178
- min: value[0],
179
- max: value[1],
180
- leftOp: '<=',
181
- rightOp: '<='
182
- };
183
- if ('object' == typeof value && null !== value) return value;
184
- return {};
185
- }
186
- function invertLowerBound(condition) {
187
- return {
188
- field: condition.field,
189
- op: '>' === condition.op ? '<=' : '<',
190
- value: condition.value
191
- };
192
- }
193
- function invertUpperBound(condition) {
194
- return {
195
- field: condition.field,
196
- op: '<' === condition.op ? '>=' : '>',
197
- value: condition.value
198
- };
199
- }
200
- function handleSimpleFilter(filter) {
201
- let mappedOp = filter.op ?? '=';
202
- const value = filter.value;
203
- if (Array.isArray(value)) {
204
- if ('=' === mappedOp) mappedOp = 'in';
205
- if ('!=' === mappedOp) mappedOp = 'not in';
206
- }
207
- return [
208
- {
209
- field: filter.field,
210
- op: mappedOp,
211
- value
212
- }
213
- ];
214
- }
215
- const DEFAULT_HAVING_AGGREGATE = {
216
- func: 'sum'
217
- };
218
- const buildHaving = (queryDSL, context)=>{
219
- const { vbiDSL } = context;
220
- const havingFilter = vbiDSL.havingFilter;
221
- if (!havingFilter || 0 === havingFilter.conditions.length) return queryDSL;
222
- const result = {
223
- ...queryDSL
224
- };
225
- result.having = {
226
- op: havingFilter.op,
227
- conditions: havingFilter.conditions.flatMap(buildHaving_mapClauseToCondition)
228
- };
229
- return result;
230
- };
231
- function isHavingGroup(clause) {
232
- return 'op' in clause && 'conditions' in clause;
233
- }
234
- function buildHaving_mapClauseToCondition(clause) {
235
- if (isHavingGroup(clause)) return [
236
- buildHaving_mapGroupToCondition(clause)
237
- ];
238
- return buildHaving_mapFilterToCondition(clause);
239
- }
240
- function buildHaving_mapGroupToCondition(group) {
241
- return {
242
- op: group.op,
243
- conditions: group.conditions.flatMap(buildHaving_mapClauseToCondition)
244
- };
245
- }
246
- function buildHaving_mapFilterToCondition(filter) {
247
- const mappedOp = normalizeOperator(filter.op, filter.value);
248
- const aggregate = mapAggregateForVQuery(filter.aggregate ?? DEFAULT_HAVING_AGGREGATE);
249
- return [
250
- {
251
- field: filter.field,
252
- aggr: aggregate,
253
- op: mappedOp,
254
- value: filter.value
255
- }
256
- ];
257
- }
258
- function normalizeOperator(op, value) {
259
- let mappedOp = op ?? '=';
260
- if (Array.isArray(value)) {
261
- if ('=' === mappedOp) mappedOp = 'in';
262
- if ('!=' === mappedOp) mappedOp = 'not in';
263
- }
264
- return mappedOp;
265
- }
266
- const buildLimit = (queryDSL, context)=>{
267
- const result = {
268
- ...queryDSL
269
- };
270
- const limit = context.vbiDSL.limit ?? 1000;
271
- result.limit = limit;
272
- return result;
273
- };
274
- const buildVQuery = (vbiDSL, builder)=>{
275
- const wrapper = (processor)=>(queryDSL)=>processor(queryDSL, {
276
- vbiDSL,
277
- builder
278
- });
279
- return (0, external_remeda_namespaceObject.pipe)({}, wrapper(buildSelect), wrapper(buildGroupBy), wrapper(buildWhere), wrapper(buildHaving), wrapper(buildLimit));
280
- };
281
- const buildVQueryDSL = ({ vbiDSL, builder })=>buildVQuery(vbiDSL, builder);
282
- const buildVSeedDSL = async ({ vbiDSL, queryDSL })=>{
283
- const connectorId = vbiDSL.connectorId;
284
- const connector = await getConnector(connectorId);
285
- const schema = await connector.discoverSchema();
286
- const queryResult = await connector.query({
287
- queryDSL,
288
- schema,
289
- connectorId
290
- });
291
- return {
292
- chartType: vbiDSL.chartType,
293
- dataset: queryResult.dataset,
294
- theme: vbiDSL.theme,
295
- locale: vbiDSL.locale
296
- };
297
- };
298
- const defaultVBIBuilderAdapters = {
299
- buildVQuery: buildVQueryDSL,
300
- buildVSeed: buildVSeedDSL
301
- };
302
- const resolveVBIBuilderAdapters = (adapters)=>({
303
- buildVQuery: adapters?.buildVQuery ?? defaultVBIBuilderAdapters.buildVQuery,
304
- buildVSeed: adapters?.buildVSeed ?? defaultVBIBuilderAdapters.buildVSeed
305
- });
306
62
  class MeasureNodeBuilder {
307
63
  yMap;
308
64
  constructor(yMap){
@@ -314,6 +70,12 @@ class MeasureNodeBuilder {
314
70
  getField() {
315
71
  return this.yMap.get('field');
316
72
  }
73
+ getEncoding() {
74
+ return this.yMap.get('encoding');
75
+ }
76
+ getSort() {
77
+ return this.yMap.get('sort');
78
+ }
317
79
  setAlias(alias) {
318
80
  this.yMap.set('alias', alias);
319
81
  return this;
@@ -322,10 +84,29 @@ class MeasureNodeBuilder {
322
84
  this.yMap.set('encoding', encoding);
323
85
  return this;
324
86
  }
87
+ setSort(sort) {
88
+ this.yMap.set('sort', sort);
89
+ return this;
90
+ }
325
91
  setAggregate(aggregate) {
326
92
  this.yMap.set('aggregate', aggregate);
327
93
  return this;
328
94
  }
95
+ setFormat(format) {
96
+ this.yMap.set('format', format);
97
+ return this;
98
+ }
99
+ getFormat() {
100
+ return this.yMap.get('format');
101
+ }
102
+ clearFormat() {
103
+ this.yMap.delete('format');
104
+ return this;
105
+ }
106
+ clearSort() {
107
+ this.yMap.delete('sort');
108
+ return this;
109
+ }
329
110
  toJSON() {
330
111
  return this.yMap.toJSON();
331
112
  }
@@ -360,9 +141,369 @@ const normalizeMeasureNodeIds = (measures)=>{
360
141
  });
361
142
  };
362
143
  const locateMeasureIndexById = (measures, measureId)=>measures.toArray().findIndex((item)=>item.get('id') === measureId);
144
+ const MEASURE_ENCODING_SUPPORT = {
145
+ table: [
146
+ 'column'
147
+ ],
148
+ pivotTable: [
149
+ 'detail'
150
+ ],
151
+ column: [
152
+ 'yAxis',
153
+ 'detail',
154
+ 'color',
155
+ 'label',
156
+ 'tooltip'
157
+ ],
158
+ columnParallel: [
159
+ 'yAxis',
160
+ 'detail',
161
+ 'color',
162
+ 'label',
163
+ 'tooltip'
164
+ ],
165
+ columnPercent: [
166
+ 'yAxis',
167
+ 'detail',
168
+ 'color',
169
+ 'label',
170
+ 'tooltip'
171
+ ],
172
+ line: [
173
+ 'yAxis',
174
+ 'detail',
175
+ 'color',
176
+ 'label',
177
+ 'tooltip'
178
+ ],
179
+ area: [
180
+ 'yAxis',
181
+ 'detail',
182
+ 'color',
183
+ 'label',
184
+ 'tooltip'
185
+ ],
186
+ areaPercent: [
187
+ 'yAxis',
188
+ 'detail',
189
+ 'color',
190
+ 'label',
191
+ 'tooltip'
192
+ ],
193
+ bar: [
194
+ 'xAxis',
195
+ 'detail',
196
+ 'color',
197
+ 'label',
198
+ 'tooltip'
199
+ ],
200
+ barParallel: [
201
+ 'xAxis',
202
+ 'detail',
203
+ 'color',
204
+ 'label',
205
+ 'tooltip'
206
+ ],
207
+ barPercent: [
208
+ 'xAxis',
209
+ 'detail',
210
+ 'color',
211
+ 'label',
212
+ 'tooltip'
213
+ ],
214
+ dualAxis: [
215
+ 'primaryYAxis',
216
+ 'secondaryYAxis',
217
+ 'color',
218
+ 'label',
219
+ 'tooltip'
220
+ ],
221
+ scatter: [
222
+ 'xAxis',
223
+ 'yAxis',
224
+ 'size',
225
+ 'color',
226
+ 'label',
227
+ 'tooltip'
228
+ ],
229
+ pie: [
230
+ 'angle',
231
+ 'detail',
232
+ 'color',
233
+ 'label',
234
+ 'tooltip'
235
+ ],
236
+ donut: [
237
+ 'angle',
238
+ 'detail',
239
+ 'color',
240
+ 'label',
241
+ 'tooltip'
242
+ ],
243
+ rose: [
244
+ 'radius',
245
+ 'detail',
246
+ 'color',
247
+ 'label',
248
+ 'tooltip'
249
+ ],
250
+ roseParallel: [
251
+ 'radius',
252
+ 'detail',
253
+ 'color',
254
+ 'label',
255
+ 'tooltip'
256
+ ],
257
+ radar: [
258
+ 'radius',
259
+ 'detail',
260
+ 'color',
261
+ 'label',
262
+ 'tooltip'
263
+ ],
264
+ funnel: [
265
+ 'size',
266
+ 'detail',
267
+ 'color',
268
+ 'label',
269
+ 'tooltip'
270
+ ],
271
+ heatmap: [
272
+ 'color',
273
+ 'detail',
274
+ 'label',
275
+ 'tooltip'
276
+ ],
277
+ histogram: [
278
+ 'value',
279
+ 'x0',
280
+ 'x1',
281
+ 'yAxis',
282
+ 'detail',
283
+ 'color',
284
+ 'label',
285
+ 'tooltip'
286
+ ],
287
+ boxplot: [
288
+ 'value',
289
+ 'q1',
290
+ 'q3',
291
+ 'min',
292
+ 'max',
293
+ 'median',
294
+ 'outliers',
295
+ 'color',
296
+ 'label',
297
+ 'tooltip'
298
+ ],
299
+ treeMap: [
300
+ 'size',
301
+ 'detail',
302
+ 'color',
303
+ 'label',
304
+ 'tooltip'
305
+ ],
306
+ sunburst: [
307
+ 'size',
308
+ 'detail',
309
+ 'color',
310
+ 'label',
311
+ 'tooltip'
312
+ ],
313
+ circlePacking: [
314
+ 'size',
315
+ 'detail',
316
+ 'color',
317
+ 'label',
318
+ 'tooltip'
319
+ ],
320
+ raceBar: [
321
+ 'xAxis',
322
+ 'detail',
323
+ 'color',
324
+ 'label',
325
+ 'tooltip'
326
+ ],
327
+ raceColumn: [
328
+ 'yAxis',
329
+ 'detail',
330
+ 'color',
331
+ 'label',
332
+ 'tooltip'
333
+ ],
334
+ raceLine: [
335
+ 'yAxis',
336
+ 'detail',
337
+ 'color',
338
+ 'label',
339
+ 'tooltip'
340
+ ],
341
+ raceScatter: [
342
+ 'xAxis',
343
+ 'yAxis',
344
+ 'size',
345
+ 'color',
346
+ 'label',
347
+ 'tooltip'
348
+ ],
349
+ racePie: [
350
+ 'angle',
351
+ 'detail',
352
+ 'color',
353
+ 'label',
354
+ 'tooltip'
355
+ ],
356
+ raceDonut: [
357
+ 'angle',
358
+ 'detail',
359
+ 'color',
360
+ 'label',
361
+ 'tooltip'
362
+ ]
363
+ };
364
+ const repeatEncoding = (first, rest = first)=>(index)=>0 === index ? first : rest;
365
+ const STRATEGY_BY_CHART_TYPE = {
366
+ [vseed_namespaceObject.ChartTypeEnum.Table]: {
367
+ supported: MEASURE_ENCODING_SUPPORT.table,
368
+ recommend: repeatEncoding('column')
369
+ },
370
+ [vseed_namespaceObject.ChartTypeEnum.PivotTable]: {
371
+ supported: MEASURE_ENCODING_SUPPORT.pivotTable,
372
+ recommend: repeatEncoding('detail')
373
+ },
374
+ [vseed_namespaceObject.ChartTypeEnum.Column]: {
375
+ supported: MEASURE_ENCODING_SUPPORT.column,
376
+ recommend: repeatEncoding('yAxis')
377
+ },
378
+ [vseed_namespaceObject.ChartTypeEnum.ColumnParallel]: {
379
+ supported: MEASURE_ENCODING_SUPPORT.columnParallel,
380
+ recommend: repeatEncoding('yAxis')
381
+ },
382
+ [vseed_namespaceObject.ChartTypeEnum.ColumnPercent]: {
383
+ supported: MEASURE_ENCODING_SUPPORT.columnPercent,
384
+ recommend: repeatEncoding('yAxis')
385
+ },
386
+ [vseed_namespaceObject.ChartTypeEnum.Line]: {
387
+ supported: MEASURE_ENCODING_SUPPORT.line,
388
+ recommend: repeatEncoding('yAxis')
389
+ },
390
+ [vseed_namespaceObject.ChartTypeEnum.Area]: {
391
+ supported: MEASURE_ENCODING_SUPPORT.area,
392
+ recommend: repeatEncoding('yAxis')
393
+ },
394
+ [vseed_namespaceObject.ChartTypeEnum.AreaPercent]: {
395
+ supported: MEASURE_ENCODING_SUPPORT.areaPercent,
396
+ recommend: repeatEncoding('yAxis')
397
+ },
398
+ [vseed_namespaceObject.ChartTypeEnum.Bar]: {
399
+ supported: MEASURE_ENCODING_SUPPORT.bar,
400
+ recommend: repeatEncoding('xAxis')
401
+ },
402
+ [vseed_namespaceObject.ChartTypeEnum.BarParallel]: {
403
+ supported: MEASURE_ENCODING_SUPPORT.barParallel,
404
+ recommend: repeatEncoding('xAxis')
405
+ },
406
+ [vseed_namespaceObject.ChartTypeEnum.BarPercent]: {
407
+ supported: MEASURE_ENCODING_SUPPORT.barPercent,
408
+ recommend: repeatEncoding('xAxis')
409
+ },
410
+ [vseed_namespaceObject.ChartTypeEnum.DualAxis]: {
411
+ supported: MEASURE_ENCODING_SUPPORT.dualAxis,
412
+ recommend: (index)=>0 === index ? 'primaryYAxis' : 'secondaryYAxis'
413
+ },
414
+ [vseed_namespaceObject.ChartTypeEnum.Scatter]: {
415
+ supported: MEASURE_ENCODING_SUPPORT.scatter,
416
+ recommend: (index)=>0 === index ? 'xAxis' : 'yAxis'
417
+ },
418
+ [vseed_namespaceObject.ChartTypeEnum.Pie]: {
419
+ supported: MEASURE_ENCODING_SUPPORT.pie,
420
+ recommend: repeatEncoding('angle')
421
+ },
422
+ [vseed_namespaceObject.ChartTypeEnum.Donut]: {
423
+ supported: MEASURE_ENCODING_SUPPORT.donut,
424
+ recommend: repeatEncoding('angle')
425
+ },
426
+ [vseed_namespaceObject.ChartTypeEnum.Rose]: {
427
+ supported: MEASURE_ENCODING_SUPPORT.rose,
428
+ recommend: repeatEncoding('radius')
429
+ },
430
+ [vseed_namespaceObject.ChartTypeEnum.RoseParallel]: {
431
+ supported: MEASURE_ENCODING_SUPPORT.roseParallel,
432
+ recommend: repeatEncoding('radius')
433
+ },
434
+ [vseed_namespaceObject.ChartTypeEnum.Radar]: {
435
+ supported: MEASURE_ENCODING_SUPPORT.radar,
436
+ recommend: repeatEncoding('radius')
437
+ },
438
+ [vseed_namespaceObject.ChartTypeEnum.Funnel]: {
439
+ supported: MEASURE_ENCODING_SUPPORT.funnel,
440
+ recommend: repeatEncoding('size')
441
+ },
442
+ [vseed_namespaceObject.ChartTypeEnum.Heatmap]: {
443
+ supported: MEASURE_ENCODING_SUPPORT.heatmap,
444
+ recommend: repeatEncoding('color')
445
+ },
446
+ [vseed_namespaceObject.ChartTypeEnum.Histogram]: {
447
+ supported: MEASURE_ENCODING_SUPPORT.histogram,
448
+ recommend: repeatEncoding('value')
449
+ },
450
+ [vseed_namespaceObject.ChartTypeEnum.Boxplot]: {
451
+ supported: MEASURE_ENCODING_SUPPORT.boxplot,
452
+ recommend: repeatEncoding('value')
453
+ },
454
+ [vseed_namespaceObject.ChartTypeEnum.TreeMap]: {
455
+ supported: MEASURE_ENCODING_SUPPORT.treeMap,
456
+ recommend: repeatEncoding('size')
457
+ },
458
+ [vseed_namespaceObject.ChartTypeEnum.Sunburst]: {
459
+ supported: MEASURE_ENCODING_SUPPORT.sunburst,
460
+ recommend: repeatEncoding('size')
461
+ },
462
+ [vseed_namespaceObject.ChartTypeEnum.CirclePacking]: {
463
+ supported: MEASURE_ENCODING_SUPPORT.circlePacking,
464
+ recommend: repeatEncoding('size')
465
+ },
466
+ [vseed_namespaceObject.ChartTypeEnum.RaceBar]: {
467
+ supported: MEASURE_ENCODING_SUPPORT.raceBar,
468
+ recommend: repeatEncoding('xAxis')
469
+ },
470
+ [vseed_namespaceObject.ChartTypeEnum.RaceColumn]: {
471
+ supported: MEASURE_ENCODING_SUPPORT.raceColumn,
472
+ recommend: repeatEncoding('yAxis')
473
+ },
474
+ [vseed_namespaceObject.ChartTypeEnum.RaceLine]: {
475
+ supported: MEASURE_ENCODING_SUPPORT.raceLine,
476
+ recommend: repeatEncoding('yAxis')
477
+ },
478
+ [vseed_namespaceObject.ChartTypeEnum.RaceScatter]: {
479
+ supported: MEASURE_ENCODING_SUPPORT.raceScatter,
480
+ recommend: (index)=>0 === index ? 'xAxis' : 'yAxis'
481
+ },
482
+ [vseed_namespaceObject.ChartTypeEnum.RacePie]: {
483
+ supported: MEASURE_ENCODING_SUPPORT.racePie,
484
+ recommend: repeatEncoding('angle')
485
+ },
486
+ [vseed_namespaceObject.ChartTypeEnum.RaceDonut]: {
487
+ supported: MEASURE_ENCODING_SUPPORT.raceDonut,
488
+ recommend: repeatEncoding('angle')
489
+ }
490
+ };
491
+ const DEFAULT_STRATEGY = STRATEGY_BY_CHART_TYPE[vseed_namespaceObject.ChartTypeEnum.Table];
492
+ const getSupportedMeasureEncodingsForChartType = (chartType)=>[
493
+ ...(STRATEGY_BY_CHART_TYPE[chartType] || DEFAULT_STRATEGY).supported
494
+ ];
495
+ const getRecommendedMeasureEncodingsForChartType = (chartType, measureCount)=>{
496
+ const strategy = STRATEGY_BY_CHART_TYPE[chartType] || DEFAULT_STRATEGY;
497
+ if (measureCount <= 0) return [];
498
+ return Array.from({
499
+ length: measureCount
500
+ }, (_, index)=>strategy.recommend(index));
501
+ };
363
502
  class MeasuresBuilder {
503
+ doc;
364
504
  dsl;
365
505
  constructor(doc, dsl){
506
+ this.doc = doc;
366
507
  this.dsl = dsl;
367
508
  doc.transact(()=>{
368
509
  const measures = getOrCreateMeasures(this.dsl);
@@ -370,38 +511,47 @@ class MeasuresBuilder {
370
511
  });
371
512
  }
372
513
  add(field, callback) {
514
+ const measures = getOrCreateMeasures(this.dsl);
515
+ const chartType = this.dsl.get('chartType') || 'table';
516
+ const [encoding] = getRecommendedMeasureEncodingsForChartType(chartType, measures.length + 1).slice(-1);
373
517
  const measure = {
374
518
  id: id_id.uuid(),
375
519
  alias: field,
376
520
  field,
377
- encoding: 'yAxis',
521
+ encoding,
378
522
  aggregate: {
379
523
  func: 'sum'
380
524
  }
381
525
  };
382
526
  const yMap = new external_yjs_namespaceObject.Map();
383
- for (const [key, value] of Object.entries(measure))yMap.set(key, value);
384
- const measures = getOrCreateMeasures(this.dsl);
385
- measures.push([
386
- yMap
387
- ]);
388
- const node = new MeasureNodeBuilder(yMap);
389
- callback(node);
527
+ this.doc.transact(()=>{
528
+ for (const [key, value] of Object.entries(measure))yMap.set(key, value);
529
+ const measures = getOrCreateMeasures(this.dsl);
530
+ measures.push([
531
+ yMap
532
+ ]);
533
+ const node = new MeasureNodeBuilder(yMap);
534
+ callback(node);
535
+ });
390
536
  return this;
391
537
  }
392
538
  remove(id) {
393
- const measures = getOrCreateMeasures(this.dsl);
394
- const index = locateMeasureIndexById(measures, id);
395
- if (-1 !== index) measures.delete(index, 1);
539
+ this.doc.transact(()=>{
540
+ const measures = getOrCreateMeasures(this.dsl);
541
+ const index = locateMeasureIndexById(measures, id);
542
+ if (-1 !== index) measures.delete(index, 1);
543
+ });
396
544
  return this;
397
545
  }
398
546
  update(id, callback) {
399
- const measures = getOrCreateMeasures(this.dsl);
400
- const index = locateMeasureIndexById(measures, id);
401
- if (-1 === index) throw new Error(`Measure with id "${id}" not found`);
402
- const measureYMap = measures.get(index);
403
- const node = new MeasureNodeBuilder(measureYMap);
404
- callback(node);
547
+ this.doc.transact(()=>{
548
+ const measures = getOrCreateMeasures(this.dsl);
549
+ const index = locateMeasureIndexById(measures, id);
550
+ if (-1 === index) throw new Error(`Measure with id "${id}" not found`);
551
+ const measureYMap = measures.get(index);
552
+ const node = new MeasureNodeBuilder(measureYMap);
553
+ callback(node);
554
+ });
405
555
  return this;
406
556
  }
407
557
  find(predicate) {
@@ -422,9 +572,9 @@ class MeasuresBuilder {
422
572
  }
423
573
  observe(callback) {
424
574
  const measures = getOrCreateMeasures(this.dsl);
425
- measures.observe(callback);
575
+ measures.observeDeep(callback);
426
576
  return ()=>{
427
- measures.unobserve(callback);
577
+ measures.unobserveDeep(callback);
428
578
  };
429
579
  }
430
580
  static isMeasureNode(node) {
@@ -445,10 +595,36 @@ class DimensionNodeBuilder {
445
595
  getField() {
446
596
  return this.yMap.get('field');
447
597
  }
448
- setAlias(alias) {
598
+ getEncoding() {
599
+ return this.yMap.get('encoding');
600
+ }
601
+ getSort() {
602
+ return this.yMap.get('sort');
603
+ }
604
+ setAlias(alias) {
449
605
  this.yMap.set('alias', alias);
450
606
  return this;
451
607
  }
608
+ setEncoding(encoding) {
609
+ this.yMap.set('encoding', encoding);
610
+ return this;
611
+ }
612
+ setSort(sort) {
613
+ this.yMap.set('sort', sort);
614
+ return this;
615
+ }
616
+ setAggregate(aggregate) {
617
+ this.yMap.set('aggregate', aggregate);
618
+ return this;
619
+ }
620
+ clearAggregate() {
621
+ this.yMap.delete('aggregate');
622
+ return this;
623
+ }
624
+ clearSort() {
625
+ this.yMap.delete('sort');
626
+ return this;
627
+ }
452
628
  toJSON() {
453
629
  return this.yMap.toJSON();
454
630
  }
@@ -466,9 +642,423 @@ const normalizeDimensionNodeIds = (dimensions)=>{
466
642
  });
467
643
  };
468
644
  const locateDimensionIndexById = (dimensions, dimensionId)=>dimensions.toArray().findIndex((item)=>item.get('id') === dimensionId);
645
+ const DIMENSION_ENCODING_SUPPORT = {
646
+ table: [
647
+ 'column'
648
+ ],
649
+ pivotTable: [
650
+ 'row',
651
+ 'column'
652
+ ],
653
+ column: [
654
+ 'xAxis',
655
+ 'color',
656
+ 'detail',
657
+ 'tooltip',
658
+ 'label',
659
+ 'row',
660
+ 'column'
661
+ ],
662
+ columnParallel: [
663
+ 'xAxis',
664
+ 'color',
665
+ 'detail',
666
+ 'tooltip',
667
+ 'label',
668
+ 'row',
669
+ 'column'
670
+ ],
671
+ columnPercent: [
672
+ 'xAxis',
673
+ 'color',
674
+ 'detail',
675
+ 'tooltip',
676
+ 'label',
677
+ 'row',
678
+ 'column'
679
+ ],
680
+ line: [
681
+ 'xAxis',
682
+ 'color',
683
+ 'detail',
684
+ 'tooltip',
685
+ 'label',
686
+ 'row',
687
+ 'column'
688
+ ],
689
+ area: [
690
+ 'xAxis',
691
+ 'color',
692
+ 'detail',
693
+ 'tooltip',
694
+ 'label',
695
+ 'row',
696
+ 'column'
697
+ ],
698
+ areaPercent: [
699
+ 'xAxis',
700
+ 'color',
701
+ 'detail',
702
+ 'tooltip',
703
+ 'label',
704
+ 'row',
705
+ 'column'
706
+ ],
707
+ dualAxis: [
708
+ 'xAxis',
709
+ 'color',
710
+ 'detail',
711
+ 'tooltip',
712
+ 'label',
713
+ 'row',
714
+ 'column'
715
+ ],
716
+ bar: [
717
+ 'yAxis',
718
+ 'color',
719
+ 'detail',
720
+ 'tooltip',
721
+ 'label',
722
+ 'row',
723
+ 'column'
724
+ ],
725
+ barParallel: [
726
+ 'yAxis',
727
+ 'color',
728
+ 'detail',
729
+ 'tooltip',
730
+ 'label',
731
+ 'row',
732
+ 'column'
733
+ ],
734
+ barPercent: [
735
+ 'yAxis',
736
+ 'color',
737
+ 'detail',
738
+ 'tooltip',
739
+ 'label',
740
+ 'row',
741
+ 'column'
742
+ ],
743
+ pie: [
744
+ 'color',
745
+ 'detail',
746
+ 'tooltip',
747
+ 'label',
748
+ 'row',
749
+ 'column'
750
+ ],
751
+ donut: [
752
+ 'color',
753
+ 'detail',
754
+ 'tooltip',
755
+ 'label',
756
+ 'row',
757
+ 'column'
758
+ ],
759
+ funnel: [
760
+ 'color',
761
+ 'detail',
762
+ 'tooltip',
763
+ 'label',
764
+ 'row',
765
+ 'column'
766
+ ],
767
+ scatter: [
768
+ 'color',
769
+ 'detail',
770
+ 'tooltip',
771
+ 'label',
772
+ 'row',
773
+ 'column'
774
+ ],
775
+ rose: [
776
+ 'angle',
777
+ 'color',
778
+ 'detail',
779
+ 'tooltip',
780
+ 'label',
781
+ 'row',
782
+ 'column'
783
+ ],
784
+ roseParallel: [
785
+ 'angle',
786
+ 'color',
787
+ 'detail',
788
+ 'tooltip',
789
+ 'label',
790
+ 'row',
791
+ 'column'
792
+ ],
793
+ radar: [
794
+ 'angle',
795
+ 'color',
796
+ 'detail',
797
+ 'tooltip',
798
+ 'label',
799
+ 'row',
800
+ 'column'
801
+ ],
802
+ heatmap: [
803
+ 'xAxis',
804
+ 'yAxis',
805
+ 'color',
806
+ 'detail',
807
+ 'tooltip',
808
+ 'label',
809
+ 'row',
810
+ 'column'
811
+ ],
812
+ boxplot: [
813
+ 'xAxis',
814
+ 'color',
815
+ 'tooltip',
816
+ 'label',
817
+ 'row',
818
+ 'column'
819
+ ],
820
+ histogram: [
821
+ 'color',
822
+ 'detail',
823
+ 'tooltip',
824
+ 'label',
825
+ 'row',
826
+ 'column'
827
+ ],
828
+ treeMap: [
829
+ 'hierarchy',
830
+ 'detail',
831
+ 'tooltip',
832
+ 'label',
833
+ 'row',
834
+ 'column'
835
+ ],
836
+ sunburst: [
837
+ 'hierarchy',
838
+ 'detail',
839
+ 'tooltip',
840
+ 'label',
841
+ 'row',
842
+ 'column'
843
+ ],
844
+ circlePacking: [
845
+ 'hierarchy',
846
+ 'detail',
847
+ 'tooltip',
848
+ 'label',
849
+ 'row',
850
+ 'column'
851
+ ],
852
+ raceBar: [
853
+ 'player',
854
+ 'yAxis',
855
+ 'color',
856
+ 'detail',
857
+ 'tooltip',
858
+ 'label',
859
+ 'row',
860
+ 'column'
861
+ ],
862
+ raceColumn: [
863
+ 'player',
864
+ 'xAxis',
865
+ 'color',
866
+ 'detail',
867
+ 'tooltip',
868
+ 'label',
869
+ 'row',
870
+ 'column'
871
+ ],
872
+ raceLine: [
873
+ 'player',
874
+ 'xAxis',
875
+ 'color',
876
+ 'detail',
877
+ 'tooltip',
878
+ 'label',
879
+ 'row',
880
+ 'column'
881
+ ],
882
+ raceScatter: [
883
+ 'player',
884
+ 'color',
885
+ 'detail',
886
+ 'tooltip',
887
+ 'label',
888
+ 'row',
889
+ 'column'
890
+ ],
891
+ racePie: [
892
+ 'player',
893
+ 'color',
894
+ 'detail',
895
+ 'tooltip',
896
+ 'label',
897
+ 'row',
898
+ 'column'
899
+ ],
900
+ raceDonut: [
901
+ 'player',
902
+ 'color',
903
+ 'detail',
904
+ 'tooltip',
905
+ 'label',
906
+ 'row',
907
+ 'column'
908
+ ]
909
+ };
910
+ const dimension_encoding_repeatEncoding = (first, rest = first)=>(index)=>0 === index ? first : rest;
911
+ const alternateEncoding = (a, b)=>(index)=>index % 2 === 0 ? a : b;
912
+ const dimension_encoding_STRATEGY_BY_CHART_TYPE = {
913
+ [vseed_namespaceObject.ChartTypeEnum.Table]: {
914
+ supported: DIMENSION_ENCODING_SUPPORT.table,
915
+ recommend: dimension_encoding_repeatEncoding('column')
916
+ },
917
+ [vseed_namespaceObject.ChartTypeEnum.PivotTable]: {
918
+ supported: DIMENSION_ENCODING_SUPPORT.pivotTable,
919
+ recommend: alternateEncoding('column', 'row')
920
+ },
921
+ [vseed_namespaceObject.ChartTypeEnum.Column]: {
922
+ supported: DIMENSION_ENCODING_SUPPORT.column,
923
+ recommend: dimension_encoding_repeatEncoding('xAxis', 'color')
924
+ },
925
+ [vseed_namespaceObject.ChartTypeEnum.ColumnParallel]: {
926
+ supported: DIMENSION_ENCODING_SUPPORT.columnParallel,
927
+ recommend: dimension_encoding_repeatEncoding('xAxis', 'color')
928
+ },
929
+ [vseed_namespaceObject.ChartTypeEnum.ColumnPercent]: {
930
+ supported: DIMENSION_ENCODING_SUPPORT.columnPercent,
931
+ recommend: dimension_encoding_repeatEncoding('xAxis', 'color')
932
+ },
933
+ [vseed_namespaceObject.ChartTypeEnum.Line]: {
934
+ supported: DIMENSION_ENCODING_SUPPORT.line,
935
+ recommend: dimension_encoding_repeatEncoding('xAxis', 'color')
936
+ },
937
+ [vseed_namespaceObject.ChartTypeEnum.Area]: {
938
+ supported: DIMENSION_ENCODING_SUPPORT.area,
939
+ recommend: dimension_encoding_repeatEncoding('xAxis', 'color')
940
+ },
941
+ [vseed_namespaceObject.ChartTypeEnum.AreaPercent]: {
942
+ supported: DIMENSION_ENCODING_SUPPORT.areaPercent,
943
+ recommend: dimension_encoding_repeatEncoding('xAxis', 'color')
944
+ },
945
+ [vseed_namespaceObject.ChartTypeEnum.DualAxis]: {
946
+ supported: DIMENSION_ENCODING_SUPPORT.dualAxis,
947
+ recommend: dimension_encoding_repeatEncoding('xAxis', 'color')
948
+ },
949
+ [vseed_namespaceObject.ChartTypeEnum.Bar]: {
950
+ supported: DIMENSION_ENCODING_SUPPORT.bar,
951
+ recommend: dimension_encoding_repeatEncoding('yAxis', 'color')
952
+ },
953
+ [vseed_namespaceObject.ChartTypeEnum.BarParallel]: {
954
+ supported: DIMENSION_ENCODING_SUPPORT.barParallel,
955
+ recommend: dimension_encoding_repeatEncoding('yAxis', 'color')
956
+ },
957
+ [vseed_namespaceObject.ChartTypeEnum.BarPercent]: {
958
+ supported: DIMENSION_ENCODING_SUPPORT.barPercent,
959
+ recommend: dimension_encoding_repeatEncoding('yAxis', 'color')
960
+ },
961
+ [vseed_namespaceObject.ChartTypeEnum.Pie]: {
962
+ supported: DIMENSION_ENCODING_SUPPORT.pie,
963
+ recommend: dimension_encoding_repeatEncoding('color')
964
+ },
965
+ [vseed_namespaceObject.ChartTypeEnum.Donut]: {
966
+ supported: DIMENSION_ENCODING_SUPPORT.donut,
967
+ recommend: dimension_encoding_repeatEncoding('color')
968
+ },
969
+ [vseed_namespaceObject.ChartTypeEnum.Funnel]: {
970
+ supported: DIMENSION_ENCODING_SUPPORT.funnel,
971
+ recommend: dimension_encoding_repeatEncoding('color')
972
+ },
973
+ [vseed_namespaceObject.ChartTypeEnum.Scatter]: {
974
+ supported: DIMENSION_ENCODING_SUPPORT.scatter,
975
+ recommend: dimension_encoding_repeatEncoding('color')
976
+ },
977
+ [vseed_namespaceObject.ChartTypeEnum.Rose]: {
978
+ supported: DIMENSION_ENCODING_SUPPORT.rose,
979
+ recommend: dimension_encoding_repeatEncoding('angle', 'color')
980
+ },
981
+ [vseed_namespaceObject.ChartTypeEnum.RoseParallel]: {
982
+ supported: DIMENSION_ENCODING_SUPPORT.roseParallel,
983
+ recommend: dimension_encoding_repeatEncoding('angle', 'color')
984
+ },
985
+ [vseed_namespaceObject.ChartTypeEnum.Radar]: {
986
+ supported: DIMENSION_ENCODING_SUPPORT.radar,
987
+ recommend: dimension_encoding_repeatEncoding('angle', 'color')
988
+ },
989
+ [vseed_namespaceObject.ChartTypeEnum.Heatmap]: {
990
+ supported: DIMENSION_ENCODING_SUPPORT.heatmap,
991
+ recommend: dimension_encoding_repeatEncoding('xAxis', 'yAxis')
992
+ },
993
+ [vseed_namespaceObject.ChartTypeEnum.Boxplot]: {
994
+ supported: DIMENSION_ENCODING_SUPPORT.boxplot,
995
+ recommend: dimension_encoding_repeatEncoding('xAxis', 'color')
996
+ },
997
+ [vseed_namespaceObject.ChartTypeEnum.Histogram]: {
998
+ supported: DIMENSION_ENCODING_SUPPORT.histogram,
999
+ recommend: dimension_encoding_repeatEncoding('color')
1000
+ },
1001
+ [vseed_namespaceObject.ChartTypeEnum.TreeMap]: {
1002
+ supported: DIMENSION_ENCODING_SUPPORT.treeMap,
1003
+ recommend: dimension_encoding_repeatEncoding('hierarchy')
1004
+ },
1005
+ [vseed_namespaceObject.ChartTypeEnum.Sunburst]: {
1006
+ supported: DIMENSION_ENCODING_SUPPORT.sunburst,
1007
+ recommend: dimension_encoding_repeatEncoding('hierarchy')
1008
+ },
1009
+ [vseed_namespaceObject.ChartTypeEnum.CirclePacking]: {
1010
+ supported: DIMENSION_ENCODING_SUPPORT.circlePacking,
1011
+ recommend: dimension_encoding_repeatEncoding('hierarchy')
1012
+ },
1013
+ [vseed_namespaceObject.ChartTypeEnum.RaceBar]: {
1014
+ supported: DIMENSION_ENCODING_SUPPORT.raceBar,
1015
+ recommend: (index)=>{
1016
+ if (0 === index) return 'player';
1017
+ if (1 === index) return 'yAxis';
1018
+ return 'color';
1019
+ }
1020
+ },
1021
+ [vseed_namespaceObject.ChartTypeEnum.RaceColumn]: {
1022
+ supported: DIMENSION_ENCODING_SUPPORT.raceColumn,
1023
+ recommend: (index)=>{
1024
+ if (0 === index) return 'player';
1025
+ if (1 === index) return 'xAxis';
1026
+ return 'color';
1027
+ }
1028
+ },
1029
+ [vseed_namespaceObject.ChartTypeEnum.RaceLine]: {
1030
+ supported: DIMENSION_ENCODING_SUPPORT.raceLine,
1031
+ recommend: (index)=>0 === index ? 'player' : 'color'
1032
+ },
1033
+ [vseed_namespaceObject.ChartTypeEnum.RaceScatter]: {
1034
+ supported: DIMENSION_ENCODING_SUPPORT.raceScatter,
1035
+ recommend: (index)=>0 === index ? 'player' : 'color'
1036
+ },
1037
+ [vseed_namespaceObject.ChartTypeEnum.RacePie]: {
1038
+ supported: DIMENSION_ENCODING_SUPPORT.racePie,
1039
+ recommend: (index)=>0 === index ? 'player' : 'color'
1040
+ },
1041
+ [vseed_namespaceObject.ChartTypeEnum.RaceDonut]: {
1042
+ supported: DIMENSION_ENCODING_SUPPORT.raceDonut,
1043
+ recommend: (index)=>0 === index ? 'player' : 'color'
1044
+ }
1045
+ };
1046
+ const dimension_encoding_DEFAULT_STRATEGY = dimension_encoding_STRATEGY_BY_CHART_TYPE[vseed_namespaceObject.ChartTypeEnum.Table];
1047
+ const getSupportedDimensionEncodingsForChartType = (chartType)=>[
1048
+ ...(dimension_encoding_STRATEGY_BY_CHART_TYPE[chartType] || dimension_encoding_DEFAULT_STRATEGY).supported
1049
+ ];
1050
+ const getRecommendedDimensionEncodingsForChartType = (chartType, dimensionCount)=>{
1051
+ const strategy = dimension_encoding_STRATEGY_BY_CHART_TYPE[chartType] || dimension_encoding_DEFAULT_STRATEGY;
1052
+ if (dimensionCount <= 0) return [];
1053
+ return Array.from({
1054
+ length: dimensionCount
1055
+ }, (_, index)=>strategy.recommend(index));
1056
+ };
469
1057
  class DimensionsBuilder {
1058
+ doc;
470
1059
  dsl;
471
1060
  constructor(doc, dsl){
1061
+ this.doc = doc;
472
1062
  this.dsl = dsl;
473
1063
  doc.transact(()=>{
474
1064
  const dimensions = getOrCreateDimensions(this.dsl);
@@ -476,34 +1066,44 @@ class DimensionsBuilder {
476
1066
  });
477
1067
  }
478
1068
  add(field, callback) {
1069
+ const dimensions = getOrCreateDimensions(this.dsl);
1070
+ const chartType = this.dsl.get('chartType') || 'table';
1071
+ const [encoding] = getRecommendedDimensionEncodingsForChartType(chartType, dimensions.length + 1).slice(-1);
479
1072
  const dimension = {
480
1073
  id: id_id.uuid(),
481
1074
  alias: field,
482
- field
1075
+ field,
1076
+ encoding
483
1077
  };
484
1078
  const yMap = new external_yjs_namespaceObject.Map();
485
- for (const [key, value] of Object.entries(dimension))yMap.set(key, value);
486
- const dimensions = getOrCreateDimensions(this.dsl);
487
- dimensions.push([
488
- yMap
489
- ]);
490
- const node = new DimensionNodeBuilder(yMap);
491
- callback(node);
1079
+ this.doc.transact(()=>{
1080
+ for (const [key, value] of Object.entries(dimension))yMap.set(key, value);
1081
+ const dimensions = getOrCreateDimensions(this.dsl);
1082
+ dimensions.push([
1083
+ yMap
1084
+ ]);
1085
+ const node = new DimensionNodeBuilder(yMap);
1086
+ callback(node);
1087
+ });
492
1088
  return this;
493
1089
  }
494
1090
  remove(id) {
495
- const dimensions = getOrCreateDimensions(this.dsl);
496
- const index = locateDimensionIndexById(dimensions, id);
497
- if (-1 !== index) dimensions.delete(index, 1);
1091
+ this.doc.transact(()=>{
1092
+ const dimensions = getOrCreateDimensions(this.dsl);
1093
+ const index = locateDimensionIndexById(dimensions, id);
1094
+ if (-1 !== index) dimensions.delete(index, 1);
1095
+ });
498
1096
  return this;
499
1097
  }
500
1098
  update(id, callback) {
501
- const dimensions = getOrCreateDimensions(this.dsl);
502
- const index = locateDimensionIndexById(dimensions, id);
503
- if (-1 === index) throw new Error(`Dimension with id "${id}" not found`);
504
- const dimensionYMap = dimensions.get(index);
505
- const node = new DimensionNodeBuilder(dimensionYMap);
506
- callback(node);
1099
+ this.doc.transact(()=>{
1100
+ const dimensions = getOrCreateDimensions(this.dsl);
1101
+ const index = locateDimensionIndexById(dimensions, id);
1102
+ if (-1 === index) throw new Error(`Dimension with id "${id}" not found`);
1103
+ const dimensionYMap = dimensions.get(index);
1104
+ const node = new DimensionNodeBuilder(dimensionYMap);
1105
+ callback(node);
1106
+ });
507
1107
  return this;
508
1108
  }
509
1109
  find(predicate) {
@@ -524,9 +1124,9 @@ class DimensionsBuilder {
524
1124
  }
525
1125
  observe(callback) {
526
1126
  const dimensions = getOrCreateDimensions(this.dsl);
527
- dimensions.observe(callback);
1127
+ dimensions.observeDeep(callback);
528
1128
  return ()=>{
529
- dimensions.unobserve(callback);
1129
+ dimensions.unobserveDeep(callback);
530
1130
  };
531
1131
  }
532
1132
  static isDimensionNode(node) {
@@ -536,9 +1136,27 @@ class DimensionsBuilder {
536
1136
  return 'children' in node;
537
1137
  }
538
1138
  }
1139
+ const reapplyDimensionEncodings = (dsl, chartType)=>{
1140
+ const dimensions = getOrCreateDimensions(dsl);
1141
+ const nodes = dimensions.toArray().filter((item)=>item instanceof external_yjs_namespaceObject.Map && 'string' == typeof item.get('field'));
1142
+ const encodings = getRecommendedDimensionEncodingsForChartType(chartType, nodes.length);
1143
+ nodes.forEach((node, index)=>{
1144
+ node.set('encoding', encodings[index]);
1145
+ });
1146
+ };
1147
+ const reapplyMeasureEncodings = (dsl, chartType)=>{
1148
+ const measures = getOrCreateMeasures(dsl);
1149
+ const nodes = measures.toArray().filter((item)=>item instanceof external_yjs_namespaceObject.Map && 'string' == typeof item.get('field'));
1150
+ const encodings = getRecommendedMeasureEncodingsForChartType(chartType, nodes.length);
1151
+ nodes.forEach((node, index)=>{
1152
+ node.set('encoding', encodings[index]);
1153
+ });
1154
+ };
539
1155
  class ChartTypeBuilder {
1156
+ doc;
540
1157
  dsl;
541
- constructor(_doc, dsl){
1158
+ constructor(doc, dsl){
1159
+ this.doc = doc;
542
1160
  this.dsl = dsl;
543
1161
  }
544
1162
  observe(callback) {
@@ -551,11 +1169,29 @@ class ChartTypeBuilder {
551
1169
  };
552
1170
  }
553
1171
  changeChartType(chartType) {
554
- this.dsl.set('chartType', chartType);
1172
+ this.doc.transact(()=>{
1173
+ this.dsl.set('chartType', chartType);
1174
+ reapplyDimensionEncodings(this.dsl, chartType);
1175
+ reapplyMeasureEncodings(this.dsl, chartType);
1176
+ });
555
1177
  }
556
1178
  getChartType() {
557
1179
  return this.dsl.get('chartType') || 'table';
558
1180
  }
1181
+ getSupportedDimensionEncodings() {
1182
+ return getSupportedDimensionEncodingsForChartType(this.getChartType());
1183
+ }
1184
+ getRecommendedDimensionEncodings(dimensionCount) {
1185
+ const resolvedCount = dimensionCount ?? this.dsl.get('dimensions')?.length;
1186
+ return getRecommendedDimensionEncodingsForChartType(this.getChartType(), resolvedCount);
1187
+ }
1188
+ getSupportedMeasureEncodings() {
1189
+ return getSupportedMeasureEncodingsForChartType(this.getChartType());
1190
+ }
1191
+ getRecommendedMeasureEncodings(measureCount) {
1192
+ const resolvedCount = measureCount ?? this.dsl.get('measures')?.length;
1193
+ return getRecommendedMeasureEncodingsForChartType(this.getChartType(), resolvedCount);
1194
+ }
559
1195
  toJSON() {
560
1196
  return this.dsl.get('chartType') || 'table';
561
1197
  }
@@ -563,25 +1199,35 @@ class ChartTypeBuilder {
563
1199
  return [
564
1200
  vseed_namespaceObject.ChartTypeEnum.Table,
565
1201
  vseed_namespaceObject.ChartTypeEnum.PivotTable,
566
- vseed_namespaceObject.ChartTypeEnum.Line,
567
1202
  vseed_namespaceObject.ChartTypeEnum.Column,
568
- vseed_namespaceObject.ChartTypeEnum.ColumnPercent,
569
1203
  vseed_namespaceObject.ChartTypeEnum.ColumnParallel,
570
- vseed_namespaceObject.ChartTypeEnum.BarPercent,
1204
+ vseed_namespaceObject.ChartTypeEnum.ColumnPercent,
1205
+ vseed_namespaceObject.ChartTypeEnum.Bar,
571
1206
  vseed_namespaceObject.ChartTypeEnum.BarParallel,
1207
+ vseed_namespaceObject.ChartTypeEnum.BarPercent,
1208
+ vseed_namespaceObject.ChartTypeEnum.Line,
572
1209
  vseed_namespaceObject.ChartTypeEnum.Area,
573
1210
  vseed_namespaceObject.ChartTypeEnum.AreaPercent,
574
1211
  vseed_namespaceObject.ChartTypeEnum.DualAxis,
575
1212
  vseed_namespaceObject.ChartTypeEnum.Scatter,
576
- vseed_namespaceObject.ChartTypeEnum.Rose,
577
- vseed_namespaceObject.ChartTypeEnum.RoseParallel,
578
1213
  vseed_namespaceObject.ChartTypeEnum.Pie,
579
1214
  vseed_namespaceObject.ChartTypeEnum.Donut,
1215
+ vseed_namespaceObject.ChartTypeEnum.Rose,
1216
+ vseed_namespaceObject.ChartTypeEnum.RoseParallel,
580
1217
  vseed_namespaceObject.ChartTypeEnum.Radar,
581
1218
  vseed_namespaceObject.ChartTypeEnum.Funnel,
582
1219
  vseed_namespaceObject.ChartTypeEnum.Heatmap,
583
1220
  vseed_namespaceObject.ChartTypeEnum.Boxplot,
584
- vseed_namespaceObject.ChartTypeEnum.Histogram
1221
+ vseed_namespaceObject.ChartTypeEnum.Histogram,
1222
+ vseed_namespaceObject.ChartTypeEnum.TreeMap,
1223
+ vseed_namespaceObject.ChartTypeEnum.Sunburst,
1224
+ vseed_namespaceObject.ChartTypeEnum.CirclePacking,
1225
+ vseed_namespaceObject.ChartTypeEnum.RaceBar,
1226
+ vseed_namespaceObject.ChartTypeEnum.RaceColumn,
1227
+ vseed_namespaceObject.ChartTypeEnum.RaceLine,
1228
+ vseed_namespaceObject.ChartTypeEnum.RaceScatter,
1229
+ vseed_namespaceObject.ChartTypeEnum.RacePie,
1230
+ vseed_namespaceObject.ChartTypeEnum.RaceDonut
585
1231
  ];
586
1232
  }
587
1233
  }
@@ -592,7 +1238,7 @@ function createWhereGroup(op = 'and', groupId = 'root') {
592
1238
  yMap.set('conditions', new external_yjs_namespaceObject.Array());
593
1239
  return yMap;
594
1240
  }
595
- function where_utils_isWhereGroup(yMap) {
1241
+ function isWhereGroup(yMap) {
596
1242
  return void 0 !== yMap.get('op') && void 0 !== yMap.get('conditions');
597
1243
  }
598
1244
  function findEntry(collection, entryId) {
@@ -604,7 +1250,7 @@ function findEntry(collection, entryId) {
604
1250
  index,
605
1251
  item
606
1252
  };
607
- if (where_utils_isWhereGroup(item)) {
1253
+ if (isWhereGroup(item)) {
608
1254
  const nestedCollection = item.get('conditions');
609
1255
  const nestedMatch = findEntry(nestedCollection, entryId);
610
1256
  if (nestedMatch) return nestedMatch;
@@ -637,6 +1283,15 @@ class WhereFilterNodeBuilder {
637
1283
  this.yMap.set('value', value);
638
1284
  return this;
639
1285
  }
1286
+ setDate(predicate) {
1287
+ this.yMap.set('op', 'date');
1288
+ this.yMap.set('value', predicate);
1289
+ return this;
1290
+ }
1291
+ getDate() {
1292
+ if ('date' !== this.yMap.get('op')) return;
1293
+ return this.yMap.get('value');
1294
+ }
640
1295
  toJSON() {
641
1296
  return this.yMap.toJSON();
642
1297
  }
@@ -797,7 +1452,7 @@ class WhereFilterBuilder {
797
1452
  };
798
1453
  }
799
1454
  static isGroup(yMap) {
800
- return where_utils_isWhereGroup(yMap);
1455
+ return isWhereGroup(yMap);
801
1456
  }
802
1457
  static isNode(yMap) {
803
1458
  return void 0 !== yMap.get('field');
@@ -810,7 +1465,7 @@ function createHavingGroup(op = 'and', groupId = 'root') {
810
1465
  yMap.set('conditions', new external_yjs_namespaceObject.Array());
811
1466
  return yMap;
812
1467
  }
813
- function having_utils_isHavingGroup(yMap) {
1468
+ function isHavingGroup(yMap) {
814
1469
  return void 0 !== yMap.get('op') && void 0 !== yMap.get('conditions');
815
1470
  }
816
1471
  function having_utils_findEntry(collection, entryId) {
@@ -822,7 +1477,7 @@ function having_utils_findEntry(collection, entryId) {
822
1477
  index,
823
1478
  item
824
1479
  };
825
- if (having_utils_isHavingGroup(item)) {
1480
+ if (isHavingGroup(item)) {
826
1481
  const nestedCollection = item.get('conditions');
827
1482
  const nestedMatch = having_utils_findEntry(nestedCollection, entryId);
828
1483
  if (nestedMatch) return nestedMatch;
@@ -1024,7 +1679,7 @@ class HavingFilterBuilder {
1024
1679
  };
1025
1680
  }
1026
1681
  static isGroup(yMap) {
1027
- return having_utils_isHavingGroup(yMap);
1682
+ return isHavingGroup(yMap);
1028
1683
  }
1029
1684
  static isNode(yMap) {
1030
1685
  return void 0 !== yMap.get('field');
@@ -1123,17 +1778,518 @@ class UndoManager {
1123
1778
  this.manager.clear(clearUndoStack, clearRedoStack);
1124
1779
  }
1125
1780
  }
1781
+ const VBI_TO_VQUERY_MEASURE_AGGR_FUNC_MAP = {
1782
+ count: 'count',
1783
+ countDistinct: 'count_distinct',
1784
+ sum: 'sum',
1785
+ avg: 'avg',
1786
+ min: 'min',
1787
+ max: 'max',
1788
+ variance: 'variance',
1789
+ variancePop: 'variance_pop',
1790
+ stddev: 'stddev',
1791
+ median: 'median',
1792
+ quantile: 'quantile'
1793
+ };
1794
+ const VBI_TO_VQUERY_DIMENSION_AGGR_FUNC_MAP = {
1795
+ toYear: 'to_year',
1796
+ toQuarter: 'to_quarter',
1797
+ toMonth: 'to_month',
1798
+ toWeek: 'to_week',
1799
+ toDay: 'to_day',
1800
+ toHour: 'to_hour',
1801
+ toMinute: 'to_minute',
1802
+ toSecond: 'to_second'
1803
+ };
1804
+ const mapAggregateForVQuery = (aggregate)=>{
1805
+ if (!aggregate) return aggregate;
1806
+ const mappedFunc = VBI_TO_VQUERY_MEASURE_AGGR_FUNC_MAP[aggregate.func] ?? aggregate.func;
1807
+ return {
1808
+ ...aggregate,
1809
+ func: mappedFunc
1810
+ };
1811
+ };
1812
+ const mapDimensionAggregateForVQuery = (aggregate)=>{
1813
+ if (!aggregate) return aggregate;
1814
+ const mappedFunc = VBI_TO_VQUERY_DIMENSION_AGGR_FUNC_MAP[aggregate.func] ?? aggregate.func;
1815
+ return {
1816
+ ...aggregate,
1817
+ func: mappedFunc
1818
+ };
1819
+ };
1820
+ const buildSelect = (queryDSL, context)=>{
1821
+ const { vbiDSL } = context;
1822
+ const measures = vbiDSL.measures;
1823
+ const dimensions = vbiDSL.dimensions;
1824
+ const result = {
1825
+ ...queryDSL
1826
+ };
1827
+ const measureNodes = measures.filter((measure)=>MeasuresBuilder.isMeasureNode(measure));
1828
+ const measureSelects = measureNodes.map((measure)=>({
1829
+ field: measure.field,
1830
+ alias: measure.id,
1831
+ aggr: mapAggregateForVQuery(measure.aggregate)
1832
+ }));
1833
+ const dimensionNodes = dimensions.filter((dimension)=>DimensionsBuilder.isDimensionNode(dimension));
1834
+ const dimensionSelects = dimensionNodes.map((dimension)=>{
1835
+ const aggregate = mapDimensionAggregateForVQuery(dimension.aggregate);
1836
+ if (!aggregate) return {
1837
+ field: dimension.field,
1838
+ alias: dimension.id
1839
+ };
1840
+ return {
1841
+ field: dimension.field,
1842
+ alias: dimension.id,
1843
+ aggr: aggregate
1844
+ };
1845
+ });
1846
+ result.select = [
1847
+ ...measureSelects,
1848
+ ...dimensionSelects
1849
+ ];
1850
+ return result;
1851
+ };
1852
+ const buildGroupBy = (queryDSL, context)=>{
1853
+ const result = {
1854
+ ...queryDSL
1855
+ };
1856
+ const { vbiDSL } = context;
1857
+ const dimensions = vbiDSL.dimensions;
1858
+ const dimensionNodes = dimensions.filter((dimension)=>DimensionsBuilder.isDimensionNode(dimension));
1859
+ result.groupBy = dimensionNodes.map((dimension)=>dimension.aggregate ? dimension.id : dimension.field);
1860
+ return result;
1861
+ };
1862
+ function resolveDatePredicate(predicate, now) {
1863
+ switch(predicate.type){
1864
+ case 'range':
1865
+ return resolveRange(predicate);
1866
+ case 'period':
1867
+ return resolvePeriod(predicate);
1868
+ case 'relative':
1869
+ return resolveRelative(predicate, now ?? new Date());
1870
+ case 'current':
1871
+ return resolveCurrent(predicate, now ?? new Date());
1872
+ }
1873
+ }
1874
+ function resolveRange(p) {
1875
+ return {
1876
+ start: toDateString(p.start),
1877
+ end: toDateString(p.end),
1878
+ bounds: p.bounds ?? '[)'
1879
+ };
1880
+ }
1881
+ function resolvePeriod(p) {
1882
+ switch(p.unit){
1883
+ case 'year':
1884
+ return {
1885
+ start: `${p.year}-01-01`,
1886
+ end: `${p.year + 1}-01-01`,
1887
+ bounds: '[)'
1888
+ };
1889
+ case 'quarter':
1890
+ return resolveQuarter(p.year, p.quarter);
1891
+ case 'month':
1892
+ return resolveMonth(p.year, p.month);
1893
+ case 'week':
1894
+ return resolveISOWeek(p.year, p.week);
1895
+ case 'day':
1896
+ return resolveDay(p.date);
1897
+ }
1898
+ }
1899
+ function resolveQuarter(year, quarter) {
1900
+ const startMonth = (quarter - 1) * 3 + 1;
1901
+ const start = formatDate(year, startMonth, 1);
1902
+ const endDate = new Date(Date.UTC(year, startMonth - 1 + 3, 1));
1903
+ return {
1904
+ start,
1905
+ end: utcToDateString(endDate),
1906
+ bounds: '[)'
1907
+ };
1908
+ }
1909
+ function resolveMonth(year, month) {
1910
+ const start = formatDate(year, month, 1);
1911
+ const endDate = new Date(Date.UTC(year, month, 1));
1912
+ return {
1913
+ start,
1914
+ end: utcToDateString(endDate),
1915
+ bounds: '[)'
1916
+ };
1917
+ }
1918
+ function resolveISOWeek(year, week) {
1919
+ const jan4 = new Date(Date.UTC(year, 0, 4));
1920
+ const dayOfWeek = jan4.getUTCDay() || 7;
1921
+ const monday = new Date(jan4.getTime() - (dayOfWeek - 1) * 86400000);
1922
+ const weekStart = new Date(monday.getTime() + (week - 1) * 604800000);
1923
+ const weekEnd = new Date(weekStart.getTime() + 604800000);
1924
+ return {
1925
+ start: utcToDateString(weekStart),
1926
+ end: utcToDateString(weekEnd),
1927
+ bounds: '[)'
1928
+ };
1929
+ }
1930
+ function resolveDay(date) {
1931
+ const d = 'string' == typeof date ? new Date(date + 'T00:00:00Z') : date;
1932
+ const next = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate() + 1));
1933
+ return {
1934
+ start: utcToDateString(d),
1935
+ end: utcToDateString(next),
1936
+ bounds: '[)'
1937
+ };
1938
+ }
1939
+ function resolveRelative(p, now) {
1940
+ const today = truncateToDay(now);
1941
+ const offset = 'last' === p.mode ? -p.amount : p.amount;
1942
+ const shifted = shiftDate(today, offset, p.unit);
1943
+ if ('last' === p.mode) return {
1944
+ start: utcToDateString(shifted),
1945
+ end: utcToDateString(today),
1946
+ bounds: '[)'
1947
+ };
1948
+ return {
1949
+ start: utcToDateString(today),
1950
+ end: utcToDateString(shifted),
1951
+ bounds: '[)'
1952
+ };
1953
+ }
1954
+ function resolveCurrent(p, now) {
1955
+ const offset = p.offset ?? 0;
1956
+ const base = truncateToDay(now);
1957
+ const periodStart = getPeriodStart(base, p.unit, offset);
1958
+ const periodEnd = shiftDate(periodStart, 1, p.unit);
1959
+ return {
1960
+ start: utcToDateString(periodStart),
1961
+ end: utcToDateString(periodEnd),
1962
+ bounds: '[)'
1963
+ };
1964
+ }
1965
+ function getPeriodStart(date, unit, offset) {
1966
+ const y = date.getUTCFullYear();
1967
+ const m = date.getUTCMonth();
1968
+ switch(unit){
1969
+ case 'year':
1970
+ return new Date(Date.UTC(y + offset, 0, 1));
1971
+ case 'quarter':
1972
+ {
1973
+ const q = Math.floor(m / 3);
1974
+ return new Date(Date.UTC(y, (q + offset) * 3, 1));
1975
+ }
1976
+ case 'month':
1977
+ return new Date(Date.UTC(y, m + offset, 1));
1978
+ case 'week':
1979
+ {
1980
+ const dow = date.getUTCDay() || 7;
1981
+ const monday = new Date(date.getTime() - (dow - 1) * 86400000);
1982
+ return new Date(monday.getTime() + 7 * offset * 86400000);
1983
+ }
1984
+ case 'day':
1985
+ return new Date(Date.UTC(y, m, date.getUTCDate() + offset));
1986
+ default:
1987
+ return date;
1988
+ }
1989
+ }
1990
+ function shiftDate(date, amount, unit) {
1991
+ const y = date.getUTCFullYear();
1992
+ const m = date.getUTCMonth();
1993
+ const d = date.getUTCDate();
1994
+ switch(unit){
1995
+ case 'year':
1996
+ return new Date(Date.UTC(y + amount, m, d));
1997
+ case 'quarter':
1998
+ return new Date(Date.UTC(y, m + 3 * amount, d));
1999
+ case 'month':
2000
+ return new Date(Date.UTC(y, m + amount, d));
2001
+ case 'week':
2002
+ return new Date(date.getTime() + 7 * amount * 86400000);
2003
+ case 'day':
2004
+ return new Date(Date.UTC(y, m, d + amount));
2005
+ default:
2006
+ return date;
2007
+ }
2008
+ }
2009
+ function truncateToDay(date) {
2010
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
2011
+ }
2012
+ function toDateString(input) {
2013
+ if ('string' == typeof input) return input;
2014
+ return utcToDateString(input);
2015
+ }
2016
+ function utcToDateString(date) {
2017
+ return formatDate(date.getUTCFullYear(), date.getUTCMonth() + 1, date.getUTCDate());
2018
+ }
2019
+ function formatDate(year, month, day) {
2020
+ const y = String(year);
2021
+ const m = String(month).padStart(2, '0');
2022
+ const d = String(day).padStart(2, '0');
2023
+ return `${y}-${m}-${d}`;
2024
+ }
2025
+ const buildWhere = (queryDSL, context)=>{
2026
+ const { vbiDSL } = context;
2027
+ const whereFilter = vbiDSL.whereFilter;
2028
+ if (!whereFilter || 0 === whereFilter.conditions.length) return queryDSL;
2029
+ const result = {
2030
+ ...queryDSL
2031
+ };
2032
+ result.where = mapGroupToCondition(whereFilter);
2033
+ return result;
2034
+ };
2035
+ function buildWhere_isWhereGroup(clause) {
2036
+ return 'op' in clause && 'conditions' in clause;
2037
+ }
2038
+ function mapClauseToCondition(clause) {
2039
+ if (buildWhere_isWhereGroup(clause)) return [
2040
+ mapGroupToCondition(clause)
2041
+ ];
2042
+ return mapFilterToCondition(clause);
2043
+ }
2044
+ function mapGroupToCondition(group) {
2045
+ return {
2046
+ op: group.op,
2047
+ conditions: group.conditions.flatMap((c)=>mapClauseToCondition(c))
2048
+ };
2049
+ }
2050
+ function mapFilterToCondition(filter) {
2051
+ if ('date' === filter.op) return handleDateFilter(filter.field, filter.value);
2052
+ if ('between' === filter.op || 'not between' === filter.op) return handleBetweenFilter(filter);
2053
+ return handleSimpleFilter(filter);
2054
+ }
2055
+ function handleDateFilter(field, predicate) {
2056
+ const range = resolveDatePredicate(predicate);
2057
+ const startOp = '>=';
2058
+ const endOp = '[]' === range.bounds ? '<=' : '<';
2059
+ return [
2060
+ {
2061
+ field,
2062
+ op: startOp,
2063
+ value: range.start
2064
+ },
2065
+ {
2066
+ field,
2067
+ op: endOp,
2068
+ value: range.end
2069
+ }
2070
+ ];
2071
+ }
2072
+ function handleBetweenFilter(filter) {
2073
+ const value = normalizeBetweenValue(filter.value);
2074
+ const lowerCondition = void 0 !== value.min && null !== value.min && '' !== value.min ? {
2075
+ field: filter.field,
2076
+ op: '<' === value.leftOp ? '>' : '>=',
2077
+ value: value.min
2078
+ } : void 0;
2079
+ const upperCondition = void 0 !== value.max && null !== value.max && '' !== value.max ? {
2080
+ field: filter.field,
2081
+ op: '<' === value.rightOp ? '<' : '<=',
2082
+ value: value.max
2083
+ } : void 0;
2084
+ if ('not between' === filter.op) {
2085
+ const outsideConditions = [
2086
+ lowerCondition && invertLowerBound(lowerCondition),
2087
+ upperCondition && invertUpperBound(upperCondition)
2088
+ ].filter(Boolean);
2089
+ if (outsideConditions.length <= 1) return outsideConditions;
2090
+ return [
2091
+ {
2092
+ op: 'or',
2093
+ conditions: outsideConditions
2094
+ }
2095
+ ];
2096
+ }
2097
+ return [
2098
+ lowerCondition,
2099
+ upperCondition
2100
+ ].filter(Boolean);
2101
+ }
2102
+ function normalizeBetweenValue(value) {
2103
+ if (Array.isArray(value)) return {
2104
+ min: value[0],
2105
+ max: value[1],
2106
+ leftOp: '<=',
2107
+ rightOp: '<='
2108
+ };
2109
+ if ('object' == typeof value && null !== value) return value;
2110
+ return {};
2111
+ }
2112
+ function invertLowerBound(condition) {
2113
+ return {
2114
+ field: condition.field,
2115
+ op: '>' === condition.op ? '<=' : '<',
2116
+ value: condition.value
2117
+ };
2118
+ }
2119
+ function invertUpperBound(condition) {
2120
+ return {
2121
+ field: condition.field,
2122
+ op: '<' === condition.op ? '>=' : '>',
2123
+ value: condition.value
2124
+ };
2125
+ }
2126
+ function handleSimpleFilter(filter) {
2127
+ let mappedOp = filter.op;
2128
+ const value = filter.value;
2129
+ if (Array.isArray(value)) {
2130
+ if ('=' === mappedOp) mappedOp = 'in';
2131
+ if ('!=' === mappedOp) mappedOp = 'not in';
2132
+ }
2133
+ return [
2134
+ {
2135
+ field: filter.field,
2136
+ op: mappedOp,
2137
+ value
2138
+ }
2139
+ ];
2140
+ }
2141
+ const buildHaving = (queryDSL, context)=>{
2142
+ const { vbiDSL } = context;
2143
+ const havingFilter = vbiDSL.havingFilter;
2144
+ if (!havingFilter || 0 === havingFilter.conditions.length) return queryDSL;
2145
+ const result = {
2146
+ ...queryDSL
2147
+ };
2148
+ result.having = {
2149
+ op: havingFilter.op,
2150
+ conditions: havingFilter.conditions.flatMap(buildHaving_mapClauseToCondition)
2151
+ };
2152
+ return result;
2153
+ };
2154
+ function buildHaving_isHavingGroup(clause) {
2155
+ return 'op' in clause && 'conditions' in clause;
2156
+ }
2157
+ function buildHaving_mapClauseToCondition(clause) {
2158
+ if (buildHaving_isHavingGroup(clause)) return [
2159
+ buildHaving_mapGroupToCondition(clause)
2160
+ ];
2161
+ return buildHaving_mapFilterToCondition(clause);
2162
+ }
2163
+ function buildHaving_mapGroupToCondition(group) {
2164
+ return {
2165
+ op: group.op,
2166
+ conditions: group.conditions.flatMap(buildHaving_mapClauseToCondition)
2167
+ };
2168
+ }
2169
+ function buildHaving_mapFilterToCondition(filter) {
2170
+ const mappedOp = normalizeOperator(filter.op, filter.value);
2171
+ const aggregate = mapAggregateForVQuery(filter.aggregate);
2172
+ return [
2173
+ {
2174
+ field: filter.field,
2175
+ aggr: aggregate,
2176
+ op: mappedOp,
2177
+ value: filter.value
2178
+ }
2179
+ ];
2180
+ }
2181
+ function normalizeOperator(op, value) {
2182
+ let mappedOp = op;
2183
+ if (Array.isArray(value)) {
2184
+ if ('=' === mappedOp) mappedOp = 'in';
2185
+ if ('!=' === mappedOp) mappedOp = 'not in';
2186
+ }
2187
+ return mappedOp;
2188
+ }
2189
+ const toOrderItem = (node)=>({
2190
+ field: node.id,
2191
+ order: node.sort?.order
2192
+ });
2193
+ const buildOrderBy = (queryDSL, context)=>{
2194
+ const result = {
2195
+ ...queryDSL
2196
+ };
2197
+ const dimensions = context.vbiDSL.dimensions.filter(DimensionsBuilder.isDimensionNode);
2198
+ const measures = context.vbiDSL.measures.filter(MeasuresBuilder.isMeasureNode);
2199
+ const sortedDimensions = dimensions.filter((node)=>node.sort);
2200
+ const sortedMeasures = measures.filter((node)=>node.sort);
2201
+ const sortedNodes = [
2202
+ ...sortedDimensions,
2203
+ ...sortedMeasures
2204
+ ];
2205
+ if (sortedNodes.length > 0) {
2206
+ result.orderBy = sortedNodes.map(toOrderItem);
2207
+ return result;
2208
+ }
2209
+ const firstDimension = dimensions[0];
2210
+ if (firstDimension) result.orderBy = [
2211
+ {
2212
+ field: firstDimension.id,
2213
+ order: 'asc'
2214
+ }
2215
+ ];
2216
+ return result;
2217
+ };
2218
+ const buildLimit = (queryDSL, context)=>{
2219
+ const result = {
2220
+ ...queryDSL
2221
+ };
2222
+ const limit = context.vbiDSL.limit ?? 1000;
2223
+ result.limit = limit;
2224
+ return result;
2225
+ };
2226
+ const buildVQuery = (vbiDSL, builder)=>{
2227
+ const wrapper = (processor)=>(queryDSL)=>processor(queryDSL, {
2228
+ vbiDSL,
2229
+ builder
2230
+ });
2231
+ return (0, external_remeda_namespaceObject.pipe)({}, wrapper(buildSelect), wrapper(buildGroupBy), wrapper(buildWhere), wrapper(buildHaving), wrapper(buildOrderBy), wrapper(buildLimit));
2232
+ };
2233
+ const buildVQueryDSL = ({ vbiDSL, builder })=>buildVQuery(vbiDSL, builder);
2234
+ const buildVSeedDSL = async ({ vbiDSL, queryDSL, options })=>{
2235
+ const connectorId = vbiDSL.connectorId;
2236
+ const connector = await getConnector(connectorId);
2237
+ const schema = await connector.discoverSchema();
2238
+ const queryResult = await connector.query({
2239
+ queryDSL,
2240
+ schema,
2241
+ connectorId,
2242
+ signal: options.signal
2243
+ });
2244
+ const measures = vbiDSL.measures.filter((measure)=>MeasuresBuilder.isMeasureNode(measure)).map((measure)=>{
2245
+ const nextMeasure = {
2246
+ id: measure.id,
2247
+ alias: measure.alias
2248
+ };
2249
+ if (measure.encoding) nextMeasure.encoding = measure.encoding;
2250
+ if (measure.format) if ('autoFormat' in measure.format && true === measure.format.autoFormat) nextMeasure.autoFormat = true;
2251
+ else {
2252
+ nextMeasure.autoFormat = false;
2253
+ nextMeasure.numFormat = Object.fromEntries(Object.entries(measure.format).filter(([key])=>'autoFormat' !== key));
2254
+ }
2255
+ return nextMeasure;
2256
+ });
2257
+ const dimensions = vbiDSL.dimensions.filter((dimension)=>DimensionsBuilder.isDimensionNode(dimension)).map((dimension)=>{
2258
+ const nextDimension = {
2259
+ id: dimension.id,
2260
+ alias: dimension.alias
2261
+ };
2262
+ if (dimension.encoding) nextDimension.encoding = dimension.encoding;
2263
+ return nextDimension;
2264
+ });
2265
+ return {
2266
+ chartType: vbiDSL.chartType,
2267
+ dataset: queryResult.dataset,
2268
+ dimensions,
2269
+ measures,
2270
+ theme: vbiDSL.theme,
2271
+ locale: vbiDSL.locale
2272
+ };
2273
+ };
2274
+ const defaultVBIChartBuilderAdapters = {
2275
+ buildVQuery: buildVQueryDSL,
2276
+ buildVSeed: buildVSeedDSL
2277
+ };
2278
+ const resolveVBIChartBuilderAdapters = (adapters)=>({
2279
+ buildVQuery: adapters?.buildVQuery ?? defaultVBIChartBuilderAdapters.buildVQuery,
2280
+ buildVSeed: adapters?.buildVSeed ?? defaultVBIChartBuilderAdapters.buildVSeed
2281
+ });
1126
2282
  const applyUpdateToDoc = (doc, update, transactionOrigin)=>{
1127
2283
  external_yjs_namespaceObject.applyUpdate(doc, update, transactionOrigin);
1128
2284
  };
1129
2285
  const encodeDocStateAsUpdate = (doc, targetStateVector)=>external_yjs_namespaceObject.encodeStateAsUpdate(doc, targetStateVector);
1130
- const buildVBIDSL = (dsl)=>dsl.toJSON();
2286
+ const buildVBIChartDSL = (dsl)=>dsl.toJSON();
1131
2287
  const getCollectionLength = (value)=>{
1132
2288
  if (value instanceof external_yjs_namespaceObject.Array) return value.length;
1133
2289
  if (Array.isArray(value)) return value.length;
1134
2290
  return 0;
1135
2291
  };
1136
- const isEmptyVBIDSL = (dsl)=>{
2292
+ const isEmptyVBIChartDSL = (dsl)=>{
1137
2293
  const dimensionsLength = getCollectionLength(dsl.get('dimensions'));
1138
2294
  const measuresLength = getCollectionLength(dsl.get('measures'));
1139
2295
  return 0 === dimensionsLength && 0 === measuresLength;
@@ -1143,7 +2299,7 @@ const getBuilderSchema = async (dsl)=>{
1143
2299
  const connector = await getConnector(connectorId);
1144
2300
  return connector.discoverSchema();
1145
2301
  };
1146
- class VBIBuilder {
2302
+ class VBIChartBuilder {
1147
2303
  doc;
1148
2304
  dsl;
1149
2305
  adapters;
@@ -1159,7 +2315,7 @@ class VBIBuilder {
1159
2315
  constructor(doc, options){
1160
2316
  this.doc = doc;
1161
2317
  this.dsl = doc.getMap('dsl');
1162
- this.adapters = resolveVBIBuilderAdapters(options?.adapters);
2318
+ this.adapters = resolveVBIChartBuilderAdapters(options?.adapters);
1163
2319
  this.undoManager = new UndoManager(this.dsl);
1164
2320
  this.chartType = new ChartTypeBuilder(doc, this.dsl);
1165
2321
  this.measures = new MeasuresBuilder(doc, this.dsl);
@@ -1172,7 +2328,7 @@ class VBIBuilder {
1172
2328
  }
1173
2329
  applyUpdate = (update, transactionOrigin)=>applyUpdateToDoc(this.doc, update, transactionOrigin);
1174
2330
  encodeStateAsUpdate = (targetStateVector)=>encodeDocStateAsUpdate(this.doc, targetStateVector);
1175
- buildVSeed = async ()=>{
2331
+ buildVSeed = async (options = {})=>{
1176
2332
  const vbiDSL = this.build();
1177
2333
  const queryDSL = this.adapters.buildVQuery({
1178
2334
  dsl: this.dsl,
@@ -1183,6 +2339,7 @@ class VBIBuilder {
1183
2339
  dsl: this.dsl,
1184
2340
  vbiDSL,
1185
2341
  queryDSL,
2342
+ options,
1186
2343
  builder: this
1187
2344
  });
1188
2345
  };
@@ -1194,14 +2351,13 @@ class VBIBuilder {
1194
2351
  builder: this
1195
2352
  });
1196
2353
  };
1197
- build = ()=>buildVBIDSL(this.dsl);
1198
- isEmpty = ()=>isEmptyVBIDSL(this.dsl);
2354
+ build = ()=>buildVBIChartDSL(this.dsl);
2355
+ isEmpty = ()=>isEmptyVBIChartDSL(this.dsl);
1199
2356
  getSchema = async ()=>getBuilderSchema(this.dsl);
1200
2357
  }
1201
2358
  const shouldEnsureIdForObject = (obj, ensureId)=>{
1202
2359
  if (true === ensureId) return true;
1203
- if ('field' === ensureId) return 'string' == typeof obj.field;
1204
- return false;
2360
+ return 'field' === ensureId && 'string' == typeof obj.field;
1205
2361
  };
1206
2362
  const toYMap = (obj, ensureId = false)=>{
1207
2363
  const yMap = new external_yjs_namespaceObject.Map();
@@ -1209,23 +2365,9 @@ const toYMap = (obj, ensureId = false)=>{
1209
2365
  for (const [key, value] of Object.entries(obj)){
1210
2366
  if (('conditions' === key || 'children' === key) && Array.isArray(value)) {
1211
2367
  const yArr = new external_yjs_namespaceObject.Array();
1212
- for (const child of value){
1213
- if (child instanceof external_yjs_namespaceObject.Map) {
1214
- yArr.push([
1215
- child
1216
- ]);
1217
- continue;
1218
- }
1219
- if ('object' == typeof child && null !== child) {
1220
- yArr.push([
1221
- toYMap(child, ensureId)
1222
- ]);
1223
- continue;
1224
- }
1225
- yArr.push([
1226
- child
1227
- ]);
1228
- }
2368
+ for (const child of value)yArr.push([
2369
+ toYMap(child, ensureId)
2370
+ ]);
1229
2371
  yMap.set(key, yArr);
1230
2372
  continue;
1231
2373
  }
@@ -1235,65 +2377,34 @@ const toYMap = (obj, ensureId = false)=>{
1235
2377
  };
1236
2378
  const ensureYArray = (arr, ensureId = false)=>{
1237
2379
  if (!arr) return new external_yjs_namespaceObject.Array();
1238
- if (arr instanceof external_yjs_namespaceObject.Array) return arr;
1239
2380
  const yArr = new external_yjs_namespaceObject.Array();
1240
- for (const item of arr){
1241
- if (item instanceof external_yjs_namespaceObject.Map) {
1242
- yArr.push([
1243
- item
1244
- ]);
1245
- continue;
1246
- }
1247
- if ('object' == typeof item && null !== item) {
1248
- yArr.push([
1249
- toYMap(item, ensureId)
1250
- ]);
1251
- continue;
1252
- }
1253
- yArr.push([
1254
- item
1255
- ]);
1256
- }
2381
+ for (const item of arr)yArr.push([
2382
+ toYMap(item, ensureId)
2383
+ ]);
1257
2384
  return yArr;
1258
2385
  };
1259
- const getDefaultWhereFilter = ()=>({
2386
+ const ensureWhereGroup = (whereFilter)=>{
2387
+ const source = whereFilter ?? {
1260
2388
  id: 'root',
1261
2389
  op: 'and',
1262
2390
  conditions: []
1263
- });
1264
- const isFilterGroupInput = (value)=>'object' == typeof value && null !== value;
1265
- const ensureWhereGroup = (whereFilter)=>{
1266
- const sourceWhereFilter = whereFilter instanceof external_yjs_namespaceObject.Map || isFilterGroupInput(whereFilter) ? whereFilter : getDefaultWhereFilter();
1267
- const whereGroup = sourceWhereFilter instanceof external_yjs_namespaceObject.Map ? sourceWhereFilter : createWhereGroup();
1268
- if (sourceWhereFilter instanceof external_yjs_namespaceObject.Map) {
1269
- if (!(whereGroup.get('conditions') instanceof external_yjs_namespaceObject.Array)) whereGroup.set('conditions', new external_yjs_namespaceObject.Array());
1270
- if (!whereGroup.get('id')) whereGroup.set('id', 'root');
1271
- if (!whereGroup.get('op')) whereGroup.set('op', 'and');
1272
- return whereGroup;
1273
- }
1274
- whereGroup.set('id', sourceWhereFilter.id ?? 'root');
1275
- whereGroup.set('op', sourceWhereFilter.op ?? 'and');
1276
- whereGroup.set('conditions', ensureYArray(sourceWhereFilter.conditions, true));
2391
+ };
2392
+ const whereGroup = createWhereGroup();
2393
+ whereGroup.set('id', source.id);
2394
+ whereGroup.set('op', source.op);
2395
+ whereGroup.set('conditions', ensureYArray(source.conditions, true));
1277
2396
  return whereGroup;
1278
2397
  };
1279
- const getDefaultHavingFilter = ()=>({
2398
+ const ensureHavingGroup = (havingFilter)=>{
2399
+ const source = havingFilter ?? {
1280
2400
  id: 'root',
1281
2401
  op: 'and',
1282
2402
  conditions: []
1283
- });
1284
- const ensure_having_group_isFilterGroupInput = (value)=>'object' == typeof value && null !== value;
1285
- const ensureHavingGroup = (havingFilter)=>{
1286
- const sourceHavingFilter = havingFilter instanceof external_yjs_namespaceObject.Map || ensure_having_group_isFilterGroupInput(havingFilter) ? havingFilter : getDefaultHavingFilter();
1287
- const havingGroup = sourceHavingFilter instanceof external_yjs_namespaceObject.Map ? sourceHavingFilter : createHavingGroup();
1288
- if (sourceHavingFilter instanceof external_yjs_namespaceObject.Map) {
1289
- if (!(havingGroup.get('conditions') instanceof external_yjs_namespaceObject.Array)) havingGroup.set('conditions', new external_yjs_namespaceObject.Array());
1290
- if (!havingGroup.get('id')) havingGroup.set('id', 'root');
1291
- if (!havingGroup.get('op')) havingGroup.set('op', 'and');
1292
- return havingGroup;
1293
- }
1294
- havingGroup.set('id', sourceHavingFilter.id ?? 'root');
1295
- havingGroup.set('op', sourceHavingFilter.op ?? 'and');
1296
- havingGroup.set('conditions', ensureYArray(sourceHavingFilter.conditions, true));
2403
+ };
2404
+ const havingGroup = createHavingGroup();
2405
+ havingGroup.set('id', source.id);
2406
+ havingGroup.set('op', source.op);
2407
+ havingGroup.set('conditions', ensureYArray(source.conditions, true));
1297
2408
  return havingGroup;
1298
2409
  };
1299
2410
  const setBaseDSLFields = (dsl, vbi)=>{
@@ -1304,7 +2415,7 @@ const setBaseDSLFields = (dsl, vbi)=>{
1304
2415
  if (vbi.locale) dsl.set('locale', vbi.locale);
1305
2416
  if (void 0 !== vbi.version) dsl.set('version', vbi.version);
1306
2417
  };
1307
- const fromVBIDSLInput = (vbi, options)=>{
2418
+ const createChartBuilderFromVBIChartDSLInput = (vbi, options)=>{
1308
2419
  const doc = new external_yjs_namespaceObject.Doc();
1309
2420
  const dsl = doc.getMap('dsl');
1310
2421
  doc.transact(()=>{
@@ -1314,9 +2425,9 @@ const fromVBIDSLInput = (vbi, options)=>{
1314
2425
  dsl.set('measures', ensureYArray(vbi.measures, 'field'));
1315
2426
  dsl.set('dimensions', ensureYArray(vbi.dimensions, 'field'));
1316
2427
  });
1317
- return new VBIBuilder(doc, options);
2428
+ return new VBIChartBuilder(doc, options);
1318
2429
  };
1319
- const generateEmptyDSL = (connectorId)=>({
2430
+ const generateEmptyChartDSL = (connectorId)=>({
1320
2431
  connectorId,
1321
2432
  chartType: 'table',
1322
2433
  measures: [],
@@ -1348,14 +2459,13 @@ const mergeBuilderOptions = (base, overrides)=>{
1348
2459
  };
1349
2460
  };
1350
2461
  function createVBI(defaultBuilderOptions) {
1351
- const from = (vbi, builderOptions)=>fromVBIDSLInput(vbi, mergeBuilderOptions(defaultBuilderOptions, builderOptions));
2462
+ const createChart = (vbi, builderOptions)=>createChartBuilderFromVBIChartDSLInput(vbi, mergeBuilderOptions(defaultBuilderOptions, builderOptions));
1352
2463
  return {
1353
2464
  connectorMap: connectorMap,
1354
2465
  registerConnector: registerConnector,
1355
2466
  getConnector: getConnector,
1356
- generateEmptyDSL: generateEmptyDSL,
1357
- from,
1358
- create: from
2467
+ generateEmptyChartDSL: generateEmptyChartDSL,
2468
+ createChart
1359
2469
  };
1360
2470
  }
1361
2471
  const VBI = createVBI();
@@ -1368,11 +2478,11 @@ exports.MeasuresBuilder = __webpack_exports__.MeasuresBuilder;
1368
2478
  exports.ThemeBuilder = __webpack_exports__.ThemeBuilder;
1369
2479
  exports.UndoManager = __webpack_exports__.UndoManager;
1370
2480
  exports.VBI = __webpack_exports__.VBI;
1371
- exports.VBIBuilder = __webpack_exports__.VBIBuilder;
2481
+ exports.VBIChartBuilder = __webpack_exports__.VBIChartBuilder;
1372
2482
  exports.WhereFilterBuilder = __webpack_exports__.WhereFilterBuilder;
1373
2483
  exports.buildVQuery = __webpack_exports__.buildVQuery;
1374
2484
  exports.createVBI = __webpack_exports__.createVBI;
1375
- exports.defaultVBIBuilderAdapters = __webpack_exports__.defaultVBIBuilderAdapters;
2485
+ exports.defaultVBIChartBuilderAdapters = __webpack_exports__.defaultVBIChartBuilderAdapters;
1376
2486
  exports.findTreeNodesBy = __webpack_exports__.findTreeNodesBy;
1377
2487
  exports.id = __webpack_exports__.id;
1378
2488
  exports.isVBIFilter = __webpack_exports__.isVBIFilter;
@@ -1380,7 +2490,7 @@ exports.isVBIHavingFilter = __webpack_exports__.isVBIHavingFilter;
1380
2490
  exports.isVBIHavingGroup = __webpack_exports__.isVBIHavingGroup;
1381
2491
  exports.isVBIWhereGroup = __webpack_exports__.isVBIWhereGroup;
1382
2492
  exports.preorderTraverse = __webpack_exports__.preorderTraverse;
1383
- exports.resolveVBIBuilderAdapters = __webpack_exports__.resolveVBIBuilderAdapters;
2493
+ exports.resolveVBIChartBuilderAdapters = __webpack_exports__.resolveVBIChartBuilderAdapters;
1384
2494
  for(var __webpack_i__ in __webpack_exports__)if (-1 === [
1385
2495
  "ChartTypeBuilder",
1386
2496
  "DimensionsBuilder",
@@ -1391,11 +2501,11 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
1391
2501
  "ThemeBuilder",
1392
2502
  "UndoManager",
1393
2503
  "VBI",
1394
- "VBIBuilder",
2504
+ "VBIChartBuilder",
1395
2505
  "WhereFilterBuilder",
1396
2506
  "buildVQuery",
1397
2507
  "createVBI",
1398
- "defaultVBIBuilderAdapters",
2508
+ "defaultVBIChartBuilderAdapters",
1399
2509
  "findTreeNodesBy",
1400
2510
  "id",
1401
2511
  "isVBIFilter",
@@ -1403,7 +2513,7 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
1403
2513
  "isVBIHavingGroup",
1404
2514
  "isVBIWhereGroup",
1405
2515
  "preorderTraverse",
1406
- "resolveVBIBuilderAdapters"
2516
+ "resolveVBIChartBuilderAdapters"
1407
2517
  ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
1408
2518
  Object.defineProperty(exports, '__esModule', {
1409
2519
  value: true