@vue-pivottable/subtotal-renderer 0.1.0 → 0.2.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/README.md +6 -6
- package/dist/core.js +19 -8
- package/dist/core.mjs +19 -8
- package/dist/index.js +185 -41
- package/dist/index.mjs +185 -41
- package/dist/vue2.js +191 -39
- package/dist/vue2.mjs +191 -39
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -16,28 +16,52 @@ function createSubtotalRenderers(PivotData) {
|
|
|
16
16
|
"Subtotal Table": makeSubtotalRenderer({ name: "vue-subtotal-table" })
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
|
-
function generateRowKeysWithSubtotals2(rowKeys, depth) {
|
|
19
|
+
function generateRowKeysWithSubtotals2(rowKeys, depth, collapsedKeys = /* @__PURE__ */ new Set()) {
|
|
20
20
|
if (depth <= 1) {
|
|
21
21
|
return rowKeys.map((key) => ({ key, isSubtotal: false, level: key.length }));
|
|
22
22
|
}
|
|
23
23
|
const result = [];
|
|
24
|
+
const addedSubtotals = /* @__PURE__ */ new Set();
|
|
24
25
|
for (let i = 0; i < rowKeys.length; i++) {
|
|
25
26
|
const rowKey = rowKeys[i];
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
for (let level =
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
rowKeys[i + 1];
|
|
28
|
+
let isHidden = false;
|
|
29
|
+
for (let level = 1; level < rowKey.length; level++) {
|
|
30
|
+
const parentKey = rowKey.slice(0, level);
|
|
31
|
+
const parentKeyStr = JSON.stringify(parentKey);
|
|
32
|
+
if (collapsedKeys.has(parentKeyStr)) {
|
|
33
|
+
isHidden = true;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
for (let level = 1; level < rowKey.length; level++) {
|
|
38
|
+
const subtotalKey = rowKey.slice(0, level);
|
|
39
|
+
const subtotalKeyStr = JSON.stringify(subtotalKey);
|
|
40
|
+
if (!addedSubtotals.has(subtotalKeyStr)) {
|
|
41
|
+
addedSubtotals.add(subtotalKeyStr);
|
|
42
|
+
let subtotalHidden = false;
|
|
43
|
+
for (let parentLevel = 1; parentLevel < level; parentLevel++) {
|
|
44
|
+
const parentKey = subtotalKey.slice(0, parentLevel);
|
|
45
|
+
if (collapsedKeys.has(JSON.stringify(parentKey))) {
|
|
46
|
+
subtotalHidden = true;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (!subtotalHidden) {
|
|
51
|
+
const isCollapsed = collapsedKeys.has(subtotalKeyStr);
|
|
52
|
+
result.push({
|
|
53
|
+
key: subtotalKey,
|
|
54
|
+
isSubtotal: true,
|
|
55
|
+
level,
|
|
56
|
+
subtotalLabel: `${subtotalKey[level - 1]} Subtotal`,
|
|
57
|
+
isCollapsed
|
|
58
|
+
});
|
|
59
|
+
}
|
|
39
60
|
}
|
|
40
61
|
}
|
|
62
|
+
if (!isHidden) {
|
|
63
|
+
result.push({ key: rowKey, isSubtotal: false, level: rowKey.length });
|
|
64
|
+
}
|
|
41
65
|
}
|
|
42
66
|
return result;
|
|
43
67
|
}
|
|
@@ -75,8 +99,60 @@ function spanSize(rowItems, i, j) {
|
|
|
75
99
|
}
|
|
76
100
|
return len;
|
|
77
101
|
}
|
|
78
|
-
function
|
|
79
|
-
if (
|
|
102
|
+
function generateColKeysWithSubtotals2(colKeys, depth, collapsedKeys = /* @__PURE__ */ new Set()) {
|
|
103
|
+
if (depth <= 1) {
|
|
104
|
+
return colKeys.map((key) => ({ key, isSubtotal: false, level: key.length }));
|
|
105
|
+
}
|
|
106
|
+
const result = [];
|
|
107
|
+
const addedSubtotals = /* @__PURE__ */ new Set();
|
|
108
|
+
for (let i = 0; i < colKeys.length; i++) {
|
|
109
|
+
const colKey = colKeys[i];
|
|
110
|
+
let isHidden = false;
|
|
111
|
+
for (let level = 1; level < colKey.length; level++) {
|
|
112
|
+
const parentKey = colKey.slice(0, level);
|
|
113
|
+
const parentKeyStr = JSON.stringify(parentKey);
|
|
114
|
+
if (collapsedKeys.has(parentKeyStr)) {
|
|
115
|
+
isHidden = true;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
for (let level = 1; level < colKey.length; level++) {
|
|
120
|
+
const subtotalKey = colKey.slice(0, level);
|
|
121
|
+
const subtotalKeyStr = JSON.stringify(subtotalKey);
|
|
122
|
+
if (!addedSubtotals.has(subtotalKeyStr)) {
|
|
123
|
+
addedSubtotals.add(subtotalKeyStr);
|
|
124
|
+
let subtotalHidden = false;
|
|
125
|
+
for (let parentLevel = 1; parentLevel < level; parentLevel++) {
|
|
126
|
+
const parentKey = subtotalKey.slice(0, parentLevel);
|
|
127
|
+
if (collapsedKeys.has(JSON.stringify(parentKey))) {
|
|
128
|
+
subtotalHidden = true;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (!subtotalHidden) {
|
|
133
|
+
const isCollapsed = collapsedKeys.has(subtotalKeyStr);
|
|
134
|
+
result.push({
|
|
135
|
+
key: subtotalKey,
|
|
136
|
+
isSubtotal: true,
|
|
137
|
+
level,
|
|
138
|
+
subtotalLabel: `${subtotalKey[level - 1]} Subtotal`,
|
|
139
|
+
isCollapsed
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (!isHidden) {
|
|
145
|
+
result.push({ key: colKey, isSubtotal: false, level: colKey.length });
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
function colSpanSizeWithSubtotals(colItems, i, j) {
|
|
151
|
+
if (colItems[i].isSubtotal) {
|
|
152
|
+
return 1;
|
|
153
|
+
}
|
|
154
|
+
const arr = colItems.map((item) => item.key);
|
|
155
|
+
if (i !== 0 && !colItems[i - 1].isSubtotal) {
|
|
80
156
|
let asPrevious = true;
|
|
81
157
|
for (let x = 0; x <= j; x++) {
|
|
82
158
|
if (arr[i - 1][x] !== arr[i][x]) {
|
|
@@ -90,6 +166,8 @@ function colSpanSize(arr, i, j) {
|
|
|
90
166
|
}
|
|
91
167
|
let len = 0;
|
|
92
168
|
while (i + len < arr.length) {
|
|
169
|
+
if (colItems[i + len].isSubtotal)
|
|
170
|
+
break;
|
|
93
171
|
let same = true;
|
|
94
172
|
for (let x = 0; x <= j; x++) {
|
|
95
173
|
if (arr[i][x] !== arr[i + len][x]) {
|
|
@@ -241,10 +319,11 @@ function makeSubtotalRenderer(opts = {}) {
|
|
|
241
319
|
const colKeys = pivotData.getColKeys();
|
|
242
320
|
const grandTotalAggregator = pivotData.getAggregator([], []);
|
|
243
321
|
const getAggregator = createSubtotalAggregatorGetter(pivotData);
|
|
244
|
-
const rowKeysWithSubtotals = generateRowKeysWithSubtotals2(rowKeys, rowAttrs.length);
|
|
322
|
+
const rowKeysWithSubtotals = generateRowKeysWithSubtotals2(rowKeys, rowAttrs.length, state.collapsedRowKeys);
|
|
323
|
+
const colKeysWithSubtotals = generateColKeysWithSubtotals2(colKeys, colAttrs.length, state.collapsedColKeys);
|
|
245
324
|
const subtotalOpts = this.subtotalOptions;
|
|
246
|
-
subtotalOpts.arrowCollapsed || "▶";
|
|
247
|
-
subtotalOpts.arrowExpanded || "▼";
|
|
325
|
+
const arrowCollapsed = subtotalOpts.arrowCollapsed || "▶";
|
|
326
|
+
const arrowExpanded = subtotalOpts.arrowExpanded || "▼";
|
|
248
327
|
const getClickHandler = (value, rowValues, colValues) => {
|
|
249
328
|
var _a;
|
|
250
329
|
if ((_a = this.tableOptions) == null ? void 0 : _a.clickCallback) {
|
|
@@ -270,23 +349,56 @@ function makeSubtotalRenderer(opts = {}) {
|
|
|
270
349
|
if (j === 0 && rowAttrs.length !== 0) {
|
|
271
350
|
cells.push(h("th", {
|
|
272
351
|
colSpan: rowAttrs.length,
|
|
273
|
-
rowSpan: colAttrs.length
|
|
274
|
-
style: {
|
|
275
|
-
backgroundColor: "#f5f5f5"
|
|
276
|
-
}
|
|
352
|
+
rowSpan: colAttrs.length
|
|
277
353
|
}));
|
|
278
354
|
}
|
|
279
355
|
cells.push(h("th", { class: "pvtAxisLabel" }, c));
|
|
280
|
-
|
|
281
|
-
const
|
|
282
|
-
if (
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
356
|
+
colKeysWithSubtotals.forEach((colItem, i) => {
|
|
357
|
+
const { key: colKey, isSubtotal, level } = colItem;
|
|
358
|
+
if (j < colKey.length) {
|
|
359
|
+
const colSpan = colSpanSizeWithSubtotals(colKeysWithSubtotals, i, j);
|
|
360
|
+
if (colSpan !== -1) {
|
|
361
|
+
const isLastAttrRow = j === colKey.length - 1;
|
|
362
|
+
if (isSubtotal && isLastAttrRow) {
|
|
363
|
+
const keyStr = JSON.stringify(colKey);
|
|
364
|
+
const isCollapsed = state.collapsedColKeys.has(keyStr);
|
|
365
|
+
const arrow = isCollapsed ? arrowCollapsed : arrowExpanded;
|
|
366
|
+
const label = `${colKey[j]} Subtotal`;
|
|
367
|
+
cells.push(h("th", {
|
|
368
|
+
class: "pvtColLabel pvtColSubtotalLabel",
|
|
369
|
+
key: `colKey${i}-${j}`,
|
|
370
|
+
colSpan,
|
|
371
|
+
rowSpan: colAttrs.length - j + (rowAttrs.length !== 0 ? 1 : 0),
|
|
372
|
+
style: {
|
|
373
|
+
fontWeight: "bold",
|
|
374
|
+
backgroundColor: "#f0f0f0"
|
|
375
|
+
}
|
|
376
|
+
}, [
|
|
377
|
+
h("span", {
|
|
378
|
+
class: "pvtColCollapseToggle",
|
|
379
|
+
style: {
|
|
380
|
+
cursor: "pointer",
|
|
381
|
+
marginRight: "4px",
|
|
382
|
+
userSelect: "none"
|
|
383
|
+
},
|
|
384
|
+
onClick: (e) => {
|
|
385
|
+
e.stopPropagation();
|
|
386
|
+
toggleColCollapse(keyStr);
|
|
387
|
+
}
|
|
388
|
+
}, arrow),
|
|
389
|
+
label
|
|
390
|
+
]));
|
|
391
|
+
} else {
|
|
392
|
+
const label = applyLabel(colAttrs[j], colKey[j]);
|
|
393
|
+
const rowSpan = isLastAttrRow && rowAttrs.length !== 0 ? 2 : 1;
|
|
394
|
+
cells.push(h("th", {
|
|
395
|
+
class: "pvtColLabel",
|
|
396
|
+
key: `colKey${i}-${j}`,
|
|
397
|
+
colSpan,
|
|
398
|
+
rowSpan
|
|
399
|
+
}, label));
|
|
400
|
+
}
|
|
401
|
+
}
|
|
290
402
|
}
|
|
291
403
|
});
|
|
292
404
|
if (j === 0 && this.rowTotal) {
|
|
@@ -302,6 +414,9 @@ function makeSubtotalRenderer(opts = {}) {
|
|
|
302
414
|
class: "pvtAxisLabel",
|
|
303
415
|
key: `rowAttr${i}`
|
|
304
416
|
}, r));
|
|
417
|
+
if (colAttrs.length !== 0) {
|
|
418
|
+
cells.push(h("th"));
|
|
419
|
+
}
|
|
305
420
|
if (colAttrs.length === 0 && this.rowTotal) {
|
|
306
421
|
cells.push(h("th", { class: "pvtTotalLabel" }, this.localeStrings.totals));
|
|
307
422
|
}
|
|
@@ -315,6 +430,9 @@ function makeSubtotalRenderer(opts = {}) {
|
|
|
315
430
|
const { key: rowKey, isSubtotal, level, subtotalLabel } = rowItem;
|
|
316
431
|
const cells = [];
|
|
317
432
|
if (isSubtotal) {
|
|
433
|
+
const keyStr = JSON.stringify(rowKey);
|
|
434
|
+
const isCollapsed = state.collapsedRowKeys.has(keyStr);
|
|
435
|
+
const arrow = isCollapsed ? arrowCollapsed : arrowExpanded;
|
|
318
436
|
const subtotalText = subtotalLabel || `${rowKey[rowKey.length - 1]} Subtotal`;
|
|
319
437
|
cells.push(h("th", {
|
|
320
438
|
class: "pvtRowLabel pvtSubtotalLabel",
|
|
@@ -323,18 +441,34 @@ function makeSubtotalRenderer(opts = {}) {
|
|
|
323
441
|
fontWeight: "bold",
|
|
324
442
|
backgroundColor: "#f0f0f0"
|
|
325
443
|
}
|
|
326
|
-
},
|
|
327
|
-
|
|
444
|
+
}, [
|
|
445
|
+
h("span", {
|
|
446
|
+
class: "pvtCollapseToggle",
|
|
447
|
+
style: {
|
|
448
|
+
cursor: "pointer",
|
|
449
|
+
marginRight: "6px",
|
|
450
|
+
userSelect: "none"
|
|
451
|
+
},
|
|
452
|
+
onClick: (e) => {
|
|
453
|
+
e.stopPropagation();
|
|
454
|
+
toggleRowCollapse(keyStr);
|
|
455
|
+
}
|
|
456
|
+
}, arrow),
|
|
457
|
+
subtotalText
|
|
458
|
+
]));
|
|
459
|
+
colKeysWithSubtotals.forEach((colItem, j) => {
|
|
460
|
+
const { key: colKey, isSubtotal: isColSubtotal } = colItem;
|
|
328
461
|
const aggregator = getAggregator(rowKey, colKey);
|
|
329
462
|
const val = aggregator.value();
|
|
330
463
|
const formattedVal = aggregator.format ? aggregator.format(val) : val;
|
|
331
464
|
const clickHandler = getClickHandler(val, rowKey, colKey);
|
|
465
|
+
const isDoubleSubtotal = isColSubtotal;
|
|
332
466
|
cells.push(h("td", {
|
|
333
|
-
class: "pvtVal pvtSubtotalVal",
|
|
467
|
+
class: isColSubtotal ? "pvtVal pvtSubtotalVal pvtColSubtotalVal" : "pvtVal pvtSubtotalVal",
|
|
334
468
|
key: `subtotal-val${i}-${j}`,
|
|
335
469
|
style: {
|
|
336
470
|
fontWeight: "bold",
|
|
337
|
-
backgroundColor: "#f0f0f0"
|
|
471
|
+
backgroundColor: isDoubleSubtotal ? "#e0e0e0" : "#f0f0f0"
|
|
338
472
|
},
|
|
339
473
|
onClick: clickHandler || void 0
|
|
340
474
|
}, formattedVal));
|
|
@@ -370,14 +504,19 @@ function makeSubtotalRenderer(opts = {}) {
|
|
|
370
504
|
}, label));
|
|
371
505
|
}
|
|
372
506
|
});
|
|
373
|
-
|
|
507
|
+
colKeysWithSubtotals.forEach((colItem, j) => {
|
|
508
|
+
const { key: colKey, isSubtotal: isColSubtotal } = colItem;
|
|
374
509
|
const aggregator = getAggregator(rowKey, colKey);
|
|
375
510
|
const val = aggregator.value();
|
|
376
511
|
const formattedVal = aggregator.format ? aggregator.format(val) : val;
|
|
377
512
|
const clickHandler = getClickHandler(val, rowKey, colKey);
|
|
378
513
|
cells.push(h("td", {
|
|
379
|
-
class: "pvtVal",
|
|
514
|
+
class: isColSubtotal ? "pvtVal pvtColSubtotalVal" : "pvtVal",
|
|
380
515
|
key: `val${i}-${j}`,
|
|
516
|
+
style: isColSubtotal ? {
|
|
517
|
+
fontWeight: "bold",
|
|
518
|
+
backgroundColor: "#f0f0f0"
|
|
519
|
+
} : void 0,
|
|
381
520
|
onClick: clickHandler || void 0
|
|
382
521
|
}, formattedVal));
|
|
383
522
|
});
|
|
@@ -400,14 +539,19 @@ function makeSubtotalRenderer(opts = {}) {
|
|
|
400
539
|
class: "pvtTotalLabel",
|
|
401
540
|
colSpan: rowAttrs.length + (colAttrs.length === 0 ? 0 : 1)
|
|
402
541
|
}, this.localeStrings.totals));
|
|
403
|
-
|
|
542
|
+
colKeysWithSubtotals.forEach((colItem, i) => {
|
|
543
|
+
const { key: colKey, isSubtotal: isColSubtotal } = colItem;
|
|
404
544
|
const totalAggregator = getAggregator([], colKey);
|
|
405
545
|
const totalVal = totalAggregator.value();
|
|
406
546
|
const formattedTotal = totalAggregator.format ? totalAggregator.format(totalVal) : totalVal;
|
|
407
547
|
const clickHandler = getClickHandler(totalVal, [], colKey);
|
|
408
548
|
cells.push(h("td", {
|
|
409
|
-
class: "pvtTotal",
|
|
549
|
+
class: isColSubtotal ? "pvtTotal pvtColSubtotalTotal" : "pvtTotal",
|
|
410
550
|
key: `colTotal${i}`,
|
|
551
|
+
style: isColSubtotal ? {
|
|
552
|
+
fontWeight: "bold",
|
|
553
|
+
backgroundColor: "#e0e0e0"
|
|
554
|
+
} : void 0,
|
|
411
555
|
onClick: clickHandler || void 0
|
|
412
556
|
}, formattedTotal));
|
|
413
557
|
});
|
package/dist/vue2.js
CHANGED
|
@@ -16,28 +16,51 @@ function createSubtotalRenderers(PivotData) {
|
|
|
16
16
|
"Subtotal Table": makeSubtotalRenderer({ name: "vue-subtotal-table" })
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
|
-
function generateRowKeysWithSubtotals(rowKeys, depth) {
|
|
19
|
+
function generateRowKeysWithSubtotals(rowKeys, depth, collapsedKeys = /* @__PURE__ */ new Set()) {
|
|
20
20
|
if (depth <= 1) {
|
|
21
21
|
return rowKeys.map((key) => ({ key, isSubtotal: false, level: key.length }));
|
|
22
22
|
}
|
|
23
23
|
const result = [];
|
|
24
|
+
const addedSubtotals = /* @__PURE__ */ new Set();
|
|
24
25
|
for (let i = 0; i < rowKeys.length; i++) {
|
|
25
26
|
const rowKey = rowKeys[i];
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
let isHidden = false;
|
|
28
|
+
for (let level = 1; level < rowKey.length; level++) {
|
|
29
|
+
const parentKey = rowKey.slice(0, level);
|
|
30
|
+
const parentKeyStr = JSON.stringify(parentKey);
|
|
31
|
+
if (collapsedKeys.has(parentKeyStr)) {
|
|
32
|
+
isHidden = true;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
for (let level = 1; level < rowKey.length; level++) {
|
|
37
|
+
const subtotalKey = rowKey.slice(0, level);
|
|
38
|
+
const subtotalKeyStr = JSON.stringify(subtotalKey);
|
|
39
|
+
if (!addedSubtotals.has(subtotalKeyStr)) {
|
|
40
|
+
addedSubtotals.add(subtotalKeyStr);
|
|
41
|
+
let subtotalHidden = false;
|
|
42
|
+
for (let parentLevel = 1; parentLevel < level; parentLevel++) {
|
|
43
|
+
const parentKey = subtotalKey.slice(0, parentLevel);
|
|
44
|
+
if (collapsedKeys.has(JSON.stringify(parentKey))) {
|
|
45
|
+
subtotalHidden = true;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (!subtotalHidden) {
|
|
50
|
+
const isCollapsed = collapsedKeys.has(subtotalKeyStr);
|
|
51
|
+
result.push({
|
|
52
|
+
key: subtotalKey,
|
|
53
|
+
isSubtotal: true,
|
|
54
|
+
level,
|
|
55
|
+
subtotalLabel: `${subtotalKey[level - 1]} Subtotal`,
|
|
56
|
+
isCollapsed
|
|
57
|
+
});
|
|
58
|
+
}
|
|
39
59
|
}
|
|
40
60
|
}
|
|
61
|
+
if (!isHidden) {
|
|
62
|
+
result.push({ key: rowKey, isSubtotal: false, level: rowKey.length });
|
|
63
|
+
}
|
|
41
64
|
}
|
|
42
65
|
return result;
|
|
43
66
|
}
|
|
@@ -75,8 +98,60 @@ function spanSize(rowItems, i, j) {
|
|
|
75
98
|
}
|
|
76
99
|
return len;
|
|
77
100
|
}
|
|
78
|
-
function
|
|
79
|
-
if (
|
|
101
|
+
function generateColKeysWithSubtotals(colKeys, depth, collapsedKeys = /* @__PURE__ */ new Set()) {
|
|
102
|
+
if (depth <= 1) {
|
|
103
|
+
return colKeys.map((key) => ({ key, isSubtotal: false, level: key.length }));
|
|
104
|
+
}
|
|
105
|
+
const result = [];
|
|
106
|
+
const addedSubtotals = /* @__PURE__ */ new Set();
|
|
107
|
+
for (let i = 0; i < colKeys.length; i++) {
|
|
108
|
+
const colKey = colKeys[i];
|
|
109
|
+
let isHidden = false;
|
|
110
|
+
for (let level = 1; level < colKey.length; level++) {
|
|
111
|
+
const parentKey = colKey.slice(0, level);
|
|
112
|
+
const parentKeyStr = JSON.stringify(parentKey);
|
|
113
|
+
if (collapsedKeys.has(parentKeyStr)) {
|
|
114
|
+
isHidden = true;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
for (let level = 1; level < colKey.length; level++) {
|
|
119
|
+
const subtotalKey = colKey.slice(0, level);
|
|
120
|
+
const subtotalKeyStr = JSON.stringify(subtotalKey);
|
|
121
|
+
if (!addedSubtotals.has(subtotalKeyStr)) {
|
|
122
|
+
addedSubtotals.add(subtotalKeyStr);
|
|
123
|
+
let subtotalHidden = false;
|
|
124
|
+
for (let parentLevel = 1; parentLevel < level; parentLevel++) {
|
|
125
|
+
const parentKey = subtotalKey.slice(0, parentLevel);
|
|
126
|
+
if (collapsedKeys.has(JSON.stringify(parentKey))) {
|
|
127
|
+
subtotalHidden = true;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (!subtotalHidden) {
|
|
132
|
+
const isCollapsed = collapsedKeys.has(subtotalKeyStr);
|
|
133
|
+
result.push({
|
|
134
|
+
key: subtotalKey,
|
|
135
|
+
isSubtotal: true,
|
|
136
|
+
level,
|
|
137
|
+
subtotalLabel: `${subtotalKey[level - 1]} Subtotal`,
|
|
138
|
+
isCollapsed
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (!isHidden) {
|
|
144
|
+
result.push({ key: colKey, isSubtotal: false, level: colKey.length });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
function colSpanSizeWithSubtotals(colItems, i, j) {
|
|
150
|
+
if (colItems[i].isSubtotal) {
|
|
151
|
+
return 1;
|
|
152
|
+
}
|
|
153
|
+
const arr = colItems.map((item) => item.key);
|
|
154
|
+
if (i !== 0 && !colItems[i - 1].isSubtotal) {
|
|
80
155
|
let asPrevious = true;
|
|
81
156
|
for (let x = 0; x <= j; x++) {
|
|
82
157
|
if (arr[i - 1][x] !== arr[i][x]) {
|
|
@@ -90,6 +165,8 @@ function colSpanSize(arr, i, j) {
|
|
|
90
165
|
}
|
|
91
166
|
let len = 0;
|
|
92
167
|
while (i + len < arr.length) {
|
|
168
|
+
if (colItems[i + len].isSubtotal)
|
|
169
|
+
break;
|
|
93
170
|
let same = true;
|
|
94
171
|
for (let x = 0; x <= j; x++) {
|
|
95
172
|
if (arr[i][x] !== arr[i + len][x]) {
|
|
@@ -243,7 +320,11 @@ function makeSubtotalRenderer(opts = {}) {
|
|
|
243
320
|
const colKeys = pivotData.getColKeys();
|
|
244
321
|
const grandTotalAggregator = pivotData.getAggregator([], []);
|
|
245
322
|
const getAggregator = core.createSubtotalAggregatorGetter(pivotData);
|
|
246
|
-
const rowKeysWithSubtotals = generateRowKeysWithSubtotals(rowKeys, rowAttrs.length);
|
|
323
|
+
const rowKeysWithSubtotals = generateRowKeysWithSubtotals(rowKeys, rowAttrs.length, this.collapsedRowKeys);
|
|
324
|
+
const colKeysWithSubtotals = generateColKeysWithSubtotals(colKeys, colAttrs.length, this.collapsedColKeys);
|
|
325
|
+
const subtotalOpts = this.subtotalOptions;
|
|
326
|
+
const arrowCollapsed = subtotalOpts.arrowCollapsed || "▶";
|
|
327
|
+
const arrowExpanded = subtotalOpts.arrowExpanded || "▼";
|
|
247
328
|
const getClickHandler = (value, rowValues, colValues) => {
|
|
248
329
|
if (this.tableOptions && this.tableOptions.clickCallback) {
|
|
249
330
|
const filters = {};
|
|
@@ -270,25 +351,62 @@ function makeSubtotalRenderer(opts = {}) {
|
|
|
270
351
|
attrs: {
|
|
271
352
|
colSpan: rowAttrs.length,
|
|
272
353
|
rowSpan: colAttrs.length
|
|
273
|
-
},
|
|
274
|
-
style: {
|
|
275
|
-
backgroundColor: "#f5f5f5"
|
|
276
354
|
}
|
|
277
355
|
}));
|
|
278
356
|
}
|
|
279
357
|
cells.push(h("th", { class: "pvtAxisLabel" }, c));
|
|
280
|
-
|
|
281
|
-
const
|
|
282
|
-
if (
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
358
|
+
colKeysWithSubtotals.forEach((colItem, i) => {
|
|
359
|
+
const { key: colKey, isSubtotal, level } = colItem;
|
|
360
|
+
if (j < colKey.length) {
|
|
361
|
+
const colSpan = colSpanSizeWithSubtotals(colKeysWithSubtotals, i, j);
|
|
362
|
+
if (colSpan !== -1) {
|
|
363
|
+
const isLastAttrRow = j === colKey.length - 1;
|
|
364
|
+
if (isSubtotal && isLastAttrRow) {
|
|
365
|
+
const keyStr = JSON.stringify(colKey);
|
|
366
|
+
const isCollapsed = this.collapsedColKeys.has(keyStr);
|
|
367
|
+
const arrow = isCollapsed ? arrowCollapsed : arrowExpanded;
|
|
368
|
+
const label = `${colKey[j]} Subtotal`;
|
|
369
|
+
cells.push(h("th", {
|
|
370
|
+
class: "pvtColLabel pvtColSubtotalLabel",
|
|
371
|
+
key: `colKey${i}-${j}`,
|
|
372
|
+
attrs: {
|
|
373
|
+
colSpan,
|
|
374
|
+
rowSpan: colAttrs.length - j + (rowAttrs.length !== 0 ? 1 : 0)
|
|
375
|
+
},
|
|
376
|
+
style: {
|
|
377
|
+
fontWeight: "bold",
|
|
378
|
+
backgroundColor: "#f0f0f0"
|
|
379
|
+
}
|
|
380
|
+
}, [
|
|
381
|
+
h("span", {
|
|
382
|
+
class: "pvtColCollapseToggle",
|
|
383
|
+
style: {
|
|
384
|
+
cursor: "pointer",
|
|
385
|
+
marginRight: "4px",
|
|
386
|
+
userSelect: "none"
|
|
387
|
+
},
|
|
388
|
+
on: {
|
|
389
|
+
click: (e) => {
|
|
390
|
+
e.stopPropagation();
|
|
391
|
+
this.toggleColCollapse(keyStr);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}, arrow),
|
|
395
|
+
label
|
|
396
|
+
]));
|
|
397
|
+
} else {
|
|
398
|
+
const label = this.applyLabel(colAttrs[j], colKey[j]);
|
|
399
|
+
const rowSpan = isLastAttrRow && rowAttrs.length !== 0 ? 2 : 1;
|
|
400
|
+
cells.push(h("th", {
|
|
401
|
+
class: "pvtColLabel",
|
|
402
|
+
key: `colKey${i}-${j}`,
|
|
403
|
+
attrs: {
|
|
404
|
+
colSpan,
|
|
405
|
+
rowSpan
|
|
406
|
+
}
|
|
407
|
+
}, label));
|
|
290
408
|
}
|
|
291
|
-
}
|
|
409
|
+
}
|
|
292
410
|
}
|
|
293
411
|
});
|
|
294
412
|
if (j === 0 && this.rowTotal) {
|
|
@@ -306,6 +424,9 @@ function makeSubtotalRenderer(opts = {}) {
|
|
|
306
424
|
class: "pvtAxisLabel",
|
|
307
425
|
key: `rowAttr${i}`
|
|
308
426
|
}, r));
|
|
427
|
+
if (colAttrs.length !== 0) {
|
|
428
|
+
cells.push(h("th"));
|
|
429
|
+
}
|
|
309
430
|
if (colAttrs.length === 0 && this.rowTotal) {
|
|
310
431
|
cells.push(h("th", { class: "pvtTotalLabel" }, this.localeStrings.totals));
|
|
311
432
|
}
|
|
@@ -319,6 +440,9 @@ function makeSubtotalRenderer(opts = {}) {
|
|
|
319
440
|
const { key: rowKey, isSubtotal, level, subtotalLabel } = rowItem;
|
|
320
441
|
const cells = [];
|
|
321
442
|
if (isSubtotal) {
|
|
443
|
+
const keyStr = JSON.stringify(rowKey);
|
|
444
|
+
const isCollapsed = this.collapsedRowKeys.has(keyStr);
|
|
445
|
+
const arrow = isCollapsed ? arrowCollapsed : arrowExpanded;
|
|
322
446
|
const subtotalText = subtotalLabel || `${rowKey[rowKey.length - 1]} Subtotal`;
|
|
323
447
|
cells.push(h("th", {
|
|
324
448
|
class: "pvtRowLabel pvtSubtotalLabel",
|
|
@@ -329,18 +453,36 @@ function makeSubtotalRenderer(opts = {}) {
|
|
|
329
453
|
fontWeight: "bold",
|
|
330
454
|
backgroundColor: "#f0f0f0"
|
|
331
455
|
}
|
|
332
|
-
},
|
|
333
|
-
|
|
456
|
+
}, [
|
|
457
|
+
h("span", {
|
|
458
|
+
class: "pvtCollapseToggle",
|
|
459
|
+
style: {
|
|
460
|
+
cursor: "pointer",
|
|
461
|
+
marginRight: "6px",
|
|
462
|
+
userSelect: "none"
|
|
463
|
+
},
|
|
464
|
+
on: {
|
|
465
|
+
click: (e) => {
|
|
466
|
+
e.stopPropagation();
|
|
467
|
+
this.toggleRowCollapse(keyStr);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}, arrow),
|
|
471
|
+
subtotalText
|
|
472
|
+
]));
|
|
473
|
+
colKeysWithSubtotals.forEach((colItem, j) => {
|
|
474
|
+
const { key: colKey, isSubtotal: isColSubtotal } = colItem;
|
|
334
475
|
const aggregator = getAggregator(rowKey, colKey);
|
|
335
476
|
const val = aggregator.value();
|
|
336
477
|
const formattedVal = aggregator.format ? aggregator.format(val) : val;
|
|
337
478
|
const clickHandler = getClickHandler(val, rowKey, colKey);
|
|
479
|
+
const isDoubleSubtotal = isColSubtotal;
|
|
338
480
|
cells.push(h("td", {
|
|
339
|
-
class: "pvtVal pvtSubtotalVal",
|
|
481
|
+
class: isColSubtotal ? "pvtVal pvtSubtotalVal pvtColSubtotalVal" : "pvtVal pvtSubtotalVal",
|
|
340
482
|
key: `subtotal-val${i}-${j}`,
|
|
341
483
|
style: {
|
|
342
484
|
fontWeight: "bold",
|
|
343
|
-
backgroundColor: "#f0f0f0"
|
|
485
|
+
backgroundColor: isDoubleSubtotal ? "#e0e0e0" : "#f0f0f0"
|
|
344
486
|
},
|
|
345
487
|
on: clickHandler ? { click: clickHandler } : {}
|
|
346
488
|
}, formattedVal));
|
|
@@ -378,14 +520,19 @@ function makeSubtotalRenderer(opts = {}) {
|
|
|
378
520
|
}, label));
|
|
379
521
|
}
|
|
380
522
|
});
|
|
381
|
-
|
|
523
|
+
colKeysWithSubtotals.forEach((colItem, j) => {
|
|
524
|
+
const { key: colKey, isSubtotal: isColSubtotal } = colItem;
|
|
382
525
|
const aggregator = getAggregator(rowKey, colKey);
|
|
383
526
|
const val = aggregator.value();
|
|
384
527
|
const formattedVal = aggregator.format ? aggregator.format(val) : val;
|
|
385
528
|
const clickHandler = getClickHandler(val, rowKey, colKey);
|
|
386
529
|
cells.push(h("td", {
|
|
387
|
-
class: "pvtVal",
|
|
530
|
+
class: isColSubtotal ? "pvtVal pvtColSubtotalVal" : "pvtVal",
|
|
388
531
|
key: `val${i}-${j}`,
|
|
532
|
+
style: isColSubtotal ? {
|
|
533
|
+
fontWeight: "bold",
|
|
534
|
+
backgroundColor: "#f0f0f0"
|
|
535
|
+
} : void 0,
|
|
389
536
|
on: clickHandler ? { click: clickHandler } : {}
|
|
390
537
|
}, formattedVal));
|
|
391
538
|
});
|
|
@@ -410,14 +557,19 @@ function makeSubtotalRenderer(opts = {}) {
|
|
|
410
557
|
colSpan: rowAttrs.length + (colAttrs.length === 0 ? 0 : 1)
|
|
411
558
|
}
|
|
412
559
|
}, this.localeStrings.totals));
|
|
413
|
-
|
|
560
|
+
colKeysWithSubtotals.forEach((colItem, i) => {
|
|
561
|
+
const { key: colKey, isSubtotal: isColSubtotal } = colItem;
|
|
414
562
|
const totalAggregator = getAggregator([], colKey);
|
|
415
563
|
const totalVal = totalAggregator.value();
|
|
416
564
|
const formattedTotal = totalAggregator.format ? totalAggregator.format(totalVal) : totalVal;
|
|
417
565
|
const clickHandler = getClickHandler(totalVal, [], colKey);
|
|
418
566
|
cells.push(h("td", {
|
|
419
|
-
class: "pvtTotal",
|
|
567
|
+
class: isColSubtotal ? "pvtTotal pvtColSubtotalTotal" : "pvtTotal",
|
|
420
568
|
key: `colTotal${i}`,
|
|
569
|
+
style: isColSubtotal ? {
|
|
570
|
+
fontWeight: "bold",
|
|
571
|
+
backgroundColor: "#e0e0e0"
|
|
572
|
+
} : void 0,
|
|
421
573
|
on: clickHandler ? { click: clickHandler } : {}
|
|
422
574
|
}, formattedTotal));
|
|
423
575
|
});
|