@provoly/dashboard 0.15.9 → 0.15.11
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/esm2022/filters/date/date-filter.component.mjs +3 -3
- package/esm2022/lib/core/components/modal-status/modal-status.component.mjs +2 -2
- package/esm2022/lib/core/model/dataset.interface.mjs +1 -1
- package/esm2022/lib/core/model/filter.interface.mjs +1 -1
- package/esm2022/lib/core/model/widget-map-manifest.interface.mjs +1 -1
- package/esm2022/lib/core/public-api.mjs +2 -2
- package/esm2022/lib/core/store/aggregation/frontend-aggregation/aggregation-utils.class.mjs +184 -0
- package/esm2022/lib/core/store/aggregation/frontend-aggregation/frontend-aggregation.service.mjs +93 -0
- package/esm2022/lib/dashboard/store/dashboard.selectors.mjs +2 -2
- package/esm2022/widgets/widget-map/component/widget-map.component.mjs +8 -6
- package/fesm2022/provoly-dashboard-filters-date.mjs +2 -2
- package/fesm2022/provoly-dashboard-filters-date.mjs.map +1 -1
- package/fesm2022/provoly-dashboard-widgets-widget-map.mjs +7 -5
- package/fesm2022/provoly-dashboard-widgets-widget-map.mjs.map +1 -1
- package/fesm2022/provoly-dashboard.mjs +230 -164
- package/fesm2022/provoly-dashboard.mjs.map +1 -1
- package/lib/core/model/dataset.interface.d.ts +1 -1
- package/lib/core/model/filter.interface.d.ts +1 -1
- package/lib/core/model/widget-map-manifest.interface.d.ts +1 -0
- package/lib/core/public-api.d.ts +1 -1
- package/lib/core/store/aggregation/frontend-aggregation/aggregation-utils.class.d.ts +33 -0
- package/lib/core/store/aggregation/frontend-aggregation/frontend-aggregation.service.d.ts +22 -0
- package/lib/dashboard/store/dashboard.selectors.d.ts +1 -1
- package/package.json +31 -31
- package/widgets/widget-map/component/widget-map.component.d.ts +2 -1
- package/esm2022/lib/core/store/aggregation/frontend-aggregation.service.mjs +0 -210
- package/lib/core/store/aggregation/frontend-aggregation.service.d.ts +0 -33
|
@@ -2573,7 +2573,7 @@ class PryModalStatusComponent {
|
|
|
2573
2573
|
.flat()
|
|
2574
2574
|
.map((preview) => ({
|
|
2575
2575
|
...preview,
|
|
2576
|
-
name: preview.name.split(',').join(', ')
|
|
2576
|
+
name: (preview.name ?? '').split(',').join(', ')
|
|
2577
2577
|
}))));
|
|
2578
2578
|
this.messageCount$ = this.store.select(DataSourceSelectors.datasetPreviews).pipe(map((previews) => {
|
|
2579
2579
|
return previews.map((preview) => preview.count).reduce((p, c) => p + c, 0);
|
|
@@ -3856,7 +3856,7 @@ const namedQueriesUses = createSelector(globalManifest, (manifest) => manifest.w
|
|
|
3856
3856
|
const presentation = createSelector(feature$4, (state) => state?.presentation);
|
|
3857
3857
|
const isCurrentPresentationModified = createSelector(presentation, globalManifest, (state, global) => !equal(global, state.initial));
|
|
3858
3858
|
const isCurrentPresentationOwner = createSelector(presentation, (state) => !!state.current && state.current.owner);
|
|
3859
|
-
const filters = createSelector(feature$4, (state) => state?.manifests.manifest.filters ??
|
|
3859
|
+
const filters = createSelector(feature$4, (state) => state?.manifests.manifest.filters ?? []);
|
|
3860
3860
|
const datasourceFilters = createSelector(feature$4, (state) => state?.manifests.manifest.filters
|
|
3861
3861
|
? state?.manifests.manifest.filters.reduce((obj, filter) => (filter.attributes.forEach((attribute) => (obj[attribute.datasource] || (obj[attribute.datasource] = [])).push({
|
|
3862
3862
|
attribute: attribute.id,
|
|
@@ -5285,195 +5285,261 @@ class ResultsetUtils {
|
|
|
5285
5285
|
}
|
|
5286
5286
|
}
|
|
5287
5287
|
|
|
5288
|
-
class
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5288
|
+
class AggregationUtils {
|
|
5289
|
+
static getAxisAttribute(classes, options, axis) {
|
|
5290
|
+
return classes
|
|
5291
|
+
.map((clazz) => clazz.attributes.find((attr) => attr.id === options[axis].attribute))
|
|
5292
|
+
.find((attr) => !!attr)?.name;
|
|
5292
5293
|
}
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
if (!abscissa || !ordinate) {
|
|
5306
|
-
throw new Error('abscissaorodinateinvalid');
|
|
5307
|
-
}
|
|
5308
|
-
let data = datasource.map((rsName) => resultSets[rsName ?? '']).filter((rsName) => !!rsName);
|
|
5309
|
-
const resultSet = data.reduce((rs1, rs2) => ResultsetUtils.mergeResultSets(rs1, rs2), {
|
|
5310
|
-
items: {},
|
|
5311
|
-
relations: [],
|
|
5312
|
-
merged: data.length
|
|
5313
|
-
});
|
|
5314
|
-
let items = Object.keys(resultSet.items)
|
|
5315
|
-
.map((classId) => resultSet.items[classId])
|
|
5316
|
-
.reduce((prev, curr) => [...prev, ...curr], []);
|
|
5317
|
-
if (!!options.groupBy) {
|
|
5318
|
-
const groupBy = classes
|
|
5319
|
-
.map((clazz) => clazz.attributes.find((attr) => attr.id === options.groupBy?.attribute))
|
|
5320
|
-
.find((attr) => !!attr)?.name;
|
|
5321
|
-
if (!groupBy) {
|
|
5322
|
-
throw new Error('groupByAttributeisinvalid');
|
|
5323
|
-
}
|
|
5324
|
-
const itemsGrouped = this.groupBy(items, groupBy);
|
|
5325
|
-
const values = [];
|
|
5326
|
-
Object.keys(itemsGrouped).forEach((key) => {
|
|
5327
|
-
values.push({
|
|
5328
|
-
key,
|
|
5329
|
-
groupBy: this.getValueFromOperation(itemsGrouped[key], options.ordinate.operation, abscissa, ordinate, options.abscissa.limit)
|
|
5330
|
-
});
|
|
5331
|
-
});
|
|
5332
|
-
return { operation: options.ordinate.operation, values: values };
|
|
5333
|
-
}
|
|
5334
|
-
const values = this.getValueFromOperation(items, options.ordinate.operation, abscissa, ordinate, options.abscissa.limit);
|
|
5335
|
-
return { operation: options.ordinate.operation, values: values };
|
|
5336
|
-
}));
|
|
5294
|
+
static getChartDatasourceResultSet(datasources, resultSets) {
|
|
5295
|
+
return datasources
|
|
5296
|
+
.filter((rsName) => rsName in resultSets)
|
|
5297
|
+
.map((rsName) => resultSets[rsName])
|
|
5298
|
+
.reduce((rs1, rs2) => ResultsetUtils.mergeResultSets(rs1, rs2), {
|
|
5299
|
+
items: {},
|
|
5300
|
+
relations: [],
|
|
5301
|
+
merged: datasources.filter((rsName) => rsName in resultSets).length
|
|
5302
|
+
});
|
|
5303
|
+
}
|
|
5304
|
+
static getAggregatedValue(operation, groupedItems, abscissaAttribute, ordinateAttribute) {
|
|
5305
|
+
return this.getAggregatedValueForOperation(operation, groupedItems[abscissaAttribute].map((item) => this.getValueFromAttribute(item, ordinateAttribute).value));
|
|
5337
5306
|
}
|
|
5338
|
-
|
|
5339
|
-
let
|
|
5340
|
-
|
|
5341
|
-
|
|
5307
|
+
static getValueFromAttribute(item, attribute) {
|
|
5308
|
+
let value = ItemUtils.getAttributeValue(item, attribute);
|
|
5309
|
+
return Array.isArray(value) ? value[0] : value;
|
|
5310
|
+
}
|
|
5311
|
+
static getAggregatedValueForOperation(operation, values) {
|
|
5342
5312
|
switch (operation) {
|
|
5343
5313
|
case Operation.COUNT:
|
|
5344
|
-
|
|
5345
|
-
key: key,
|
|
5346
|
-
value: groupByAbscissa[key].length
|
|
5347
|
-
})));
|
|
5348
|
-
break;
|
|
5314
|
+
return values.length;
|
|
5349
5315
|
case Operation.SUM:
|
|
5350
|
-
|
|
5351
|
-
key: key,
|
|
5352
|
-
value: this.getSum(groupByAbscissa[key], ordinate)
|
|
5353
|
-
})));
|
|
5354
|
-
break;
|
|
5316
|
+
return values.reduce((acc, val) => acc + val, 0);
|
|
5355
5317
|
case Operation.DISTINCT:
|
|
5356
|
-
|
|
5357
|
-
key: key,
|
|
5358
|
-
value: this.getDistinct(groupByAbscissa[key], ordinate)
|
|
5359
|
-
})));
|
|
5360
|
-
break;
|
|
5318
|
+
return [...new Set(values)].length;
|
|
5361
5319
|
case Operation.AVERAGE:
|
|
5362
|
-
|
|
5363
|
-
key: key,
|
|
5364
|
-
value: this.getAverage(groupByAbscissa[key], ordinate)
|
|
5365
|
-
})));
|
|
5366
|
-
break;
|
|
5320
|
+
return values.reduce((acc, val) => acc + val, 0) / values.length;
|
|
5367
5321
|
case Operation.MEDIAN:
|
|
5368
|
-
|
|
5369
|
-
key: key,
|
|
5370
|
-
value: this.getQuartile(groupByAbscissa[key], ordinate, 0.5)
|
|
5371
|
-
})));
|
|
5372
|
-
break;
|
|
5322
|
+
return this.getQuartile(values, 0.5);
|
|
5373
5323
|
case Operation.Q1:
|
|
5374
|
-
|
|
5375
|
-
key: key,
|
|
5376
|
-
value: this.getQuartile(groupByAbscissa[key], ordinate, 0.25)
|
|
5377
|
-
})));
|
|
5378
|
-
break;
|
|
5324
|
+
return this.getQuartile(values, 0.25);
|
|
5379
5325
|
case Operation.Q3:
|
|
5380
|
-
|
|
5381
|
-
key: key,
|
|
5382
|
-
value: this.getQuartile(groupByAbscissa[key], ordinate, 0.75)
|
|
5383
|
-
})));
|
|
5384
|
-
break;
|
|
5326
|
+
return this.getQuartile(values, 0.75);
|
|
5385
5327
|
case Operation.MIN:
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
})));
|
|
5390
|
-
break;
|
|
5328
|
+
return Math.min(...values);
|
|
5329
|
+
case Operation.MAX:
|
|
5330
|
+
return Math.max(...values);
|
|
5391
5331
|
default:
|
|
5392
|
-
|
|
5393
|
-
key: key,
|
|
5394
|
-
value: this.getMax(groupByAbscissa[key], ordinate)
|
|
5395
|
-
})));
|
|
5396
|
-
break;
|
|
5332
|
+
return -1;
|
|
5397
5333
|
}
|
|
5398
|
-
|
|
5399
|
-
|
|
5334
|
+
}
|
|
5335
|
+
static getQuartile(values, q) {
|
|
5336
|
+
if (values.length === 0)
|
|
5337
|
+
return 0;
|
|
5338
|
+
values.sort((a, b) => a - b);
|
|
5339
|
+
let pos = (values.length - 1) * q;
|
|
5340
|
+
if (pos % 1 === 0) {
|
|
5341
|
+
return values[pos];
|
|
5400
5342
|
}
|
|
5401
|
-
|
|
5343
|
+
pos = Math.floor(pos);
|
|
5344
|
+
return values[pos + 1] !== undefined ? (values[pos] + values[pos + 1]) / 2 : values[pos];
|
|
5402
5345
|
}
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5346
|
+
static formatByLimit(data, limit, operation) {
|
|
5347
|
+
if (!limit.isTimeLimit) {
|
|
5348
|
+
data
|
|
5349
|
+
.sort((a, b) => (limit.order === 'asc' ? (a.value > b.value ? 1 : -1) : a.value < b.value ? 1 : -1))
|
|
5350
|
+
.splice(limit.at);
|
|
5351
|
+
return data;
|
|
5352
|
+
}
|
|
5353
|
+
return this.formatDataByTimeLimit(data, limit, operation);
|
|
5354
|
+
}
|
|
5355
|
+
static formatDataByTimeLimit(data, limit, operation) {
|
|
5356
|
+
let distinctValues = [];
|
|
5357
|
+
data
|
|
5358
|
+
.map((obj) => ({ ...obj, key: this.getKeyValueForTimeInterval(obj.key, limit.interval) }))
|
|
5359
|
+
.forEach((obj) => {
|
|
5360
|
+
const isNotDistinct = distinctValues.find((distinct) => obj.key === distinct.key);
|
|
5361
|
+
if (!!isNotDistinct) {
|
|
5362
|
+
isNotDistinct.values.push(obj.value);
|
|
5409
5363
|
}
|
|
5410
5364
|
else {
|
|
5411
|
-
|
|
5365
|
+
distinctValues.push({ key: obj.key, values: [] });
|
|
5412
5366
|
}
|
|
5413
5367
|
});
|
|
5414
|
-
return
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
return Array.isArray(value) ? value[0] : value;
|
|
5419
|
-
}
|
|
5420
|
-
getSum(items, attribute) {
|
|
5421
|
-
let sum = 0;
|
|
5422
|
-
items.forEach((item) => {
|
|
5423
|
-
sum += this.getValueFromAttribute(item, attribute).value;
|
|
5424
|
-
});
|
|
5425
|
-
return sum;
|
|
5368
|
+
return distinctValues.map((obj) => ({
|
|
5369
|
+
...obj,
|
|
5370
|
+
value: AggregationUtils.getAggregatedValueForOperation(operation, obj.values)
|
|
5371
|
+
}));
|
|
5426
5372
|
}
|
|
5427
|
-
|
|
5428
|
-
const
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5373
|
+
static getKeyValueForTimeInterval(key, interval) {
|
|
5374
|
+
const date = new Date(key);
|
|
5375
|
+
switch (interval) {
|
|
5376
|
+
case 'second':
|
|
5377
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()).toISOString();
|
|
5378
|
+
case 'minute':
|
|
5379
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes()).toISOString();
|
|
5380
|
+
case 'hour':
|
|
5381
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours()).toISOString();
|
|
5382
|
+
case 'day':
|
|
5383
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate()).toISOString();
|
|
5384
|
+
case 'week':
|
|
5385
|
+
const daysToSubtract = (7 + date.getUTCDay()) % 7;
|
|
5386
|
+
date.setUTCDate(date.getUTCDate() - daysToSubtract);
|
|
5387
|
+
return date.toISOString();
|
|
5388
|
+
case 'quarter':
|
|
5389
|
+
const quarterStartMonths = [0, 3, 6, 9]; // January, April, July, October
|
|
5390
|
+
const quarter = Math.floor(date.getUTCMonth() / 3);
|
|
5391
|
+
const year = date.getUTCFullYear();
|
|
5392
|
+
const startOfQuarter = new Date(Date.UTC(year, quarterStartMonths[quarter], 1, 0, 0, 0, 0));
|
|
5393
|
+
return startOfQuarter.toISOString();
|
|
5394
|
+
case 'year':
|
|
5395
|
+
return new Date(new Date(key).getFullYear(), 0, 1).toISOString();
|
|
5396
|
+
default:
|
|
5397
|
+
return date.toISOString();
|
|
5398
|
+
}
|
|
5434
5399
|
}
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5400
|
+
static filterItems(items, filters) {
|
|
5401
|
+
let filtersByAttribute = filters
|
|
5402
|
+
.map((filter) => filter.attributes.map((attribute) => ({
|
|
5403
|
+
...filter,
|
|
5404
|
+
attribute: attribute.id,
|
|
5405
|
+
attributes: undefined
|
|
5406
|
+
})))
|
|
5407
|
+
.flat();
|
|
5408
|
+
return filters.length > 0
|
|
5409
|
+
? [
|
|
5410
|
+
...new Set(filtersByAttribute
|
|
5411
|
+
.map((filter) => items.filter((item) => this.doesItemValuePassFilter(item, filter.attribute, filter.operator, filter.value)))
|
|
5412
|
+
.flat())
|
|
5413
|
+
]
|
|
5414
|
+
: items;
|
|
5415
|
+
}
|
|
5416
|
+
static doesItemValuePassFilter(item, attribute, operator, filterValue) {
|
|
5417
|
+
let value = AggregationUtils.getValueFromAttribute(item, attribute)?.value;
|
|
5418
|
+
let date1, date2;
|
|
5419
|
+
console.log(operator);
|
|
5420
|
+
switch (operator) {
|
|
5421
|
+
case 'EQUALS':
|
|
5422
|
+
return value === filterValue;
|
|
5423
|
+
case 'NOT_EQUALS':
|
|
5424
|
+
return value !== filterValue;
|
|
5425
|
+
case 'CONTAINS':
|
|
5426
|
+
return value.includes(filterValue);
|
|
5427
|
+
case 'START_WITH':
|
|
5428
|
+
return value.startsWith(filterValue);
|
|
5429
|
+
case 'END_WITH':
|
|
5430
|
+
return value.endsWith(filterValue);
|
|
5431
|
+
case 'GREATER_THAN':
|
|
5432
|
+
if (typeof filterValue === 'number') {
|
|
5433
|
+
return value > filterValue;
|
|
5434
|
+
}
|
|
5435
|
+
else if (typeof filterValue === 'string') {
|
|
5436
|
+
return new Date(value) > new Date(filterValue);
|
|
5437
|
+
}
|
|
5438
|
+
else {
|
|
5439
|
+
return false;
|
|
5440
|
+
}
|
|
5441
|
+
case 'LOWER_THAN':
|
|
5442
|
+
if (typeof filterValue === 'number') {
|
|
5443
|
+
return value < filterValue;
|
|
5444
|
+
}
|
|
5445
|
+
else if (typeof filterValue === 'string') {
|
|
5446
|
+
return new Date(value) < new Date(filterValue);
|
|
5447
|
+
}
|
|
5448
|
+
else {
|
|
5449
|
+
return false;
|
|
5450
|
+
}
|
|
5451
|
+
case 'INSIDE':
|
|
5452
|
+
[date1, date2] = [
|
|
5453
|
+
new Date(filterValue.split(',')[0]),
|
|
5454
|
+
new Date(filterValue.split(',')[1])
|
|
5455
|
+
];
|
|
5456
|
+
return new Date(value) > new Date(date1) && new Date(value) < new Date(date2);
|
|
5457
|
+
case 'OUTSIDE':
|
|
5458
|
+
[date1, date2] = [
|
|
5459
|
+
new Date(filterValue.split(',')[0]),
|
|
5460
|
+
new Date(filterValue.split(',')[1])
|
|
5461
|
+
];
|
|
5462
|
+
return new Date(value) < new Date(date1) && new Date(value) > new Date(date2);
|
|
5463
|
+
default:
|
|
5464
|
+
return true;
|
|
5465
|
+
}
|
|
5442
5466
|
}
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5467
|
+
}
|
|
5468
|
+
|
|
5469
|
+
class PryFrontendAggregationService extends PryAggregationService {
|
|
5470
|
+
constructor(store) {
|
|
5471
|
+
super();
|
|
5472
|
+
this.store = store;
|
|
5446
5473
|
}
|
|
5447
|
-
|
|
5448
|
-
return [
|
|
5474
|
+
aggregate(datasources, options) {
|
|
5475
|
+
return combineLatest([
|
|
5476
|
+
this.store.select(DashboardSelectors.resultSets),
|
|
5477
|
+
this.store.select(ClassSelectors.classes),
|
|
5478
|
+
this.store.select(DashboardSelectors.filters)
|
|
5479
|
+
]).pipe(map(([resultSets, classes, filters]) => {
|
|
5480
|
+
const resultSet = AggregationUtils.getChartDatasourceResultSet(datasources, resultSets);
|
|
5481
|
+
let items = Object.keys(resultSet.items)
|
|
5482
|
+
.map((classId) => resultSet.items[classId])
|
|
5483
|
+
.reduce((prev, curr) => [...prev, ...curr], []);
|
|
5484
|
+
items = AggregationUtils.filterItems(items, filters);
|
|
5485
|
+
return this.getAggregationResult(options, classes, items);
|
|
5486
|
+
}));
|
|
5449
5487
|
}
|
|
5450
|
-
|
|
5451
|
-
const
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5488
|
+
getAggregationResult(options, classes, items) {
|
|
5489
|
+
const [abscissa, ordinate] = [
|
|
5490
|
+
AggregationUtils.getAxisAttribute(classes, options, 'abscissa') ?? '',
|
|
5491
|
+
AggregationUtils.getAxisAttribute(classes, options, 'ordinate') ?? ''
|
|
5492
|
+
];
|
|
5493
|
+
const aggregationResult = {
|
|
5494
|
+
operation: options.ordinate.operation,
|
|
5495
|
+
values: []
|
|
5496
|
+
};
|
|
5497
|
+
if (!options.groupBy) {
|
|
5498
|
+
if (!!options.ordinate.operation)
|
|
5499
|
+
console.warn('no ordinate operation selected');
|
|
5500
|
+
aggregationResult.values = this.getChartDataBasedOnOperation(items, options.ordinate.operation, abscissa, ordinate, options.abscissa.limit);
|
|
5501
|
+
console.log(aggregationResult.values);
|
|
5456
5502
|
}
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5503
|
+
else {
|
|
5504
|
+
const groupByAttribute = classes
|
|
5505
|
+
.map((clazz) => clazz.attributes.find((attr) => attr.id === options.groupBy?.attribute))
|
|
5506
|
+
.find((attr) => !!attr)?.name ?? '';
|
|
5507
|
+
const itemsGrouped = this.getItemsGroupedByAttributeValue(items, groupByAttribute);
|
|
5508
|
+
aggregationResult.values = Object.keys(itemsGrouped).map((key) => ({
|
|
5509
|
+
key,
|
|
5510
|
+
groupBy: this.getChartDataBasedOnOperation(itemsGrouped[key], options.ordinate.operation, abscissa, ordinate, options.abscissa.limit)
|
|
5511
|
+
}));
|
|
5460
5512
|
}
|
|
5461
|
-
return
|
|
5462
|
-
}
|
|
5463
|
-
getPercentile(items, attribute, q) {
|
|
5464
|
-
const allValues = items.map((item) => this.getValueFromAttribute(item, attribute).value);
|
|
5465
|
-
const allValuesSorted = allValues.sort((a, b) => a - b);
|
|
5466
|
-
return ((100 * allValuesSorted.reduce((acc, v) => acc + (v < q ? 1 : 0) + (v === q ? 0.5 : 0), 0)) /
|
|
5467
|
-
allValuesSorted.length);
|
|
5513
|
+
return aggregationResult;
|
|
5468
5514
|
}
|
|
5469
|
-
|
|
5470
|
-
if (
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5515
|
+
getItemsGroupedByAttributeValue(items, attribute) {
|
|
5516
|
+
if (attribute === '')
|
|
5517
|
+
console.warn('groupBy attribute not found');
|
|
5518
|
+
let distinctValues = {};
|
|
5519
|
+
items.forEach((item) => {
|
|
5520
|
+
let value = AggregationUtils.getValueFromAttribute(item, attribute)?.value;
|
|
5521
|
+
if (!!value)
|
|
5522
|
+
distinctValues[value] = [...(distinctValues[value] ?? []), item];
|
|
5523
|
+
});
|
|
5524
|
+
return distinctValues;
|
|
5525
|
+
}
|
|
5526
|
+
// get { key, value } object list that will be our data to show in the chart
|
|
5527
|
+
getChartDataBasedOnOperation(items, operation, abscissa, ordinate, limit) {
|
|
5528
|
+
if (abscissa === '' || ordinate === '')
|
|
5529
|
+
console.warn('abscissa or ordinate attribute not found');
|
|
5530
|
+
const groupByAbscissa = this.getItemsGroupedByAttributeValue(items, abscissa);
|
|
5531
|
+
let result = [
|
|
5532
|
+
...Object.keys(groupByAbscissa).map((abscissaAttribute) => {
|
|
5533
|
+
console.log(AggregationUtils.getAggregatedValue(operation, groupByAbscissa, abscissaAttribute, ordinate ?? ''));
|
|
5534
|
+
return {
|
|
5535
|
+
key: +abscissaAttribute || abscissaAttribute,
|
|
5536
|
+
value: AggregationUtils.getAggregatedValue(operation, groupByAbscissa, abscissaAttribute, ordinate ?? '')
|
|
5537
|
+
};
|
|
5538
|
+
})
|
|
5539
|
+
];
|
|
5540
|
+
if (limit)
|
|
5541
|
+
result = AggregationUtils.formatByLimit(result, limit, operation);
|
|
5542
|
+
return result;
|
|
5477
5543
|
}
|
|
5478
5544
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: PryFrontendAggregationService, deps: [{ token: i1.Store }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
5479
5545
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: PryFrontendAggregationService, providedIn: 'root' }); }
|