@dhis2/analytics 26.0.15 → 26.0.16
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/build/cjs/modules/pivotTable/PivotTableEngine.js +8 -21
- package/build/cjs/modules/pivotTable/__tests__/addToTotalIfNumber.js +71 -0
- package/build/cjs/modules/pivotTable/addToTotalIfNumber.js +8 -0
- package/build/es/modules/pivotTable/PivotTableEngine.js +8 -21
- package/build/es/modules/pivotTable/__tests__/addToTotalIfNumber.js +69 -0
- package/build/es/modules/pivotTable/addToTotalIfNumber.js +1 -0
- package/package.json +1 -1
|
@@ -10,6 +10,7 @@ var _predefinedDimensions = require("../predefinedDimensions.js");
|
|
|
10
10
|
var _renderValue = require("../renderValue.js");
|
|
11
11
|
var _valueTypes = require("../valueTypes.js");
|
|
12
12
|
var _AdaptiveClippingController = require("./AdaptiveClippingController.js");
|
|
13
|
+
var _addToTotalIfNumber = require("./addToTotalIfNumber.js");
|
|
13
14
|
var _parseValue = require("./parseValue.js");
|
|
14
15
|
var _pivotTableConstants = require("./pivotTableConstants.js");
|
|
15
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -525,9 +526,7 @@ class PivotTableEngine {
|
|
|
525
526
|
dataFields.forEach(field => {
|
|
526
527
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
527
528
|
const value = (0, _parseValue.parseValue)(dataRow[headerIndex]);
|
|
528
|
-
|
|
529
|
-
totalCell[field] = (totalCell[field] || 0) + value;
|
|
530
|
-
}
|
|
529
|
+
totalCell[field] = (0, _addToTotalIfNumber.addToTotalIfNumber)(value, totalCell[field]);
|
|
531
530
|
});
|
|
532
531
|
}
|
|
533
532
|
totalCell.count += 1;
|
|
@@ -543,9 +542,7 @@ class PivotTableEngine {
|
|
|
543
542
|
dataFields.forEach(field => {
|
|
544
543
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
545
544
|
const value = (0, _parseValue.parseValue)(dataRow[headerIndex]);
|
|
546
|
-
|
|
547
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
548
|
-
}
|
|
545
|
+
percentageTotal[field] = (0, _addToTotalIfNumber.addToTotalIfNumber)(value, percentageTotal[field]);
|
|
549
546
|
});
|
|
550
547
|
if (totals.columnSubtotal) {
|
|
551
548
|
if (!this.percentageTotals[totals.columnSubtotal.row]) {
|
|
@@ -558,9 +555,7 @@ class PivotTableEngine {
|
|
|
558
555
|
dataFields.forEach(field => {
|
|
559
556
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
560
557
|
const value = (0, _parseValue.parseValue)(dataRow[headerIndex]);
|
|
561
|
-
|
|
562
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
563
|
-
}
|
|
558
|
+
percentageTotal[field] = (0, _addToTotalIfNumber.addToTotalIfNumber)(value, percentageTotal[field]);
|
|
564
559
|
});
|
|
565
560
|
}
|
|
566
561
|
if (totals.columnTotal) {
|
|
@@ -574,9 +569,7 @@ class PivotTableEngine {
|
|
|
574
569
|
dataFields.forEach(field => {
|
|
575
570
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
576
571
|
const value = (0, _parseValue.parseValue)(dataRow[headerIndex]);
|
|
577
|
-
|
|
578
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
579
|
-
}
|
|
572
|
+
percentageTotal[field] = (0, _addToTotalIfNumber.addToTotalIfNumber)(value, percentageTotal[field]);
|
|
580
573
|
});
|
|
581
574
|
}
|
|
582
575
|
}
|
|
@@ -591,9 +584,7 @@ class PivotTableEngine {
|
|
|
591
584
|
dataFields.forEach(field => {
|
|
592
585
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
593
586
|
const value = (0, _parseValue.parseValue)(dataRow[headerIndex]);
|
|
594
|
-
|
|
595
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
596
|
-
}
|
|
587
|
+
percentageTotal[field] = (0, _addToTotalIfNumber.addToTotalIfNumber)(value, percentageTotal[field]);
|
|
597
588
|
});
|
|
598
589
|
if (totals.rowSubtotal) {
|
|
599
590
|
if (!this.percentageTotals[totals.rowSubtotal.column]) {
|
|
@@ -606,9 +597,7 @@ class PivotTableEngine {
|
|
|
606
597
|
dataFields.forEach(field => {
|
|
607
598
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
608
599
|
const value = (0, _parseValue.parseValue)(dataRow[headerIndex]);
|
|
609
|
-
|
|
610
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
611
|
-
}
|
|
600
|
+
percentageTotal[field] = (0, _addToTotalIfNumber.addToTotalIfNumber)(value, percentageTotal[field]);
|
|
612
601
|
});
|
|
613
602
|
}
|
|
614
603
|
if (totals.rowTotal) {
|
|
@@ -622,9 +611,7 @@ class PivotTableEngine {
|
|
|
622
611
|
dataFields.forEach(field => {
|
|
623
612
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
624
613
|
const value = (0, _parseValue.parseValue)(dataRow[headerIndex]);
|
|
625
|
-
|
|
626
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
627
|
-
}
|
|
614
|
+
percentageTotal[field] = (0, _addToTotalIfNumber.addToTotalIfNumber)(value, percentageTotal[field]);
|
|
628
615
|
});
|
|
629
616
|
}
|
|
630
617
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _addToTotalIfNumber = require("../addToTotalIfNumber.js");
|
|
4
|
+
const tests = [{
|
|
5
|
+
testName: 'negative value',
|
|
6
|
+
value: -1,
|
|
7
|
+
total: undefined,
|
|
8
|
+
expected: -1
|
|
9
|
+
}, {
|
|
10
|
+
testName: 'zero value',
|
|
11
|
+
value: 0,
|
|
12
|
+
total: undefined,
|
|
13
|
+
expected: 0
|
|
14
|
+
}, {
|
|
15
|
+
testName: 'positive value',
|
|
16
|
+
value: 1,
|
|
17
|
+
total: undefined,
|
|
18
|
+
expected: 1
|
|
19
|
+
}, {
|
|
20
|
+
testName: 'null value',
|
|
21
|
+
value: null,
|
|
22
|
+
total: undefined,
|
|
23
|
+
expected: undefined
|
|
24
|
+
}, {
|
|
25
|
+
testName: 'undefined value',
|
|
26
|
+
value: undefined,
|
|
27
|
+
total: undefined,
|
|
28
|
+
expected: undefined
|
|
29
|
+
}, {
|
|
30
|
+
testName: 'string value',
|
|
31
|
+
value: 'string',
|
|
32
|
+
total: undefined,
|
|
33
|
+
expected: undefined
|
|
34
|
+
}, {
|
|
35
|
+
testName: 'negative value with existing total',
|
|
36
|
+
value: -1,
|
|
37
|
+
total: 100,
|
|
38
|
+
expected: 99
|
|
39
|
+
}, {
|
|
40
|
+
testName: 'zero value with existing total',
|
|
41
|
+
value: 0,
|
|
42
|
+
total: 100,
|
|
43
|
+
expected: 100
|
|
44
|
+
}, {
|
|
45
|
+
testName: 'positive value with existing total',
|
|
46
|
+
value: 1,
|
|
47
|
+
total: 100,
|
|
48
|
+
expected: 101
|
|
49
|
+
}, {
|
|
50
|
+
testName: 'null value with existing total',
|
|
51
|
+
value: null,
|
|
52
|
+
total: 100,
|
|
53
|
+
expected: 100
|
|
54
|
+
}, {
|
|
55
|
+
testName: 'undefined value with existing total',
|
|
56
|
+
value: undefined,
|
|
57
|
+
total: 100,
|
|
58
|
+
expected: 100
|
|
59
|
+
}, {
|
|
60
|
+
testName: 'string value with existing total',
|
|
61
|
+
value: 'string',
|
|
62
|
+
total: 100,
|
|
63
|
+
expected: 100
|
|
64
|
+
}];
|
|
65
|
+
describe('addToTotalIfNumber', () => {
|
|
66
|
+
tests.forEach(t => {
|
|
67
|
+
it(t.testName, () => {
|
|
68
|
+
expect((0, _addToTotalIfNumber.addToTotalIfNumber)(t.value, t.total)).toEqual(t.expected);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.addToTotalIfNumber = void 0;
|
|
7
|
+
const addToTotalIfNumber = (value, total) => typeof value === 'number' && Number.isFinite(value) ? (total !== null && total !== void 0 ? total : 0) + value : total;
|
|
8
|
+
exports.addToTotalIfNumber = addToTotalIfNumber;
|
|
@@ -7,6 +7,7 @@ import { DIMENSION_ID_ORGUNIT } from '../predefinedDimensions.js';
|
|
|
7
7
|
import { renderValue } from '../renderValue.js';
|
|
8
8
|
import { VALUE_TYPE_NUMBER, VALUE_TYPE_TEXT } from '../valueTypes.js';
|
|
9
9
|
import { AdaptiveClippingController } from './AdaptiveClippingController.js';
|
|
10
|
+
import { addToTotalIfNumber } from './addToTotalIfNumber.js';
|
|
10
11
|
import { parseValue } from './parseValue.js';
|
|
11
12
|
import { AGGREGATE_TYPE_NA, AGGREGATE_TYPE_AVERAGE, AGGREGATE_TYPE_SUM, CELL_TYPE_VALUE, CELL_TYPE_TOTAL, CELL_TYPE_SUBTOTAL, SORT_ORDER_ASCENDING, SORT_ORDER_DESCENDING, DISPLAY_DENSITY_PADDING_COMPACT, DISPLAY_DENSITY_PADDING_COMFORTABLE, DISPLAY_DENSITY_OPTION_COMFORTABLE, DISPLAY_DENSITY_OPTION_COMPACT, DISPLAY_DENSITY_OPTION_NORMAL, DISPLAY_DENSITY_PADDING_NORMAL, FONT_SIZE_OPTION_SMALL, FONT_SIZE_SMALL, FONT_SIZE_OPTION_LARGE, FONT_SIZE_LARGE, FONT_SIZE_OPTION_NORMAL, FONT_SIZE_NORMAL, NUMBER_TYPE_COLUMN_PERCENTAGE, NUMBER_TYPE_ROW_PERCENTAGE, NUMBER_TYPE_VALUE } from './pivotTableConstants.js';
|
|
12
13
|
const dataFields = ['value', 'numerator', 'denominator', 'factor', 'multiplier', 'divisor'];
|
|
@@ -518,9 +519,7 @@ export class PivotTableEngine {
|
|
|
518
519
|
dataFields.forEach(field => {
|
|
519
520
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
520
521
|
const value = parseValue(dataRow[headerIndex]);
|
|
521
|
-
|
|
522
|
-
totalCell[field] = (totalCell[field] || 0) + value;
|
|
523
|
-
}
|
|
522
|
+
totalCell[field] = addToTotalIfNumber(value, totalCell[field]);
|
|
524
523
|
});
|
|
525
524
|
}
|
|
526
525
|
totalCell.count += 1;
|
|
@@ -536,9 +535,7 @@ export class PivotTableEngine {
|
|
|
536
535
|
dataFields.forEach(field => {
|
|
537
536
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
538
537
|
const value = parseValue(dataRow[headerIndex]);
|
|
539
|
-
|
|
540
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
541
|
-
}
|
|
538
|
+
percentageTotal[field] = addToTotalIfNumber(value, percentageTotal[field]);
|
|
542
539
|
});
|
|
543
540
|
if (totals.columnSubtotal) {
|
|
544
541
|
if (!this.percentageTotals[totals.columnSubtotal.row]) {
|
|
@@ -551,9 +548,7 @@ export class PivotTableEngine {
|
|
|
551
548
|
dataFields.forEach(field => {
|
|
552
549
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
553
550
|
const value = parseValue(dataRow[headerIndex]);
|
|
554
|
-
|
|
555
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
556
|
-
}
|
|
551
|
+
percentageTotal[field] = addToTotalIfNumber(value, percentageTotal[field]);
|
|
557
552
|
});
|
|
558
553
|
}
|
|
559
554
|
if (totals.columnTotal) {
|
|
@@ -567,9 +562,7 @@ export class PivotTableEngine {
|
|
|
567
562
|
dataFields.forEach(field => {
|
|
568
563
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
569
564
|
const value = parseValue(dataRow[headerIndex]);
|
|
570
|
-
|
|
571
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
572
|
-
}
|
|
565
|
+
percentageTotal[field] = addToTotalIfNumber(value, percentageTotal[field]);
|
|
573
566
|
});
|
|
574
567
|
}
|
|
575
568
|
}
|
|
@@ -584,9 +577,7 @@ export class PivotTableEngine {
|
|
|
584
577
|
dataFields.forEach(field => {
|
|
585
578
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
586
579
|
const value = parseValue(dataRow[headerIndex]);
|
|
587
|
-
|
|
588
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
589
|
-
}
|
|
580
|
+
percentageTotal[field] = addToTotalIfNumber(value, percentageTotal[field]);
|
|
590
581
|
});
|
|
591
582
|
if (totals.rowSubtotal) {
|
|
592
583
|
if (!this.percentageTotals[totals.rowSubtotal.column]) {
|
|
@@ -599,9 +590,7 @@ export class PivotTableEngine {
|
|
|
599
590
|
dataFields.forEach(field => {
|
|
600
591
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
601
592
|
const value = parseValue(dataRow[headerIndex]);
|
|
602
|
-
|
|
603
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
604
|
-
}
|
|
593
|
+
percentageTotal[field] = addToTotalIfNumber(value, percentageTotal[field]);
|
|
605
594
|
});
|
|
606
595
|
}
|
|
607
596
|
if (totals.rowTotal) {
|
|
@@ -615,9 +604,7 @@ export class PivotTableEngine {
|
|
|
615
604
|
dataFields.forEach(field => {
|
|
616
605
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
617
606
|
const value = parseValue(dataRow[headerIndex]);
|
|
618
|
-
|
|
619
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
620
|
-
}
|
|
607
|
+
percentageTotal[field] = addToTotalIfNumber(value, percentageTotal[field]);
|
|
621
608
|
});
|
|
622
609
|
}
|
|
623
610
|
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { addToTotalIfNumber } from '../addToTotalIfNumber.js';
|
|
2
|
+
const tests = [{
|
|
3
|
+
testName: 'negative value',
|
|
4
|
+
value: -1,
|
|
5
|
+
total: undefined,
|
|
6
|
+
expected: -1
|
|
7
|
+
}, {
|
|
8
|
+
testName: 'zero value',
|
|
9
|
+
value: 0,
|
|
10
|
+
total: undefined,
|
|
11
|
+
expected: 0
|
|
12
|
+
}, {
|
|
13
|
+
testName: 'positive value',
|
|
14
|
+
value: 1,
|
|
15
|
+
total: undefined,
|
|
16
|
+
expected: 1
|
|
17
|
+
}, {
|
|
18
|
+
testName: 'null value',
|
|
19
|
+
value: null,
|
|
20
|
+
total: undefined,
|
|
21
|
+
expected: undefined
|
|
22
|
+
}, {
|
|
23
|
+
testName: 'undefined value',
|
|
24
|
+
value: undefined,
|
|
25
|
+
total: undefined,
|
|
26
|
+
expected: undefined
|
|
27
|
+
}, {
|
|
28
|
+
testName: 'string value',
|
|
29
|
+
value: 'string',
|
|
30
|
+
total: undefined,
|
|
31
|
+
expected: undefined
|
|
32
|
+
}, {
|
|
33
|
+
testName: 'negative value with existing total',
|
|
34
|
+
value: -1,
|
|
35
|
+
total: 100,
|
|
36
|
+
expected: 99
|
|
37
|
+
}, {
|
|
38
|
+
testName: 'zero value with existing total',
|
|
39
|
+
value: 0,
|
|
40
|
+
total: 100,
|
|
41
|
+
expected: 100
|
|
42
|
+
}, {
|
|
43
|
+
testName: 'positive value with existing total',
|
|
44
|
+
value: 1,
|
|
45
|
+
total: 100,
|
|
46
|
+
expected: 101
|
|
47
|
+
}, {
|
|
48
|
+
testName: 'null value with existing total',
|
|
49
|
+
value: null,
|
|
50
|
+
total: 100,
|
|
51
|
+
expected: 100
|
|
52
|
+
}, {
|
|
53
|
+
testName: 'undefined value with existing total',
|
|
54
|
+
value: undefined,
|
|
55
|
+
total: 100,
|
|
56
|
+
expected: 100
|
|
57
|
+
}, {
|
|
58
|
+
testName: 'string value with existing total',
|
|
59
|
+
value: 'string',
|
|
60
|
+
total: 100,
|
|
61
|
+
expected: 100
|
|
62
|
+
}];
|
|
63
|
+
describe('addToTotalIfNumber', () => {
|
|
64
|
+
tests.forEach(t => {
|
|
65
|
+
it(t.testName, () => {
|
|
66
|
+
expect(addToTotalIfNumber(t.value, t.total)).toEqual(t.expected);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const addToTotalIfNumber = (value, total) => typeof value === 'number' && Number.isFinite(value) ? (total !== null && total !== void 0 ? total : 0) + value : total;
|