dbgate-datalib 6.4.3-alpha.1 → 6.5.0
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/lib/FreeTableGridDisplay.d.ts +2 -0
- package/lib/GridDisplay.d.ts +3 -1
- package/lib/GridDisplay.js +4 -2
- package/lib/TableGridDisplay.d.ts +4 -1
- package/lib/TableGridDisplay.js +4 -3
- package/lib/ViewGridDisplay.d.ts +2 -0
- package/lib/chartDefinitions.d.ts +80 -0
- package/lib/chartDefinitions.js +18 -0
- package/lib/chartProcessor.d.ts +23 -0
- package/lib/chartProcessor.js +296 -0
- package/lib/chartScoring.d.ts +3 -0
- package/lib/chartScoring.js +28 -0
- package/lib/chartTools.d.ts +19 -0
- package/lib/chartTools.js +471 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/tests/chartProcessor.test.d.ts +1 -0
- package/lib/tests/chartProcessor.test.js +357 -0
- package/package.json +7 -5
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.computeChartBucketCardinality = exports.fillChartTimelineBuckets = exports.aggregateChartNumericValuesFromChild = exports.aggregateChartNumericValuesFromSource = exports.autoAggregateCompactTimelineChart = exports.compareChartDatesParsed = exports.computeDateBucketDistance = exports.computeChartBucketKey = exports.incrementChartDate = exports.stringifyChartDate = exports.tryParseChartDate = exports.getChartDebugPrint = void 0;
|
|
7
|
+
const toPairs_1 = __importDefault(require("lodash/toPairs"));
|
|
8
|
+
const sumBy_1 = __importDefault(require("lodash/sumBy"));
|
|
9
|
+
const chartDefinitions_1 = require("./chartDefinitions");
|
|
10
|
+
const date_fns_1 = require("date-fns");
|
|
11
|
+
function getChartDebugPrint(chart) {
|
|
12
|
+
let res = '';
|
|
13
|
+
res += `Chart: ${chart.definition.chartType} (${chart.definition.xdef.transformFunction})\n`;
|
|
14
|
+
for (const key of chart.bucketKeysOrdered) {
|
|
15
|
+
res += `${key}: ${(0, toPairs_1.default)(chart.buckets[key])
|
|
16
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
17
|
+
.join(', ')}\n`;
|
|
18
|
+
}
|
|
19
|
+
return res;
|
|
20
|
+
}
|
|
21
|
+
exports.getChartDebugPrint = getChartDebugPrint;
|
|
22
|
+
function tryParseChartDate(dateInput) {
|
|
23
|
+
if (dateInput instanceof Date) {
|
|
24
|
+
return {
|
|
25
|
+
year: dateInput.getFullYear(),
|
|
26
|
+
month: dateInput.getMonth() + 1,
|
|
27
|
+
day: dateInput.getDate(),
|
|
28
|
+
hour: dateInput.getHours(),
|
|
29
|
+
minute: dateInput.getMinutes(),
|
|
30
|
+
second: dateInput.getSeconds(),
|
|
31
|
+
fraction: undefined, // Date object does not have fraction
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
if (typeof dateInput !== 'string')
|
|
35
|
+
return null;
|
|
36
|
+
const m = dateInput.match(/^(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(Z|[+-]\d{2}:\d{2})?)?$/);
|
|
37
|
+
if (!m)
|
|
38
|
+
return null;
|
|
39
|
+
const [_notUsed, year, month, day, hour, minute, second, fraction] = m;
|
|
40
|
+
return {
|
|
41
|
+
year: parseInt(year, 10),
|
|
42
|
+
month: parseInt(month, 10),
|
|
43
|
+
day: parseInt(day, 10),
|
|
44
|
+
hour: parseInt(hour, 10) || 0,
|
|
45
|
+
minute: parseInt(minute, 10) || 0,
|
|
46
|
+
second: parseInt(second, 10) || 0,
|
|
47
|
+
fraction: fraction || undefined,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
exports.tryParseChartDate = tryParseChartDate;
|
|
51
|
+
function pad2Digits(number) {
|
|
52
|
+
return ('00' + number).slice(-2);
|
|
53
|
+
}
|
|
54
|
+
function stringifyChartDate(value, transform) {
|
|
55
|
+
switch (transform) {
|
|
56
|
+
case 'date:year':
|
|
57
|
+
return `${value.year}`;
|
|
58
|
+
case 'date:month':
|
|
59
|
+
return `${value.year}-${pad2Digits(value.month)}`;
|
|
60
|
+
case 'date:day':
|
|
61
|
+
return `${value.year}-${pad2Digits(value.month)}-${pad2Digits(value.day)}`;
|
|
62
|
+
case 'date:hour':
|
|
63
|
+
return `${value.year}-${pad2Digits(value.month)}-${pad2Digits(value.day)} ${pad2Digits(value.hour)}`;
|
|
64
|
+
case 'date:minute':
|
|
65
|
+
return `${value.year}-${pad2Digits(value.month)}-${pad2Digits(value.day)} ${pad2Digits(value.hour)}:${pad2Digits(value.minute)}`;
|
|
66
|
+
default:
|
|
67
|
+
return '';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.stringifyChartDate = stringifyChartDate;
|
|
71
|
+
function incrementChartDate(value, transform) {
|
|
72
|
+
var _a, _b, _c, _d;
|
|
73
|
+
const dateRepresentation = new Date(value.year, ((_a = value.month) !== null && _a !== void 0 ? _a : 1) - 1, (_b = value.day) !== null && _b !== void 0 ? _b : 1, (_c = value.hour) !== null && _c !== void 0 ? _c : 0, (_d = value.minute) !== null && _d !== void 0 ? _d : 0);
|
|
74
|
+
let newDateRepresentation;
|
|
75
|
+
switch (transform) {
|
|
76
|
+
case 'date:year':
|
|
77
|
+
newDateRepresentation = (0, date_fns_1.addYears)(dateRepresentation, 1);
|
|
78
|
+
break;
|
|
79
|
+
case 'date:month':
|
|
80
|
+
newDateRepresentation = (0, date_fns_1.addMonths)(dateRepresentation, 1);
|
|
81
|
+
break;
|
|
82
|
+
case 'date:day':
|
|
83
|
+
newDateRepresentation = (0, date_fns_1.addDays)(dateRepresentation, 1);
|
|
84
|
+
break;
|
|
85
|
+
case 'date:hour':
|
|
86
|
+
newDateRepresentation = (0, date_fns_1.addHours)(dateRepresentation, 1);
|
|
87
|
+
break;
|
|
88
|
+
case 'date:minute':
|
|
89
|
+
newDateRepresentation = (0, date_fns_1.addMinutes)(dateRepresentation, 1);
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
switch (transform) {
|
|
93
|
+
case 'date:year':
|
|
94
|
+
return { year: newDateRepresentation.getFullYear() };
|
|
95
|
+
case 'date:month':
|
|
96
|
+
return {
|
|
97
|
+
year: newDateRepresentation.getFullYear(),
|
|
98
|
+
month: newDateRepresentation.getMonth() + 1,
|
|
99
|
+
};
|
|
100
|
+
case 'date:day':
|
|
101
|
+
return {
|
|
102
|
+
year: newDateRepresentation.getFullYear(),
|
|
103
|
+
month: newDateRepresentation.getMonth() + 1,
|
|
104
|
+
day: newDateRepresentation.getDate(),
|
|
105
|
+
};
|
|
106
|
+
case 'date:hour':
|
|
107
|
+
return {
|
|
108
|
+
year: newDateRepresentation.getFullYear(),
|
|
109
|
+
month: newDateRepresentation.getMonth() + 1,
|
|
110
|
+
day: newDateRepresentation.getDate(),
|
|
111
|
+
hour: newDateRepresentation.getHours(),
|
|
112
|
+
};
|
|
113
|
+
case 'date:minute':
|
|
114
|
+
return {
|
|
115
|
+
year: newDateRepresentation.getFullYear(),
|
|
116
|
+
month: newDateRepresentation.getMonth() + 1,
|
|
117
|
+
day: newDateRepresentation.getDate(),
|
|
118
|
+
hour: newDateRepresentation.getHours(),
|
|
119
|
+
minute: newDateRepresentation.getMinutes(),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.incrementChartDate = incrementChartDate;
|
|
124
|
+
function computeChartBucketKey(dateParsed, chart, row) {
|
|
125
|
+
switch (chart.definition.xdef.transformFunction) {
|
|
126
|
+
case 'date:year':
|
|
127
|
+
return [dateParsed ? `${dateParsed.year}` : null, { year: dateParsed.year }];
|
|
128
|
+
case 'date:month':
|
|
129
|
+
return [
|
|
130
|
+
dateParsed ? `${dateParsed.year}-${pad2Digits(dateParsed.month)}` : null,
|
|
131
|
+
{
|
|
132
|
+
year: dateParsed.year,
|
|
133
|
+
month: dateParsed.month,
|
|
134
|
+
},
|
|
135
|
+
];
|
|
136
|
+
case 'date:day':
|
|
137
|
+
return [
|
|
138
|
+
dateParsed ? `${dateParsed.year}-${pad2Digits(dateParsed.month)}-${pad2Digits(dateParsed.day)}` : null,
|
|
139
|
+
{
|
|
140
|
+
year: dateParsed.year,
|
|
141
|
+
month: dateParsed.month,
|
|
142
|
+
day: dateParsed.day,
|
|
143
|
+
},
|
|
144
|
+
];
|
|
145
|
+
case 'date:hour':
|
|
146
|
+
return [
|
|
147
|
+
dateParsed
|
|
148
|
+
? `${dateParsed.year}-${pad2Digits(dateParsed.month)}-${pad2Digits(dateParsed.day)} ${pad2Digits(dateParsed.hour)}`
|
|
149
|
+
: null,
|
|
150
|
+
{
|
|
151
|
+
year: dateParsed.year,
|
|
152
|
+
month: dateParsed.month,
|
|
153
|
+
day: dateParsed.day,
|
|
154
|
+
hour: dateParsed.hour,
|
|
155
|
+
},
|
|
156
|
+
];
|
|
157
|
+
case 'date:minute':
|
|
158
|
+
return [
|
|
159
|
+
dateParsed
|
|
160
|
+
? `${dateParsed.year}-${pad2Digits(dateParsed.month)}-${pad2Digits(dateParsed.day)} ${pad2Digits(dateParsed.hour)}:${pad2Digits(dateParsed.minute)}`
|
|
161
|
+
: null,
|
|
162
|
+
{
|
|
163
|
+
year: dateParsed.year,
|
|
164
|
+
month: dateParsed.month,
|
|
165
|
+
day: dateParsed.day,
|
|
166
|
+
hour: dateParsed.hour,
|
|
167
|
+
minute: dateParsed.minute,
|
|
168
|
+
},
|
|
169
|
+
];
|
|
170
|
+
case 'identity':
|
|
171
|
+
default:
|
|
172
|
+
return [row[chart.definition.xdef.field], null];
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
exports.computeChartBucketKey = computeChartBucketKey;
|
|
176
|
+
function computeDateBucketDistance(begin, end, transform) {
|
|
177
|
+
switch (transform) {
|
|
178
|
+
case 'date:year':
|
|
179
|
+
return end.year - begin.year;
|
|
180
|
+
case 'date:month':
|
|
181
|
+
return (end.year - begin.year) * 12 + (end.month - begin.month);
|
|
182
|
+
case 'date:day':
|
|
183
|
+
return ((end.year - begin.year) * 365 +
|
|
184
|
+
(end.month - begin.month) * 30 + // rough approximation
|
|
185
|
+
(end.day - begin.day));
|
|
186
|
+
case 'date:hour':
|
|
187
|
+
return ((end.year - begin.year) * 365 * 24 +
|
|
188
|
+
(end.month - begin.month) * 30 * 24 + // rough approximation
|
|
189
|
+
(end.day - begin.day) * 24 +
|
|
190
|
+
(end.hour - begin.hour));
|
|
191
|
+
case 'date:minute':
|
|
192
|
+
return ((end.year - begin.year) * 365 * 24 * 60 +
|
|
193
|
+
(end.month - begin.month) * 30 * 24 * 60 + // rough approximation
|
|
194
|
+
(end.day - begin.day) * 24 * 60 +
|
|
195
|
+
(end.hour - begin.hour) * 60 +
|
|
196
|
+
(end.minute - begin.minute));
|
|
197
|
+
case 'identity':
|
|
198
|
+
default:
|
|
199
|
+
return NaN;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
exports.computeDateBucketDistance = computeDateBucketDistance;
|
|
203
|
+
function compareChartDatesParsed(a, b, transform) {
|
|
204
|
+
switch (transform) {
|
|
205
|
+
case 'date:year':
|
|
206
|
+
return a.year - b.year;
|
|
207
|
+
case 'date:month':
|
|
208
|
+
return a.year === b.year ? a.month - b.month : a.year - b.year;
|
|
209
|
+
case 'date:day':
|
|
210
|
+
return a.year === b.year && a.month === b.month
|
|
211
|
+
? a.day - b.day
|
|
212
|
+
: a.year === b.year
|
|
213
|
+
? a.month - b.month
|
|
214
|
+
: a.year - b.year;
|
|
215
|
+
case 'date:hour':
|
|
216
|
+
return a.year === b.year && a.month === b.month && a.day === b.day
|
|
217
|
+
? a.hour - b.hour
|
|
218
|
+
: a.year === b.year && a.month === b.month
|
|
219
|
+
? a.day - b.day
|
|
220
|
+
: a.year === b.year
|
|
221
|
+
? a.month - b.month
|
|
222
|
+
: a.year - b.year;
|
|
223
|
+
case 'date:minute':
|
|
224
|
+
return a.year === b.year && a.month === b.month && a.day === b.day && a.hour === b.hour
|
|
225
|
+
? a.minute - b.minute
|
|
226
|
+
: a.year === b.year && a.month === b.month && a.day === b.day
|
|
227
|
+
? a.hour - b.hour
|
|
228
|
+
: a.year === b.year && a.month === b.month
|
|
229
|
+
? a.day - b.day
|
|
230
|
+
: a.year === b.year
|
|
231
|
+
? a.month - b.month
|
|
232
|
+
: a.year - b.year;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
exports.compareChartDatesParsed = compareChartDatesParsed;
|
|
236
|
+
function getParentDateBucketKey(bucketKey, transform) {
|
|
237
|
+
switch (transform) {
|
|
238
|
+
case 'date:year':
|
|
239
|
+
return null; // no parent for year
|
|
240
|
+
case 'date:month':
|
|
241
|
+
return bucketKey.slice(0, 4);
|
|
242
|
+
case 'date:day':
|
|
243
|
+
return bucketKey.slice(0, 7);
|
|
244
|
+
case 'date:hour':
|
|
245
|
+
return bucketKey.slice(0, 10);
|
|
246
|
+
case 'date:minute':
|
|
247
|
+
return bucketKey.slice(0, 13);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function getParentDateBucketTransform(transform) {
|
|
251
|
+
switch (transform) {
|
|
252
|
+
case 'date:year':
|
|
253
|
+
return null; // no parent for year
|
|
254
|
+
case 'date:month':
|
|
255
|
+
return 'date:year';
|
|
256
|
+
case 'date:day':
|
|
257
|
+
return 'date:month';
|
|
258
|
+
case 'date:hour':
|
|
259
|
+
return 'date:day';
|
|
260
|
+
case 'date:minute':
|
|
261
|
+
return 'date:hour';
|
|
262
|
+
default:
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
function getParentKeyParsed(date, transform) {
|
|
267
|
+
switch (transform) {
|
|
268
|
+
case 'date:year':
|
|
269
|
+
return null; // no parent for year
|
|
270
|
+
case 'date:month':
|
|
271
|
+
return { year: date.year };
|
|
272
|
+
case 'date:day':
|
|
273
|
+
return { year: date.year, month: date.month };
|
|
274
|
+
case 'date:hour':
|
|
275
|
+
return { year: date.year, month: date.month, day: date.day };
|
|
276
|
+
case 'date:minute':
|
|
277
|
+
return { year: date.year, month: date.month, day: date.day, hour: date.hour };
|
|
278
|
+
default:
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
function createParentChartAggregation(chart) {
|
|
283
|
+
if (chart.isGivenDefinition) {
|
|
284
|
+
// if the chart is created with a given definition, we cannot create a parent aggregation
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
const parentTransform = getParentDateBucketTransform(chart.definition.xdef.transformFunction);
|
|
288
|
+
if (!parentTransform) {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
const res = {
|
|
292
|
+
definition: Object.assign(Object.assign({}, chart.definition), { xdef: Object.assign(Object.assign({}, chart.definition.xdef), { transformFunction: parentTransform }) }),
|
|
293
|
+
rowsAdded: chart.rowsAdded,
|
|
294
|
+
bucketKeysOrdered: [],
|
|
295
|
+
buckets: {},
|
|
296
|
+
bucketKeyDateParsed: {},
|
|
297
|
+
isGivenDefinition: false,
|
|
298
|
+
invalidXRows: chart.invalidXRows,
|
|
299
|
+
invalidYRows: Object.assign({}, chart.invalidYRows),
|
|
300
|
+
validYRows: Object.assign({}, chart.validYRows),
|
|
301
|
+
topDistinctValues: Object.assign({}, chart.topDistinctValues),
|
|
302
|
+
availableColumns: chart.availableColumns,
|
|
303
|
+
};
|
|
304
|
+
for (const [bucketKey, bucketValues] of Object.entries(chart.buckets)) {
|
|
305
|
+
const parentKey = getParentDateBucketKey(bucketKey, chart.definition.xdef.transformFunction);
|
|
306
|
+
if (!parentKey) {
|
|
307
|
+
// skip if the bucket is already a parent
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
res.bucketKeyDateParsed[parentKey] = getParentKeyParsed(chart.bucketKeyDateParsed[bucketKey], chart.definition.xdef.transformFunction);
|
|
311
|
+
aggregateChartNumericValuesFromChild(res, parentKey, bucketValues);
|
|
312
|
+
}
|
|
313
|
+
const bucketKeys = Object.keys(res.buckets).sort();
|
|
314
|
+
res.minX = bucketKeys.length > 0 ? bucketKeys[0] : null;
|
|
315
|
+
res.maxX = bucketKeys.length > 0 ? bucketKeys[bucketKeys.length - 1] : null;
|
|
316
|
+
return res;
|
|
317
|
+
}
|
|
318
|
+
function autoAggregateCompactTimelineChart(chart) {
|
|
319
|
+
var _a;
|
|
320
|
+
while (true) {
|
|
321
|
+
const fromParsed = chart.bucketKeyDateParsed[chart.minX];
|
|
322
|
+
const toParsed = chart.bucketKeyDateParsed[chart.maxX];
|
|
323
|
+
if (!fromParsed || !toParsed) {
|
|
324
|
+
return chart; // cannot fill timeline buckets without valid date range
|
|
325
|
+
}
|
|
326
|
+
const transform = chart.definition.xdef.transformFunction;
|
|
327
|
+
if (!transform.startsWith('date:')) {
|
|
328
|
+
return chart; // cannot aggregate non-date charts
|
|
329
|
+
}
|
|
330
|
+
const dateDistance = computeDateBucketDistance(fromParsed, toParsed, transform);
|
|
331
|
+
if (dateDistance < ((_a = chart.definition.xdef.parentAggregateLimit) !== null && _a !== void 0 ? _a : chartDefinitions_1.ChartConstDefaults.parentAggregateLimit)) {
|
|
332
|
+
return chart; // no need to aggregate further, the distance is less than the limit
|
|
333
|
+
}
|
|
334
|
+
const parentChart = createParentChartAggregation(chart);
|
|
335
|
+
if (!parentChart) {
|
|
336
|
+
return chart; // cannot create parent aggregation
|
|
337
|
+
}
|
|
338
|
+
chart = parentChart;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
exports.autoAggregateCompactTimelineChart = autoAggregateCompactTimelineChart;
|
|
342
|
+
function aggregateChartNumericValuesFromSource(chart, bucketKey, numericColumns, row) {
|
|
343
|
+
for (const ydef of chart.definition.ydefs) {
|
|
344
|
+
if (numericColumns[ydef.field] == null) {
|
|
345
|
+
if (row[ydef.field]) {
|
|
346
|
+
chart.invalidYRows[ydef.field] = (chart.invalidYRows[ydef.field] || 0) + 1; // increment invalid row count if the field is not numeric
|
|
347
|
+
}
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
chart.validYRows[ydef.field] = (chart.validYRows[ydef.field] || 0) + 1; // increment valid row count
|
|
351
|
+
let distinctValues = chart.topDistinctValues[ydef.field];
|
|
352
|
+
if (!distinctValues) {
|
|
353
|
+
distinctValues = new Set();
|
|
354
|
+
chart.topDistinctValues[ydef.field] = distinctValues;
|
|
355
|
+
}
|
|
356
|
+
if (distinctValues.size < chartDefinitions_1.ChartLimits.MAX_DISTINCT_VALUES) {
|
|
357
|
+
chart.topDistinctValues[ydef.field].add(numericColumns[ydef.field]);
|
|
358
|
+
}
|
|
359
|
+
switch (ydef.aggregateFunction) {
|
|
360
|
+
case 'sum':
|
|
361
|
+
chart.buckets[bucketKey][ydef.field] =
|
|
362
|
+
(chart.buckets[bucketKey][ydef.field] || 0) + (numericColumns[ydef.field] || 0);
|
|
363
|
+
break;
|
|
364
|
+
case 'first':
|
|
365
|
+
if (chart.buckets[bucketKey][ydef.field] === undefined) {
|
|
366
|
+
chart.buckets[bucketKey][ydef.field] = numericColumns[ydef.field];
|
|
367
|
+
}
|
|
368
|
+
break;
|
|
369
|
+
case 'last':
|
|
370
|
+
chart.buckets[bucketKey][ydef.field] = numericColumns[ydef.field];
|
|
371
|
+
break;
|
|
372
|
+
case 'min':
|
|
373
|
+
if (chart.buckets[bucketKey][ydef.field] === undefined) {
|
|
374
|
+
chart.buckets[bucketKey][ydef.field] = numericColumns[ydef.field];
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
chart.buckets[bucketKey][ydef.field] = Math.min(chart.buckets[bucketKey][ydef.field], numericColumns[ydef.field]);
|
|
378
|
+
}
|
|
379
|
+
break;
|
|
380
|
+
case 'max':
|
|
381
|
+
if (chart.buckets[bucketKey][ydef.field] === undefined) {
|
|
382
|
+
chart.buckets[bucketKey][ydef.field] = numericColumns[ydef.field];
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
chart.buckets[bucketKey][ydef.field] = Math.max(chart.buckets[bucketKey][ydef.field], numericColumns[ydef.field]);
|
|
386
|
+
}
|
|
387
|
+
break;
|
|
388
|
+
case 'count':
|
|
389
|
+
chart.buckets[bucketKey][ydef.field] = (chart.buckets[bucketKey][ydef.field] || 0) + 1;
|
|
390
|
+
break;
|
|
391
|
+
case 'avg':
|
|
392
|
+
if (chart.buckets[bucketKey][ydef.field] === undefined) {
|
|
393
|
+
chart.buckets[bucketKey][ydef.field] = [numericColumns[ydef.field], 1]; // [sum, count]
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
chart.buckets[bucketKey][ydef.field][0] += numericColumns[ydef.field];
|
|
397
|
+
chart.buckets[bucketKey][ydef.field][1] += 1;
|
|
398
|
+
}
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
exports.aggregateChartNumericValuesFromSource = aggregateChartNumericValuesFromSource;
|
|
404
|
+
function aggregateChartNumericValuesFromChild(chart, bucketKey, childBucketValues) {
|
|
405
|
+
for (const ydef of chart.definition.ydefs) {
|
|
406
|
+
if (childBucketValues[ydef.field] == undefined) {
|
|
407
|
+
continue; // skip if the field is not present in the child bucket
|
|
408
|
+
}
|
|
409
|
+
if (!chart.buckets[bucketKey]) {
|
|
410
|
+
chart.buckets[bucketKey] = {};
|
|
411
|
+
}
|
|
412
|
+
switch (ydef.aggregateFunction) {
|
|
413
|
+
case 'sum':
|
|
414
|
+
case 'count':
|
|
415
|
+
chart.buckets[bucketKey][ydef.field] =
|
|
416
|
+
(chart.buckets[bucketKey][ydef.field] || 0) + (childBucketValues[ydef.field] || 0);
|
|
417
|
+
break;
|
|
418
|
+
case 'min':
|
|
419
|
+
if (chart.buckets[bucketKey][ydef.field] === undefined) {
|
|
420
|
+
chart.buckets[bucketKey][ydef.field] = childBucketValues[ydef.field];
|
|
421
|
+
}
|
|
422
|
+
else {
|
|
423
|
+
chart.buckets[bucketKey][ydef.field] = Math.min(chart.buckets[bucketKey][ydef.field], childBucketValues[ydef.field]);
|
|
424
|
+
}
|
|
425
|
+
break;
|
|
426
|
+
case 'max':
|
|
427
|
+
if (chart.buckets[bucketKey][ydef.field] === undefined) {
|
|
428
|
+
chart.buckets[bucketKey][ydef.field] = childBucketValues[ydef.field];
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
chart.buckets[bucketKey][ydef.field] = Math.max(chart.buckets[bucketKey][ydef.field], childBucketValues[ydef.field]);
|
|
432
|
+
}
|
|
433
|
+
break;
|
|
434
|
+
case 'avg':
|
|
435
|
+
if (chart.buckets[bucketKey][ydef.field] === undefined) {
|
|
436
|
+
chart.buckets[bucketKey][ydef.field] = childBucketValues[ydef.field];
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
chart.buckets[bucketKey][ydef.field][0] += childBucketValues[ydef.field][0];
|
|
440
|
+
chart.buckets[bucketKey][ydef.field][1] += childBucketValues[ydef.field][1];
|
|
441
|
+
}
|
|
442
|
+
break;
|
|
443
|
+
case 'first':
|
|
444
|
+
case 'last':
|
|
445
|
+
throw new Error(`Cannot aggregate ${ydef.aggregateFunction} for ${ydef.field} in child bucket`);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
exports.aggregateChartNumericValuesFromChild = aggregateChartNumericValuesFromChild;
|
|
450
|
+
function fillChartTimelineBuckets(chart) {
|
|
451
|
+
const fromParsed = chart.bucketKeyDateParsed[chart.minX];
|
|
452
|
+
const toParsed = chart.bucketKeyDateParsed[chart.maxX];
|
|
453
|
+
if (!fromParsed || !toParsed) {
|
|
454
|
+
return; // cannot fill timeline buckets without valid date range
|
|
455
|
+
}
|
|
456
|
+
const transform = chart.definition.xdef.transformFunction;
|
|
457
|
+
let currentParsed = fromParsed;
|
|
458
|
+
while (compareChartDatesParsed(currentParsed, toParsed, transform) <= 0) {
|
|
459
|
+
const bucketKey = stringifyChartDate(currentParsed, transform);
|
|
460
|
+
if (!chart.buckets[bucketKey]) {
|
|
461
|
+
chart.buckets[bucketKey] = {};
|
|
462
|
+
chart.bucketKeyDateParsed[bucketKey] = currentParsed;
|
|
463
|
+
}
|
|
464
|
+
currentParsed = incrementChartDate(currentParsed, transform);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
exports.fillChartTimelineBuckets = fillChartTimelineBuckets;
|
|
468
|
+
function computeChartBucketCardinality(bucket) {
|
|
469
|
+
return (0, sumBy_1.default)(Object.keys(bucket), field => bucket[field]);
|
|
470
|
+
}
|
|
471
|
+
exports.computeChartBucketCardinality = computeChartBucketCardinality;
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -39,3 +39,5 @@ __exportStar(require("./FreeTableGridDisplay"), exports);
|
|
|
39
39
|
__exportStar(require("./FreeTableModel"), exports);
|
|
40
40
|
__exportStar(require("./CustomGridDisplay"), exports);
|
|
41
41
|
__exportStar(require("./ScriptDrivedDeployer"), exports);
|
|
42
|
+
__exportStar(require("./chartDefinitions"), exports);
|
|
43
|
+
__exportStar(require("./chartProcessor"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|