@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.
- package/dist/builder/adapters/vquery-vseed/build-vquery.d.ts +2 -2
- package/dist/builder/adapters/vquery-vseed/build-vseed.d.ts +2 -2
- package/dist/builder/adapters/vquery-vseed/index.d.ts +3 -3
- package/dist/builder/builder.d.ts +6 -6
- package/dist/builder/features/chart-type/chart-type-builder.d.ts +20 -1
- package/dist/builder/features/chart-type/dimension-encoding.d.ts +4 -0
- package/dist/builder/features/chart-type/measure-encoding.d.ts +4 -0
- package/dist/builder/features/chart-type/reapply-dimension-encodings.d.ts +2 -0
- package/dist/builder/features/chart-type/reapply-measure-encodings.d.ts +2 -0
- package/dist/builder/features/dimensions/dim-builder.d.ts +3 -2
- package/dist/builder/features/dimensions/dim-node-builder.d.ts +32 -1
- package/dist/builder/features/havingFilter/having-builder.d.ts +2 -2
- package/dist/builder/features/measures/mea-builder.d.ts +3 -2
- package/dist/builder/features/measures/mea-node-builder.d.ts +33 -3
- package/dist/builder/features/whereFilter/where-builder.d.ts +2 -2
- package/dist/builder/features/whereFilter/where-node-builder.d.ts +11 -2
- package/dist/builder/index.d.ts +1 -1
- package/dist/builder/modules/build.d.ts +2 -2
- package/dist/builder/modules/index.d.ts +2 -2
- package/dist/builder/modules/is-empty.d.ts +1 -1
- package/dist/index.cjs +1497 -387
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1489 -379
- package/dist/pipeline/vqueryDSL/aggregateMap.d.ts +23 -3
- package/dist/pipeline/vqueryDSL/buildOrderBy.d.ts +2 -0
- package/dist/pipeline/vqueryDSL/index.d.ts +2 -2
- package/dist/pipeline/vqueryDSL/resolveDatePredicate.d.ts +7 -0
- package/dist/pipeline/vqueryDSL/types.d.ts +6 -5
- package/dist/types/builder/VBIInterface.d.ts +5 -4
- package/dist/types/builder/adapter.d.ts +15 -13
- package/dist/types/builder/build-vseed.d.ts +3 -0
- package/dist/types/builder/context.d.ts +2 -2
- package/dist/types/builder/index.d.ts +4 -3
- package/dist/types/builder/observe.d.ts +2 -1
- package/dist/types/connector/query.d.ts +1 -0
- package/dist/types/dsl/dimensions/aggregate.d.ts +15 -0
- package/dist/types/dsl/dimensions/dimensions.d.ts +62 -0
- package/dist/types/dsl/encoding.d.ts +2 -2
- package/dist/types/dsl/havingFilter/having.d.ts +3 -3
- package/dist/types/dsl/index.d.ts +5 -3
- package/dist/types/dsl/measures/measures.d.ts +151 -4
- package/dist/types/dsl/sort.d.ts +13 -0
- package/dist/types/dsl/vbi/vbi.d.ts +90 -5
- package/dist/types/dsl/whereFilter/date.d.ts +95 -0
- package/dist/types/dsl/whereFilter/filters.d.ts +142 -5
- package/dist/utils/filter-guards.d.ts +2 -2
- package/dist/vbi/create-vbi.d.ts +6 -7
- package/dist/vbi/from/from-vbi-dsl-input.d.ts +3 -3
- package/dist/vbi/from/set-base-dsl-fields.d.ts +2 -2
- package/dist/vbi/generate-empty-dsl.d.ts +2 -2
- package/dist/vbi/normalize/types.d.ts +3 -3
- 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
|
-
|
|
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
|
|
521
|
+
encoding,
|
|
378
522
|
aggregate: {
|
|
379
523
|
func: 'sum'
|
|
380
524
|
}
|
|
381
525
|
};
|
|
382
526
|
const yMap = new external_yjs_namespaceObject.Map();
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
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
|
-
|
|
394
|
-
|
|
395
|
-
|
|
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
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
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.
|
|
575
|
+
measures.observeDeep(callback);
|
|
426
576
|
return ()=>{
|
|
427
|
-
measures.
|
|
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
|
-
|
|
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
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
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
|
-
|
|
496
|
-
|
|
497
|
-
|
|
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
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
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.
|
|
1127
|
+
dimensions.observeDeep(callback);
|
|
528
1128
|
return ()=>{
|
|
529
|
-
dimensions.
|
|
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(
|
|
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.
|
|
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.
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 = ()=>
|
|
1198
|
-
isEmpty = ()=>
|
|
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
|
-
|
|
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
|
-
|
|
1214
|
-
|
|
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
|
-
|
|
1242
|
-
|
|
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
|
|
2386
|
+
const ensureWhereGroup = (whereFilter)=>{
|
|
2387
|
+
const source = whereFilter ?? {
|
|
1260
2388
|
id: 'root',
|
|
1261
2389
|
op: 'and',
|
|
1262
2390
|
conditions: []
|
|
1263
|
-
}
|
|
1264
|
-
const
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
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
|
|
2398
|
+
const ensureHavingGroup = (havingFilter)=>{
|
|
2399
|
+
const source = havingFilter ?? {
|
|
1280
2400
|
id: 'root',
|
|
1281
2401
|
op: 'and',
|
|
1282
2402
|
conditions: []
|
|
1283
|
-
}
|
|
1284
|
-
const
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
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
|
|
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
|
|
2428
|
+
return new VBIChartBuilder(doc, options);
|
|
1318
2429
|
};
|
|
1319
|
-
const
|
|
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
|
|
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
|
-
|
|
1357
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
"
|
|
2504
|
+
"VBIChartBuilder",
|
|
1395
2505
|
"WhereFilterBuilder",
|
|
1396
2506
|
"buildVQuery",
|
|
1397
2507
|
"createVBI",
|
|
1398
|
-
"
|
|
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
|
-
"
|
|
2516
|
+
"resolveVBIChartBuilderAdapters"
|
|
1407
2517
|
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
1408
2518
|
Object.defineProperty(exports, '__esModule', {
|
|
1409
2519
|
value: true
|