@hrforte/react-pivottable 2.2.1 → 3.0.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/dist/PivotDataWorker.js +219 -13
- package/dist/PivotDataWorker.js.map +1 -1
- package/dist/PivotTable.js +2 -1
- package/dist/PivotTable.js.map +1 -1
- package/dist/PivotTableUI.js +145 -48
- package/dist/PivotTableUI.js.map +1 -1
- package/dist/TableRenderers.js +629 -118
- package/dist/TableRenderers.js.map +1 -1
- package/dist/Utilities.js +104 -179
- package/dist/Utilities.js.map +1 -1
- package/dist/__tests__/PivotDataWorker-test.js +437 -7
- package/dist/__tests__/PivotDataWorker-test.js.map +1 -1
- package/dist/__tests__/PivotTableUI-processing-test.js +42 -3
- package/dist/__tests__/PivotTableUI-processing-test.js.map +1 -1
- package/dist/__tests__/PivotTableUI-rerender-test.js +314 -0
- package/dist/__tests__/PivotTableUI-rerender-test.js.map +1 -0
- package/dist/__tests__/TableRenderers-showNumericalOrder-test.js +449 -0
- package/dist/__tests__/TableRenderers-showNumericalOrder-test.js.map +1 -1
- package/dist/__tests__/pivotCompute-test.js +137 -0
- package/dist/__tests__/pivotCompute-test.js.map +1 -1
- package/dist/pivot-worker.js +510 -201
- package/dist/pivotCompute.js +238 -12
- package/dist/pivotCompute.js.map +1 -1
- package/dist/pivotWorker.js +165 -9
- package/dist/pivotWorker.js.map +1 -1
- package/dist/pivottable.css +277 -235
- package/package.json +1 -1
package/dist/TableRenderers.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.getPivotTableProps = undefined;
|
|
6
7
|
|
|
7
8
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
8
9
|
|
|
@@ -20,6 +21,10 @@ var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
|
20
21
|
|
|
21
22
|
var _Utilities = require('./Utilities');
|
|
22
23
|
|
|
24
|
+
var _pivotCompute = require('./pivotCompute');
|
|
25
|
+
|
|
26
|
+
var _PivotDataWorker = require('./PivotDataWorker');
|
|
27
|
+
|
|
23
28
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
24
29
|
|
|
25
30
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
@@ -28,7 +33,59 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen
|
|
|
28
33
|
|
|
29
34
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
30
35
|
|
|
31
|
-
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
36
|
+
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } /* eslint-disable no-inline-comments */
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
var pivotTablePropsByElement = new WeakMap();
|
|
40
|
+
|
|
41
|
+
var getPivotTableProps = exports.getPivotTableProps = function getPivotTableProps(element) {
|
|
42
|
+
return pivotTablePropsByElement.get(element);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
var VIRTUAL_ROW_HEIGHT = 32;
|
|
46
|
+
var VIRTUAL_ROW_OVERSCAN = 8;
|
|
47
|
+
var VIRTUAL_ROW_BLOCK = 32;
|
|
48
|
+
var VIRTUAL_COLUMN_WIDTH = 100;
|
|
49
|
+
var VIRTUAL_COLUMN_OVERSCAN = 4;
|
|
50
|
+
var VIRTUAL_COLUMN_BLOCK = 16;
|
|
51
|
+
var VIRTUAL_LOADING_PAINT_MS = 16;
|
|
52
|
+
var VIRTUAL_SCROLL_DEBOUNCE_MS = 500;
|
|
53
|
+
var INITIAL_ROW_WINDOW_END = 50;
|
|
54
|
+
var INITIAL_COLUMN_WINDOW_END = 32;
|
|
55
|
+
var FLAT_KEY_SEPARATOR = String.fromCharCode(0);
|
|
56
|
+
|
|
57
|
+
var _getViewportKeyForProps = function _getViewportKeyForProps(props) {
|
|
58
|
+
var precomputed = props.precomputedData;
|
|
59
|
+
return precomputed && typeof precomputed.viewportKey === 'number' && !(0, _pivotCompute.sortersHaveFunctions)(props.sorters) ? precomputed.viewportKey : null;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
function PivotLoadingContent() {
|
|
63
|
+
return _react2.default.createElement(
|
|
64
|
+
_react2.default.Fragment,
|
|
65
|
+
null,
|
|
66
|
+
_react2.default.createElement('div', { className: 'pvtLoadingSpinner', 'aria-hidden': 'true' }),
|
|
67
|
+
_react2.default.createElement(
|
|
68
|
+
'div',
|
|
69
|
+
{ className: 'pvtLoadingText' },
|
|
70
|
+
'Processing'
|
|
71
|
+
)
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
var getScrollParent = function getScrollParent(element) {
|
|
76
|
+
var parent = element.parentElement;
|
|
77
|
+
while (parent && parent !== document.body) {
|
|
78
|
+
var _window$getComputedSt = window.getComputedStyle(parent),
|
|
79
|
+
overflowX = _window$getComputedSt.overflowX,
|
|
80
|
+
overflowY = _window$getComputedSt.overflowY;
|
|
81
|
+
|
|
82
|
+
if (overflowX === 'auto' || overflowX === 'scroll' || overflowY === 'auto' || overflowY === 'scroll') {
|
|
83
|
+
return parent;
|
|
84
|
+
}
|
|
85
|
+
parent = parent.parentElement;
|
|
86
|
+
}
|
|
87
|
+
return window;
|
|
88
|
+
};
|
|
32
89
|
|
|
33
90
|
// helper function for setting row/col-span in pivotTableRenderer
|
|
34
91
|
var spanSize = function spanSize(arr, i, j) {
|
|
@@ -64,24 +121,31 @@ var spanSize = function spanSize(arr, i, j) {
|
|
|
64
121
|
return len;
|
|
65
122
|
};
|
|
66
123
|
|
|
67
|
-
// ==>
|
|
68
|
-
|
|
69
|
-
|
|
124
|
+
// ==> Build a lookup: name -> group label <==
|
|
125
|
+
// `match` can contain row attribute names, the synthetic 'Values' column
|
|
126
|
+
// (aggregations displayed as rows) and aggregation names/labels
|
|
127
|
+
// (aggregations displayed as columns).
|
|
128
|
+
function buildGroupLookup(rowGroupConfig) {
|
|
129
|
+
var lookup = {};
|
|
70
130
|
(rowGroupConfig || []).forEach(function (_ref) {
|
|
71
131
|
var label = _ref.label,
|
|
72
132
|
match = _ref.match;
|
|
73
133
|
|
|
74
134
|
match.forEach(function (name) {
|
|
75
|
-
|
|
135
|
+
lookup[name] = label;
|
|
76
136
|
});
|
|
77
137
|
});
|
|
138
|
+
return lookup;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// ==> Calculate the positions for GroupSegments <==
|
|
142
|
+
function buildHeaderGroupSegments(attrs, rowGroupConfig) {
|
|
143
|
+
var lookup = buildGroupLookup(rowGroupConfig);
|
|
78
144
|
|
|
79
145
|
// Mỗi attribute luôn là 1 segment riêng — không gộp colSpan nữa,
|
|
80
146
|
// để label nhóm (vd "AAA") hiện lặp lại trên từng cột con.
|
|
81
|
-
return
|
|
82
|
-
|
|
83
|
-
var group = attrToGroup[name] !== undefined ? attrToGroup[name] : null;
|
|
84
|
-
return { group: group, span: 1 };
|
|
147
|
+
return attrs.map(function (name) {
|
|
148
|
+
return { group: lookup[name] || null, span: 1 };
|
|
85
149
|
});
|
|
86
150
|
}
|
|
87
151
|
|
|
@@ -342,18 +406,308 @@ function makeRenderer() {
|
|
|
342
406
|
var TableRenderer = function (_React$PureComponent) {
|
|
343
407
|
_inherits(TableRenderer, _React$PureComponent);
|
|
344
408
|
|
|
345
|
-
function TableRenderer() {
|
|
409
|
+
function TableRenderer(props) {
|
|
346
410
|
_classCallCheck(this, TableRenderer);
|
|
347
411
|
|
|
348
|
-
|
|
412
|
+
var _this = _possibleConstructorReturn(this, (TableRenderer.__proto__ || Object.getPrototypeOf(TableRenderer)).call(this, props));
|
|
413
|
+
|
|
414
|
+
_this.state = {
|
|
415
|
+
start: 0,
|
|
416
|
+
end: INITIAL_ROW_WINDOW_END,
|
|
417
|
+
rows: null,
|
|
418
|
+
columnStart: 0,
|
|
419
|
+
columnEnd: INITIAL_COLUMN_WINDOW_END,
|
|
420
|
+
columnTotals: null,
|
|
421
|
+
viewportKey: null,
|
|
422
|
+
sourceViewportKey: _getViewportKeyForProps(props),
|
|
423
|
+
scrollPending: false
|
|
424
|
+
};
|
|
425
|
+
_this.bodyRef = _react2.default.createRef();
|
|
426
|
+
_this.scrollParent = null;
|
|
427
|
+
_this.overlayBounds = null;
|
|
428
|
+
_this.frameId = null;
|
|
429
|
+
_this.scrollTimer = null;
|
|
430
|
+
_this.scrollPending = false;
|
|
431
|
+
_this.rowCount = 0;
|
|
432
|
+
_this.columnCount = 0;
|
|
433
|
+
_this.leadingColumnCount = 0;
|
|
434
|
+
_this.leadingColumnWidth = 0;
|
|
435
|
+
_this.pivotProps = null;
|
|
436
|
+
_this.pivotData = null;
|
|
437
|
+
_this.requestedWindow = null;
|
|
438
|
+
_this.viewportTimer = null;
|
|
439
|
+
_this.unmounted = false;
|
|
440
|
+
_this.scheduleUpdate = _this.scheduleUpdate.bind(_this);
|
|
441
|
+
_this.handleScroll = _this.handleScroll.bind(_this);
|
|
442
|
+
return _this;
|
|
349
443
|
}
|
|
350
444
|
|
|
351
445
|
_createClass(TableRenderer, [{
|
|
446
|
+
key: 'componentDidMount',
|
|
447
|
+
value: function componentDidMount() {
|
|
448
|
+
this.attachScroll();
|
|
449
|
+
this.updateWindow();
|
|
450
|
+
}
|
|
451
|
+
}, {
|
|
452
|
+
key: 'componentDidUpdate',
|
|
453
|
+
value: function componentDidUpdate(prevProps) {
|
|
454
|
+
if (prevProps === this.props) {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
var previousViewportKey = this.getViewportKeyForProps(prevProps);
|
|
459
|
+
var nextViewportKey = this.getViewportKey();
|
|
460
|
+
if (previousViewportKey !== nextViewportKey) {
|
|
461
|
+
this.invalidateViewportRequest();
|
|
462
|
+
if (this.scrollTimer !== null) {
|
|
463
|
+
clearTimeout(this.scrollTimer);
|
|
464
|
+
this.scrollTimer = null;
|
|
465
|
+
}
|
|
466
|
+
this.scrollPending = false;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
this.attachScroll();
|
|
470
|
+
this.scheduleUpdate();
|
|
471
|
+
}
|
|
472
|
+
}, {
|
|
473
|
+
key: 'componentWillUnmount',
|
|
474
|
+
value: function componentWillUnmount() {
|
|
475
|
+
this.unmounted = true;
|
|
476
|
+
if (this.viewportTimer !== null) {
|
|
477
|
+
clearTimeout(this.viewportTimer);
|
|
478
|
+
}
|
|
479
|
+
if (this.scrollTimer !== null) {
|
|
480
|
+
clearTimeout(this.scrollTimer);
|
|
481
|
+
}
|
|
482
|
+
if (this.scrollParent) {
|
|
483
|
+
this.scrollParent.removeEventListener('scroll', this.handleScroll);
|
|
484
|
+
}
|
|
485
|
+
window.removeEventListener('resize', this.scheduleUpdate);
|
|
486
|
+
if (this.frameId !== null) {
|
|
487
|
+
if (typeof cancelAnimationFrame === 'function') {
|
|
488
|
+
cancelAnimationFrame(this.frameId);
|
|
489
|
+
} else {
|
|
490
|
+
clearTimeout(this.frameId);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}, {
|
|
495
|
+
key: 'attachScroll',
|
|
496
|
+
value: function attachScroll() {
|
|
497
|
+
if (!this.props.virtualizeRows) {
|
|
498
|
+
if (this.scrollParent) {
|
|
499
|
+
this.scrollParent.removeEventListener('scroll', this.handleScroll);
|
|
500
|
+
this.scrollParent = null;
|
|
501
|
+
window.removeEventListener('resize', this.scheduleUpdate);
|
|
502
|
+
}
|
|
503
|
+
if (this.scrollTimer !== null) {
|
|
504
|
+
clearTimeout(this.scrollTimer);
|
|
505
|
+
this.scrollTimer = null;
|
|
506
|
+
}
|
|
507
|
+
this.scrollPending = false;
|
|
508
|
+
this.invalidateViewportRequest();
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
if (!this.bodyRef.current) {
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
var parent = getScrollParent(this.bodyRef.current);
|
|
515
|
+
if (parent === this.scrollParent) {
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
if (this.scrollParent) {
|
|
519
|
+
this.scrollParent.removeEventListener('scroll', this.handleScroll);
|
|
520
|
+
}
|
|
521
|
+
this.scrollParent = parent;
|
|
522
|
+
this.updateOverlayBounds();
|
|
523
|
+
parent.addEventListener('scroll', this.handleScroll, { passive: true });
|
|
524
|
+
window.addEventListener('resize', this.scheduleUpdate);
|
|
525
|
+
}
|
|
526
|
+
}, {
|
|
527
|
+
key: 'updateOverlayBounds',
|
|
528
|
+
value: function updateOverlayBounds() {
|
|
529
|
+
if (!this.scrollParent) {
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
var bounds = this.scrollParent === window ? {
|
|
533
|
+
top: 0,
|
|
534
|
+
left: 0,
|
|
535
|
+
width: window.innerWidth,
|
|
536
|
+
height: window.innerHeight
|
|
537
|
+
} : this.scrollParent.getBoundingClientRect();
|
|
538
|
+
this.overlayBounds = {
|
|
539
|
+
top: Math.max(0, bounds.top),
|
|
540
|
+
left: Math.max(0, bounds.left),
|
|
541
|
+
width: Math.max(0, Math.min(window.innerWidth, bounds.left + bounds.width) - Math.max(0, bounds.left)),
|
|
542
|
+
height: Math.max(0, Math.min(window.innerHeight, bounds.top + bounds.height) - Math.max(0, bounds.top))
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
}, {
|
|
546
|
+
key: 'handleScroll',
|
|
547
|
+
value: function handleScroll() {
|
|
548
|
+
var _this2 = this;
|
|
549
|
+
|
|
550
|
+
if (this.scrollTimer !== null) {
|
|
551
|
+
clearTimeout(this.scrollTimer);
|
|
552
|
+
}
|
|
553
|
+
if (!this.scrollPending) {
|
|
554
|
+
this.scrollPending = true;
|
|
555
|
+
this.updateOverlayBounds();
|
|
556
|
+
this.setState({ scrollPending: true });
|
|
557
|
+
}
|
|
558
|
+
this.scrollTimer = setTimeout(function () {
|
|
559
|
+
_this2.scrollTimer = null;
|
|
560
|
+
_this2.scrollPending = false;
|
|
561
|
+
_this2.updateWindow();
|
|
562
|
+
if (!_this2.unmounted) {
|
|
563
|
+
_this2.setState({ scrollPending: false });
|
|
564
|
+
}
|
|
565
|
+
}, VIRTUAL_SCROLL_DEBOUNCE_MS);
|
|
566
|
+
}
|
|
567
|
+
}, {
|
|
568
|
+
key: 'scheduleUpdate',
|
|
569
|
+
value: function scheduleUpdate() {
|
|
570
|
+
var _this3 = this;
|
|
571
|
+
|
|
572
|
+
if (this.frameId !== null) {
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
var schedule = typeof requestAnimationFrame === 'function' ? requestAnimationFrame : function (callback) {
|
|
576
|
+
return setTimeout(callback, 16);
|
|
577
|
+
};
|
|
578
|
+
this.frameId = schedule(function () {
|
|
579
|
+
_this3.frameId = null;
|
|
580
|
+
_this3.updateOverlayBounds();
|
|
581
|
+
if (!_this3.props.virtualizeRows && _this3.state.scrollPending) {
|
|
582
|
+
_this3.setState({ scrollPending: false });
|
|
583
|
+
}
|
|
584
|
+
if (!_this3.scrollPending) {
|
|
585
|
+
_this3.updateWindow();
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
}, {
|
|
590
|
+
key: 'getViewportKeyForProps',
|
|
591
|
+
value: function getViewportKeyForProps(props) {
|
|
592
|
+
return _getViewportKeyForProps(props);
|
|
593
|
+
}
|
|
594
|
+
}, {
|
|
595
|
+
key: 'getViewportKey',
|
|
596
|
+
value: function getViewportKey() {
|
|
597
|
+
return this.getViewportKeyForProps(this.props);
|
|
598
|
+
}
|
|
599
|
+
}, {
|
|
600
|
+
key: 'invalidateViewportRequest',
|
|
601
|
+
value: function invalidateViewportRequest() {
|
|
602
|
+
this.requestedWindow = null;
|
|
603
|
+
if (this.viewportTimer !== null) {
|
|
604
|
+
clearTimeout(this.viewportTimer);
|
|
605
|
+
this.viewportTimer = null;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}, {
|
|
609
|
+
key: 'requestViewportWindow',
|
|
610
|
+
value: function requestViewportWindow(start, end, columnStart, columnEnd, viewportKey) {
|
|
611
|
+
var _this4 = this;
|
|
612
|
+
|
|
613
|
+
var columnMode = this.props.tableOptions && this.props.tableOptions.aggregationDisplayMode === 'column';
|
|
614
|
+
var requestKey = viewportKey + ':' + start + ':' + end + ':' + (columnStart + ':' + columnEnd + ':' + columnMode);
|
|
615
|
+
if (requestKey === this.requestedWindow) {
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
this.requestedWindow = requestKey;
|
|
619
|
+
if (this.viewportTimer !== null) {
|
|
620
|
+
clearTimeout(this.viewportTimer);
|
|
621
|
+
}
|
|
622
|
+
this.setState({
|
|
623
|
+
start: start,
|
|
624
|
+
end: end,
|
|
625
|
+
columnStart: columnStart,
|
|
626
|
+
columnEnd: columnEnd,
|
|
627
|
+
rows: null,
|
|
628
|
+
columnTotals: null,
|
|
629
|
+
viewportKey: viewportKey
|
|
630
|
+
});
|
|
631
|
+
// Give the browser a frame to paint the loading row before dispatching.
|
|
632
|
+
this.viewportTimer = setTimeout(function () {
|
|
633
|
+
_this4.viewportTimer = null;
|
|
634
|
+
(0, _PivotDataWorker.computePivotViewportInWorker)(viewportKey, start, end, columnMode, columnStart, columnEnd).catch(function (error) {
|
|
635
|
+
if (error && error.code === 'PIVOT_VIEWPORT_CANCELLED') {
|
|
636
|
+
return null;
|
|
637
|
+
}
|
|
638
|
+
return (0, _pivotCompute.computePivotViewport)(_this4.props.precomputedData, start, end, columnMode, columnStart, columnEnd);
|
|
639
|
+
}).then(function (viewport) {
|
|
640
|
+
if (!viewport || _this4.unmounted || _this4.requestedWindow !== requestKey) {
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
_this4.setState({
|
|
644
|
+
rows: viewport.rows,
|
|
645
|
+
columnTotals: viewport.colTotals || {}
|
|
646
|
+
});
|
|
647
|
+
});
|
|
648
|
+
}, VIRTUAL_LOADING_PAINT_MS);
|
|
649
|
+
}
|
|
650
|
+
}, {
|
|
651
|
+
key: 'measureLeadingColumnWidth',
|
|
652
|
+
value: function measureLeadingColumnWidth() {
|
|
653
|
+
var body = this.bodyRef.current;
|
|
654
|
+
var table = body && body.parentElement;
|
|
655
|
+
var firstColumn = table && table.querySelector('thead .pvtColLabel');
|
|
656
|
+
if (!table || !firstColumn) {
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
var tableBounds = table.getBoundingClientRect();
|
|
660
|
+
var firstColumnBounds = firstColumn.getBoundingClientRect();
|
|
661
|
+
var leftSpacer = table.querySelector('thead .pvtVirtualColumnSpacer-left');
|
|
662
|
+
var leftSpacerWidth = leftSpacer ? leftSpacer.getBoundingClientRect().width : 0;
|
|
663
|
+
var measuredWidth = firstColumnBounds.left - tableBounds.left - leftSpacerWidth;
|
|
664
|
+
if (Number.isFinite(measuredWidth) && measuredWidth > 0) {
|
|
665
|
+
this.leadingColumnWidth = measuredWidth;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}, {
|
|
669
|
+
key: 'updateWindow',
|
|
670
|
+
value: function updateWindow() {
|
|
671
|
+
if (!this.scrollParent || !this.bodyRef.current || !this.props.virtualizeRows) {
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
var viewportTop = this.scrollParent === window ? 0 : this.scrollParent.getBoundingClientRect().top;
|
|
675
|
+
var viewportHeight = this.scrollParent === window ? window.innerHeight : this.scrollParent.clientHeight;
|
|
676
|
+
var viewportLeft = this.scrollParent === window ? 0 : this.scrollParent.getBoundingClientRect().left;
|
|
677
|
+
var viewportWidth = this.scrollParent === window ? window.innerWidth : this.scrollParent.clientWidth;
|
|
678
|
+
var bodyBounds = this.bodyRef.current.getBoundingClientRect();
|
|
679
|
+
var bodyTop = Number.isFinite(bodyBounds.top) ? bodyBounds.top : 0;
|
|
680
|
+
var bodyLeft = Number.isFinite(bodyBounds.left) ? bodyBounds.left : 0;
|
|
681
|
+
this.measureLeadingColumnWidth();
|
|
682
|
+
var offset = viewportTop - bodyTop;
|
|
683
|
+
var requestedStart = Math.max(0, Math.min(this.rowCount, Math.floor(offset / VIRTUAL_ROW_HEIGHT) - VIRTUAL_ROW_OVERSCAN));
|
|
684
|
+
var start = Math.floor(requestedStart / VIRTUAL_ROW_BLOCK) * VIRTUAL_ROW_BLOCK;
|
|
685
|
+
var end = Math.min(this.rowCount, start + Math.ceil(viewportHeight / VIRTUAL_ROW_HEIGHT) + VIRTUAL_ROW_BLOCK + VIRTUAL_ROW_OVERSCAN * 2);
|
|
686
|
+
var horizontalOffset = Math.max(0, viewportLeft - bodyLeft - (this.leadingColumnWidth || this.leadingColumnCount * VIRTUAL_COLUMN_WIDTH));
|
|
687
|
+
var requestedColumnStart = Math.max(0, Math.min(this.columnCount, Math.floor(horizontalOffset / VIRTUAL_COLUMN_WIDTH) - VIRTUAL_COLUMN_OVERSCAN));
|
|
688
|
+
var columnStart = Math.floor(requestedColumnStart / VIRTUAL_COLUMN_BLOCK) * VIRTUAL_COLUMN_BLOCK;
|
|
689
|
+
var columnEnd = Math.min(this.columnCount, columnStart + Math.ceil(viewportWidth / VIRTUAL_COLUMN_WIDTH) + VIRTUAL_COLUMN_BLOCK + VIRTUAL_COLUMN_OVERSCAN * 2);
|
|
690
|
+
var viewportKey = this.getViewportKey();
|
|
691
|
+
if (viewportKey !== null && (this.rowCount > _pivotCompute.VIRTUAL_ROW_THRESHOLD || this.columnCount > _pivotCompute.VIRTUAL_COLUMN_THRESHOLD)) {
|
|
692
|
+
this.requestViewportWindow(start, end, columnStart, columnEnd, viewportKey);
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
this.invalidateViewportRequest();
|
|
696
|
+
if (start !== this.state.start || end !== this.state.end || columnStart !== this.state.columnStart || columnEnd !== this.state.columnEnd) {
|
|
697
|
+
this.setState({ start: start, end: end, columnStart: columnStart, columnEnd: columnEnd });
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}, {
|
|
352
701
|
key: 'render',
|
|
353
702
|
value: function render() {
|
|
354
|
-
var
|
|
703
|
+
var _this5 = this;
|
|
355
704
|
|
|
356
|
-
|
|
705
|
+
if (this.pivotProps !== this.props) {
|
|
706
|
+
var pivotProps = !this.props.virtualizeRows && this.props.precomputedData && this.props.precomputedData.virtualized ? Object.assign({}, this.props, { precomputedData: null }) : this.props;
|
|
707
|
+
this.pivotData = new _Utilities.PivotData(pivotProps);
|
|
708
|
+
this.pivotProps = this.props;
|
|
709
|
+
}
|
|
710
|
+
var pivotData = this.pivotData;
|
|
357
711
|
var colAttrs = pivotData.props.cols;
|
|
358
712
|
var rowAttrs = pivotData.props.rows;
|
|
359
713
|
var aggregations = pivotData.getAggregations();
|
|
@@ -369,16 +723,15 @@ function makeRenderer() {
|
|
|
369
723
|
var shouldRenderRowHeaderPlaceholder = rowAttrsToRender.length !== 0;
|
|
370
724
|
|
|
371
725
|
// --- Row group header (rowGroupConfig) ---
|
|
726
|
+
// `match` may reference row attribute names, 'Values' (aggregations shown
|
|
727
|
+
// as rows) and aggregation names/labels (aggregations shown as columns).
|
|
728
|
+
// Every column gets its own <th>, so the group label is repeated on each.
|
|
372
729
|
var rowGroupConfig = this.props.rowGroupConfig;
|
|
373
730
|
var hasHeaderGroup = Boolean(rowGroupConfig && rowGroupConfig.length);
|
|
374
|
-
var
|
|
375
|
-
|
|
376
|
-
// are multiple aggregators shown as rows; it isn't part of any group.
|
|
377
|
-
var headerGroupExtraSpan = rowAttrsToRender.length - rowAttrs.length;
|
|
731
|
+
var groupLookup = buildGroupLookup(rowGroupConfig);
|
|
732
|
+
var headerGroupSegments = hasHeaderGroup ? buildHeaderGroupSegments(rowAttrsToRender, rowGroupConfig) : [];
|
|
378
733
|
var renderGroupSegments = function renderGroupSegments(rowSpan) {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
var cells = headerGroupSegments.map(function (seg, idx) {
|
|
734
|
+
return headerGroupSegments.map(function (seg, idx) {
|
|
382
735
|
return _react2.default.createElement(
|
|
383
736
|
'th',
|
|
384
737
|
{
|
|
@@ -391,10 +744,6 @@ function makeRenderer() {
|
|
|
391
744
|
seg.group || ''
|
|
392
745
|
);
|
|
393
746
|
});
|
|
394
|
-
if (extraSpan > 0) {
|
|
395
|
-
cells.push(_react2.default.createElement('th', { key: 'hgSegExtra', colSpan: extraSpan, rowSpan: rowSpan }));
|
|
396
|
-
}
|
|
397
|
-
return cells;
|
|
398
747
|
};
|
|
399
748
|
// --- End row group header ---
|
|
400
749
|
|
|
@@ -408,7 +757,7 @@ function makeRenderer() {
|
|
|
408
757
|
// The "No." header cell is rendered in the first header row and spans
|
|
409
758
|
// every header row, so the repeated header rows (column attributes,
|
|
410
759
|
// aggregator labels, row group labels) stay aligned with the body.
|
|
411
|
-
var numberColumnHeaderRowSpan = colAttrsToRender.length + (renderedAggregationHeaderRow ? 1 : 0) + (rowAttrsToRender.length !== 0 && !renderedAggregationHeaderRow ? 1 : 0) + (hasHeaderGroup && colAttrsToRender.length === 0 && rowAttrsToRender.length !== 0 ? 1 : 0);
|
|
760
|
+
var numberColumnHeaderRowSpan = colAttrsToRender.length + (renderedAggregationHeaderRow ? 1 : 0) + (rowAttrsToRender.length !== 0 && !renderedAggregationHeaderRow ? 1 : 0) + (hasHeaderGroup && colAttrsToRender.length === 0 && rowAttrsToRender.length !== 0 ? 1 : 0) + (renderedAggregationHeaderRow && hasHeaderGroup ? 1 : 0);
|
|
412
761
|
var numberColumnInGroupRow = hasHeaderGroup && colAttrsToRender.length === 0 && rowAttrsToRender.length !== 0;
|
|
413
762
|
var renderNumberHeaderCell = function renderNumberHeaderCell() {
|
|
414
763
|
var rowSpan = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : numberColumnHeaderRowSpan;
|
|
@@ -422,86 +771,96 @@ function makeRenderer() {
|
|
|
422
771
|
|
|
423
772
|
var rowKeys = pivotData.getRowKeys();
|
|
424
773
|
var baseRowKeys = hasMultipleAggregators && !isColumnAggregationMode && rowKeys.length === 0 ? [[]] : rowKeys;
|
|
425
|
-
var
|
|
426
|
-
|
|
427
|
-
acc.push({
|
|
428
|
-
displayKey: rowKey.concat([agg.label || agg.aggregatorName]),
|
|
429
|
-
actualKey: rowKey,
|
|
430
|
-
aggregationKey: agg.key
|
|
431
|
-
});
|
|
432
|
-
});
|
|
433
|
-
return acc;
|
|
434
|
-
}, []) : baseRowKeys.map(function (rowKey) {
|
|
435
|
-
return {
|
|
436
|
-
displayKey: rowKey,
|
|
437
|
-
actualKey: rowKey,
|
|
438
|
-
aggregationKey: primaryAggregation.key
|
|
439
|
-
};
|
|
440
|
-
});
|
|
441
|
-
var rowKeyValues = renderedRows.map(function (r) {
|
|
442
|
-
return r.displayKey;
|
|
443
|
-
});
|
|
774
|
+
var totalRowCount = this.props.precomputedData && this.props.precomputedData.virtualized && typeof this.props.precomputedData.totalRows === 'number' ? this.props.precomputedData.totalRows : baseRowKeys.length * (hasMultipleAggregators && !isColumnAggregationMode ? aggregations.length : 1);
|
|
775
|
+
var isRowVirtualized = Boolean(this.props.virtualizeRows) && totalRowCount > _pivotCompute.VIRTUAL_ROW_THRESHOLD;
|
|
444
776
|
var colKeys = pivotData.getColKeys();
|
|
445
777
|
var baseColKeys = isColumnAggregationMode && colKeys.length === 0 ? [[]] : colKeys;
|
|
446
|
-
var
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
778
|
+
var totalColumnCount = isColumnAggregationMode ? baseColKeys.length * aggregations.length : colKeys.length;
|
|
779
|
+
var isColumnVirtualized = Boolean(this.props.virtualizeRows) && totalColumnCount > _pivotCompute.VIRTUAL_COLUMN_THRESHOLD;
|
|
780
|
+
var isVirtualized = isRowVirtualized || isColumnVirtualized;
|
|
781
|
+
var visibleColumnStart = isColumnVirtualized ? Math.min(this.state.columnStart, totalColumnCount) : 0;
|
|
782
|
+
var visibleColumnEnd = isColumnVirtualized ? Math.min(Math.max(this.state.columnEnd, visibleColumnStart), totalColumnCount) : totalColumnCount;
|
|
783
|
+
var columnMeta = [];
|
|
784
|
+
for (var columnIndex = visibleColumnStart; columnIndex < visibleColumnEnd; columnIndex++) {
|
|
785
|
+
if (isColumnAggregationMode) {
|
|
786
|
+
var colKey = baseColKeys[Math.floor(columnIndex / aggregations.length)];
|
|
787
|
+
var aggregation = aggregations[columnIndex % aggregations.length];
|
|
788
|
+
columnMeta.push({
|
|
789
|
+
displayKey: colKey.concat([aggregation.label || aggregation.aggregatorName]),
|
|
450
790
|
actualKey: colKey,
|
|
451
|
-
aggregationKey:
|
|
791
|
+
aggregationKey: aggregation.key,
|
|
792
|
+
absoluteIndex: columnIndex
|
|
452
793
|
});
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
794
|
+
} else {
|
|
795
|
+
var _colKey = colKeys[columnIndex];
|
|
796
|
+
columnMeta.push({
|
|
797
|
+
displayKey: _colKey,
|
|
798
|
+
actualKey: _colKey,
|
|
799
|
+
aggregationKey: primaryAggregation.key,
|
|
800
|
+
absoluteIndex: columnIndex
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
}
|
|
462
804
|
var colKeyValues = columnMeta.map(function (col) {
|
|
463
805
|
return col.displayKey;
|
|
464
806
|
});
|
|
807
|
+
var leftColumnSpacerWidth = isColumnVirtualized ? visibleColumnStart * VIRTUAL_COLUMN_WIDTH : 0;
|
|
808
|
+
var rightColumnSpacerWidth = isColumnVirtualized ? (totalColumnCount - visibleColumnEnd) * VIRTUAL_COLUMN_WIDTH : 0;
|
|
809
|
+
var renderColumnSpacer = function renderColumnSpacer(side, width) {
|
|
810
|
+
var Cell = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'th';
|
|
811
|
+
return width > 0 ? _react2.default.createElement(Cell, {
|
|
812
|
+
'aria-hidden': 'true',
|
|
813
|
+
className: 'pvtVirtualColumnSpacer pvtVirtualColumnSpacer-' + side,
|
|
814
|
+
key: 'virtual-column-spacer-' + side,
|
|
815
|
+
style: { width: width, minWidth: width, maxWidth: width }
|
|
816
|
+
}) : null;
|
|
817
|
+
};
|
|
465
818
|
|
|
466
819
|
var renderAggregatorHeaderCells = function renderAggregatorHeaderCells() {
|
|
467
|
-
return
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
//
|
|
478
|
-
//
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
820
|
+
return _react2.default.createElement(
|
|
821
|
+
_react2.default.Fragment,
|
|
822
|
+
null,
|
|
823
|
+
renderColumnSpacer('left', leftColumnSpacerWidth),
|
|
824
|
+
columnMeta.map(function (colMeta, idx) {
|
|
825
|
+
var label = colMeta.displayKey[colMeta.displayKey.length - 1] || '';
|
|
826
|
+
// Calculate colspan/rowspan so aggregator headers line up with column groups
|
|
827
|
+
// aggregator index is the last element in displayKey (after column attrs)
|
|
828
|
+
var aggIndex = colAttrsToRender.length;
|
|
829
|
+
// When there are column attributes, each aggregator should appear once per column group,
|
|
830
|
+
// so each aggregator header should have colSpan = 1.
|
|
831
|
+
// When there are no column attributes, use spanSize to merge identical aggregator labels.
|
|
832
|
+
var colSpan = void 0;
|
|
833
|
+
if (hasColumnAttributes) {
|
|
834
|
+
// Each aggregator appears once per column group, so colSpan is always 1
|
|
835
|
+
// This ensures aggregator headers are listed in each column group and align
|
|
836
|
+
// correctly with the column groups above (which have colSpan = number of aggregators)
|
|
837
|
+
colSpan = 1;
|
|
838
|
+
} else {
|
|
839
|
+
// Use spanSize to merge identical aggregator labels when there are no column attributes
|
|
840
|
+
colSpan = spanSize(colKeyValues, idx, aggIndex);
|
|
841
|
+
// If spanSize returned -1 it means this cell is merged into a previous one
|
|
842
|
+
if (colSpan === -1) {
|
|
843
|
+
return null;
|
|
844
|
+
}
|
|
487
845
|
}
|
|
488
|
-
}
|
|
489
846
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
847
|
+
// When there are column attributes, rowSpan should account for the row header row
|
|
848
|
+
// When there are no column attributes, rowSpan is 1
|
|
849
|
+
var rowSpan = hasColumnAttributes && rowAttrsToRender.length !== 0 ? 1 : 1;
|
|
493
850
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
851
|
+
return _react2.default.createElement(
|
|
852
|
+
'th',
|
|
853
|
+
{
|
|
854
|
+
className: 'pvtColLabel',
|
|
855
|
+
key: 'agg-label-' + colMeta.absoluteIndex,
|
|
856
|
+
colSpan: colSpan,
|
|
857
|
+
rowSpan: rowSpan
|
|
858
|
+
},
|
|
859
|
+
label
|
|
860
|
+
);
|
|
861
|
+
}),
|
|
862
|
+
renderColumnSpacer('right', rightColumnSpacerWidth)
|
|
863
|
+
);
|
|
505
864
|
};
|
|
506
865
|
|
|
507
866
|
var valueCellColors = function valueCellColors() {};
|
|
@@ -566,6 +925,52 @@ function makeRenderer() {
|
|
|
566
925
|
aggregationNameLookup[agg.key] = agg.aggregatorName;
|
|
567
926
|
});
|
|
568
927
|
|
|
928
|
+
// Lookup aggregationKey -> aggregation definition (to read `vals`)
|
|
929
|
+
var aggregationByKey = {};
|
|
930
|
+
aggregations.forEach(function (agg) {
|
|
931
|
+
aggregationByKey[agg.key] = agg;
|
|
932
|
+
});
|
|
933
|
+
|
|
934
|
+
// Find the group label for an aggregation. rowGroupConfig `match` is
|
|
935
|
+
// compared against the aggregation's `vals` (the field names it works
|
|
936
|
+
// on, e.g. ['Employee Ref']). Falls back to label / aggregatorName.
|
|
937
|
+
var getAggregationGroup = function getAggregationGroup(aggregationKey) {
|
|
938
|
+
var agg = aggregationByKey[aggregationKey];
|
|
939
|
+
if (!agg) {
|
|
940
|
+
return null;
|
|
941
|
+
}
|
|
942
|
+
var vals = Array.isArray(agg.vals) ? agg.vals : [];
|
|
943
|
+
for (var k = 0; k < vals.length; k++) {
|
|
944
|
+
if (groupLookup[vals[k]]) {
|
|
945
|
+
return groupLookup[vals[k]];
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
return groupLookup[agg.label] || groupLookup[agg.aggregatorName] || null;
|
|
949
|
+
};
|
|
950
|
+
|
|
951
|
+
// Group label cells for the aggregation columns (column aggregation mode).
|
|
952
|
+
// Each column renders its own <th>, so the label repeats on every column.
|
|
953
|
+
var renderAggregatorGroupCells = function renderAggregatorGroupCells() {
|
|
954
|
+
return _react2.default.createElement(
|
|
955
|
+
_react2.default.Fragment,
|
|
956
|
+
null,
|
|
957
|
+
renderColumnSpacer('left', leftColumnSpacerWidth),
|
|
958
|
+
columnMeta.map(function (colMeta) {
|
|
959
|
+
var group = getAggregationGroup(colMeta.aggregationKey);
|
|
960
|
+
return _react2.default.createElement(
|
|
961
|
+
'th',
|
|
962
|
+
{
|
|
963
|
+
key: 'aggGrp' + colMeta.absoluteIndex
|
|
964
|
+
// eslint-disable-next-line no-undefined
|
|
965
|
+
, style: group ? groupLabelStyle : undefined
|
|
966
|
+
},
|
|
967
|
+
group || ''
|
|
968
|
+
);
|
|
969
|
+
}),
|
|
970
|
+
renderColumnSpacer('right', rightColumnSpacerWidth)
|
|
971
|
+
);
|
|
972
|
+
};
|
|
973
|
+
|
|
569
974
|
// Helper function to get cell style with conditional formatting
|
|
570
975
|
var getCellStyle = function getCellStyle(value) {
|
|
571
976
|
var heatmapStyle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
@@ -713,41 +1118,41 @@ function makeRenderer() {
|
|
|
713
1118
|
|
|
714
1119
|
var handleColSort = function handleColSort(attr, e) {
|
|
715
1120
|
e.stopPropagation();
|
|
716
|
-
if (
|
|
717
|
-
var currentSort =
|
|
1121
|
+
if (_this5.props.onColSort) {
|
|
1122
|
+
var currentSort = _this5.props.colSorts && _this5.props.colSorts[attr];
|
|
718
1123
|
var nextSort = 'ASC';
|
|
719
1124
|
if (currentSort === 'ASC') {
|
|
720
1125
|
nextSort = 'DESC';
|
|
721
1126
|
} else if (currentSort === 'DESC') {
|
|
722
1127
|
nextSort = null;
|
|
723
1128
|
}
|
|
724
|
-
|
|
1129
|
+
_this5.props.onColSort(attr, nextSort);
|
|
725
1130
|
}
|
|
726
1131
|
};
|
|
727
1132
|
|
|
728
1133
|
var handleRowSort = function handleRowSort(attr, e) {
|
|
729
1134
|
e.stopPropagation();
|
|
730
|
-
if (
|
|
731
|
-
var currentSort =
|
|
1135
|
+
if (_this5.props.onRowSort) {
|
|
1136
|
+
var currentSort = _this5.props.rowSorts && _this5.props.rowSorts[attr];
|
|
732
1137
|
var nextSort = 'ASC';
|
|
733
1138
|
if (currentSort === 'ASC') {
|
|
734
1139
|
nextSort = 'DESC';
|
|
735
1140
|
} else if (currentSort === 'DESC') {
|
|
736
1141
|
nextSort = null;
|
|
737
1142
|
}
|
|
738
|
-
|
|
1143
|
+
_this5.props.onRowSort(attr, nextSort);
|
|
739
1144
|
}
|
|
740
1145
|
};
|
|
741
1146
|
|
|
742
1147
|
var getSortButton = function getSortButton(attr, isCol) {
|
|
743
|
-
var currentSort = isCol ?
|
|
1148
|
+
var currentSort = isCol ? _this5.props.colSorts && _this5.props.colSorts[attr] : _this5.props.rowSorts && _this5.props.rowSorts[attr];
|
|
744
1149
|
var handleSort = isCol ? handleColSort : handleRowSort;
|
|
745
1150
|
var sortIcon = '';
|
|
746
1151
|
if (currentSort !== null) {
|
|
747
1152
|
if (isCol) {
|
|
748
|
-
sortIcon =
|
|
1153
|
+
sortIcon = _this5.props.colSortIcons[currentSort] || _this5.props.colSortIcons.DEFAULT;
|
|
749
1154
|
} else {
|
|
750
|
-
sortIcon =
|
|
1155
|
+
sortIcon = _this5.props.rowSortIcons[currentSort] || _this5.props.rowSortIcons.DEFAULT;
|
|
751
1156
|
}
|
|
752
1157
|
}
|
|
753
1158
|
return _react2.default.createElement(
|
|
@@ -766,10 +1171,29 @@ function makeRenderer() {
|
|
|
766
1171
|
|
|
767
1172
|
var totalRowAggregations = isColumnAggregationMode ? [primaryAggregation] : hasMultipleAggregators ? aggregations : [primaryAggregation];
|
|
768
1173
|
var totalsLabelText = 'Totals';
|
|
1174
|
+
this.rowCount = totalRowCount;
|
|
1175
|
+
this.columnCount = totalColumnCount;
|
|
1176
|
+
this.leadingColumnCount = rowAttrsToRender.length + (hasNumberColumn ? 1 : 0) + (showTotalsColumn && colAttrsToRender.length !== 0 && rowAttrsToRender.length !== 0 ? 1 : 0);
|
|
1177
|
+
var visibleStart = isRowVirtualized ? Math.min(this.state.start, totalRowCount) : 0;
|
|
1178
|
+
var visibleEnd = isRowVirtualized ? Math.min(Math.max(this.state.end, visibleStart), totalRowCount) : totalRowCount;
|
|
1179
|
+
var viewportKey = isVirtualized ? this.getViewportKey() : null;
|
|
1180
|
+
var viewportReady = viewportKey !== null && this.state.viewportKey === viewportKey && this.state.start === visibleStart && this.state.end === visibleEnd && this.state.columnStart === visibleColumnStart && this.state.columnEnd === visibleColumnEnd && this.state.columnTotals !== null && this.state.rows !== null;
|
|
1181
|
+
var isViewportLoading = viewportKey !== null && !viewportReady;
|
|
1182
|
+
var viewportColumnTotals = this.state.columnTotals || {};
|
|
1183
|
+
var visibleRows = isViewportLoading ? [] : viewportKey !== null ? this.state.rows : (0, _pivotCompute.computePivotViewport)({ rowKeys: baseRowKeys, aggregations: aggregations }, visibleStart, visibleEnd, isColumnAggregationMode, visibleColumnStart, visibleColumnEnd).rows;
|
|
1184
|
+
var virtualColumnCount = rowAttrsToRender.length + columnMeta.length + (leftColumnSpacerWidth > 0 ? 1 : 0) + (rightColumnSpacerWidth > 0 ? 1 : 0) + (hasNumberColumn ? 1 : 0) + (showTotalsColumn ? 1 : 0);
|
|
769
1185
|
|
|
770
1186
|
return _react2.default.createElement(
|
|
771
1187
|
'table',
|
|
772
|
-
{
|
|
1188
|
+
{
|
|
1189
|
+
className: 'pvtTable' + (isVirtualized ? ' pvtVirtualized' : '') + ('' + (isColumnVirtualized ? ' pvtVirtualColumns' : '')),
|
|
1190
|
+
'data-pvt-virtualized': isVirtualized ? 'true' : null,
|
|
1191
|
+
ref: function ref(element) {
|
|
1192
|
+
if (element) {
|
|
1193
|
+
pivotTablePropsByElement.set(element, _this5.props);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
},
|
|
773
1197
|
_react2.default.createElement(
|
|
774
1198
|
'thead',
|
|
775
1199
|
null,
|
|
@@ -778,7 +1202,7 @@ function makeRenderer() {
|
|
|
778
1202
|
'tr',
|
|
779
1203
|
{ key: 'colAttr' + j },
|
|
780
1204
|
hasNumberColumn && j === 0 && renderNumberHeaderCell(),
|
|
781
|
-
shouldRenderRowHeaderPlaceholder && (isColumnAggregationMode || j === 0) && !(isColumnAggregationMode && hasColumnAttributes && rowAttrsToRender.length === 1) && (hasHeaderGroup && j === 0 && !isColumnAggregationMode ? renderGroupSegments(colAttrsToRender.length
|
|
1205
|
+
shouldRenderRowHeaderPlaceholder && (isColumnAggregationMode || j === 0) && !(isColumnAggregationMode && hasColumnAttributes && rowAttrsToRender.length === 1) && (hasHeaderGroup && j === 0 && !isColumnAggregationMode ? renderGroupSegments(colAttrsToRender.length) : _react2.default.createElement('th', {
|
|
782
1206
|
colSpan: isColumnAggregationMode && hasColumnAttributes ? rowAttrsToRender.length - 1 : rowAttrsToRender.length,
|
|
783
1207
|
rowSpan: isColumnAggregationMode && hasColumnAttributes ? 1 : colAttrsToRender.length
|
|
784
1208
|
})),
|
|
@@ -788,6 +1212,7 @@ function makeRenderer() {
|
|
|
788
1212
|
c,
|
|
789
1213
|
colAttrs.includes(c) && getSortButton(c, true)
|
|
790
1214
|
) : null,
|
|
1215
|
+
renderColumnSpacer('left', leftColumnSpacerWidth),
|
|
791
1216
|
colKeyValues.map(function (colKey, i) {
|
|
792
1217
|
var x = spanSize(colKeyValues, i, j);
|
|
793
1218
|
|
|
@@ -800,13 +1225,14 @@ function makeRenderer() {
|
|
|
800
1225
|
'th',
|
|
801
1226
|
{
|
|
802
1227
|
className: 'pvtColLabel',
|
|
803
|
-
key: 'colKey' + i,
|
|
1228
|
+
key: 'colKey' + columnMeta[i].absoluteIndex,
|
|
804
1229
|
colSpan: x,
|
|
805
1230
|
rowSpan: j === colAttrsToRender.length - 1 && rowAttrsToRender.length !== 0 && !isColumnAggregationMode ? 2 : 1
|
|
806
1231
|
},
|
|
807
1232
|
formattedColLabel
|
|
808
1233
|
);
|
|
809
1234
|
}),
|
|
1235
|
+
renderColumnSpacer('right', rightColumnSpacerWidth),
|
|
810
1236
|
showTotalsColumn && j === 0 && _react2.default.createElement(
|
|
811
1237
|
'th',
|
|
812
1238
|
{
|
|
@@ -817,12 +1243,18 @@ function makeRenderer() {
|
|
|
817
1243
|
)
|
|
818
1244
|
);
|
|
819
1245
|
}),
|
|
1246
|
+
isColumnAggregationMode && hasColumnAttributes && hasHeaderGroup && _react2.default.createElement(
|
|
1247
|
+
'tr',
|
|
1248
|
+
null,
|
|
1249
|
+
renderGroupSegments(1),
|
|
1250
|
+
renderAggregatorGroupCells()
|
|
1251
|
+
),
|
|
820
1252
|
hasHeaderGroup && colAttrsToRender.length === 0 && rowAttrsToRender.length !== 0 && _react2.default.createElement(
|
|
821
1253
|
'tr',
|
|
822
1254
|
null,
|
|
823
1255
|
hasNumberColumn && renderNumberHeaderCell(),
|
|
824
|
-
renderGroupSegments(1
|
|
825
|
-
_react2.default.createElement('th', null)
|
|
1256
|
+
renderGroupSegments(1),
|
|
1257
|
+
isColumnAggregationMode ? renderAggregatorGroupCells() : _react2.default.createElement('th', null)
|
|
826
1258
|
),
|
|
827
1259
|
isColumnAggregationMode && hasColumnAttributes && _react2.default.createElement(
|
|
828
1260
|
'tr',
|
|
@@ -863,20 +1295,61 @@ function makeRenderer() {
|
|
|
863
1295
|
),
|
|
864
1296
|
_react2.default.createElement(
|
|
865
1297
|
'tbody',
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
1298
|
+
{ ref: this.bodyRef },
|
|
1299
|
+
isRowVirtualized && visibleStart > 0 && _react2.default.createElement(
|
|
1300
|
+
'tr',
|
|
1301
|
+
{ className: 'pvtVirtualSpacer', 'aria-hidden': 'true' },
|
|
1302
|
+
_react2.default.createElement('td', {
|
|
1303
|
+
colSpan: virtualColumnCount,
|
|
1304
|
+
style: {
|
|
1305
|
+
height: visibleStart * VIRTUAL_ROW_HEIGHT,
|
|
1306
|
+
padding: 0,
|
|
1307
|
+
border: 0
|
|
1308
|
+
}
|
|
1309
|
+
})
|
|
1310
|
+
),
|
|
1311
|
+
isViewportLoading && _react2.default.createElement(
|
|
1312
|
+
'tr',
|
|
1313
|
+
{ className: 'pvtVirtualLoading', 'aria-hidden': 'true' },
|
|
1314
|
+
_react2.default.createElement('td', {
|
|
1315
|
+
colSpan: virtualColumnCount,
|
|
1316
|
+
style: {
|
|
1317
|
+
height: (visibleEnd - visibleStart) * VIRTUAL_ROW_HEIGHT
|
|
1318
|
+
}
|
|
1319
|
+
})
|
|
1320
|
+
),
|
|
1321
|
+
isVirtualized && this.overlayBounds && (this.state.scrollPending || isViewportLoading) && _react2.default.createElement(
|
|
1322
|
+
'tr',
|
|
1323
|
+
{ className: 'pvtVirtualOverlayRow' },
|
|
1324
|
+
_react2.default.createElement(
|
|
1325
|
+
'td',
|
|
1326
|
+
{ colSpan: virtualColumnCount },
|
|
1327
|
+
_react2.default.createElement(
|
|
1328
|
+
'div',
|
|
1329
|
+
{
|
|
1330
|
+
className: 'pvtLoadingOverlay pvtVirtualScrollOverlay',
|
|
1331
|
+
role: 'status',
|
|
1332
|
+
style: this.overlayBounds
|
|
1333
|
+
},
|
|
1334
|
+
_react2.default.createElement(PivotLoadingContent, null)
|
|
1335
|
+
)
|
|
1336
|
+
)
|
|
1337
|
+
),
|
|
1338
|
+
visibleRows.map(function (rowMeta, visibleIndex) {
|
|
1339
|
+
var i = visibleStart + visibleIndex;
|
|
1340
|
+
var hasViewportValues = rowMeta.cells !== null;
|
|
1341
|
+
var totalAggregator = hasViewportValues ? pivotData.getPrecomputedAggregator(rowMeta.rowTotal, rowMeta.aggregationKey) : pivotData.getAggregator(rowMeta.actualKey, [], rowMeta.aggregationKey);
|
|
869
1342
|
var displayKey = rowMeta.displayKey;
|
|
870
1343
|
return _react2.default.createElement(
|
|
871
1344
|
'tr',
|
|
872
|
-
{ key: 'rowKeyRow' + i },
|
|
1345
|
+
{ className: 'pvtDataRow', key: 'rowKeyRow' + i },
|
|
873
1346
|
hasNumberColumn && _react2.default.createElement(
|
|
874
1347
|
'th',
|
|
875
1348
|
{ className: 'pvtRowNumber', key: 'rowNumber' + i },
|
|
876
1349
|
i + 1
|
|
877
1350
|
),
|
|
878
1351
|
displayKey.map(function (txt, j) {
|
|
879
|
-
var x =
|
|
1352
|
+
var x = rowMeta.spans[j];
|
|
880
1353
|
if (x === -1) {
|
|
881
1354
|
return null;
|
|
882
1355
|
}
|
|
@@ -893,22 +1366,24 @@ function makeRenderer() {
|
|
|
893
1366
|
formattedTxt
|
|
894
1367
|
);
|
|
895
1368
|
}),
|
|
896
|
-
|
|
1369
|
+
renderColumnSpacer('left', leftColumnSpacerWidth, 'td'),
|
|
1370
|
+
columnMeta.map(function (colMeta) {
|
|
897
1371
|
var aggregationKeyForCell = isColumnAggregationMode ? colMeta.aggregationKey : rowMeta.aggregationKey;
|
|
898
|
-
var aggregator = pivotData.getAggregator(rowMeta.actualKey, colMeta.actualKey, aggregationKeyForCell);
|
|
1372
|
+
var aggregator = hasViewportValues ? pivotData.getPrecomputedAggregator(rowMeta.cells[colMeta.actualKey.join(FLAT_KEY_SEPARATOR)], aggregationKeyForCell) : pivotData.getAggregator(rowMeta.actualKey, colMeta.actualKey, aggregationKeyForCell);
|
|
899
1373
|
var value = aggregator.value();
|
|
900
1374
|
var heatmapStyle = valueCellColors(rowMeta.actualKey, colMeta.actualKey, value) || {};
|
|
901
1375
|
return _react2.default.createElement(
|
|
902
1376
|
'td',
|
|
903
1377
|
{
|
|
904
1378
|
className: 'pvtVal',
|
|
905
|
-
key: 'pvtVal' + i + '-' +
|
|
1379
|
+
key: 'pvtVal' + i + '-' + colMeta.absoluteIndex,
|
|
906
1380
|
onClick: getClickHandler && getClickHandler(value, rowMeta.actualKey, colMeta.actualKey),
|
|
907
1381
|
style: getCellStyle(value, heatmapStyle)
|
|
908
1382
|
},
|
|
909
1383
|
formatCellValue(value, aggregator, aggregationKeyForCell)
|
|
910
1384
|
);
|
|
911
1385
|
}),
|
|
1386
|
+
renderColumnSpacer('right', rightColumnSpacerWidth, 'td'),
|
|
912
1387
|
showTotalsColumn && _react2.default.createElement(
|
|
913
1388
|
'td',
|
|
914
1389
|
{
|
|
@@ -920,6 +1395,18 @@ function makeRenderer() {
|
|
|
920
1395
|
)
|
|
921
1396
|
);
|
|
922
1397
|
}),
|
|
1398
|
+
isRowVirtualized && visibleEnd < totalRowCount && _react2.default.createElement(
|
|
1399
|
+
'tr',
|
|
1400
|
+
{ className: 'pvtVirtualSpacer', 'aria-hidden': 'true' },
|
|
1401
|
+
_react2.default.createElement('td', {
|
|
1402
|
+
colSpan: virtualColumnCount,
|
|
1403
|
+
style: {
|
|
1404
|
+
height: (totalRowCount - visibleEnd) * VIRTUAL_ROW_HEIGHT,
|
|
1405
|
+
padding: 0,
|
|
1406
|
+
border: 0
|
|
1407
|
+
}
|
|
1408
|
+
})
|
|
1409
|
+
),
|
|
923
1410
|
totalRowAggregations.map(function (agg) {
|
|
924
1411
|
var grandTotalAggregator = pivotData.getAggregator([], [], isColumnAggregationMode ? primaryAggregation.key : agg.key);
|
|
925
1412
|
var totalLabel = hasMultipleAggregators && !isColumnAggregationMode ? 'Totals \u2013 ' + (agg.label || agg.aggregatorName) : totalsLabelText;
|
|
@@ -934,20 +1421,23 @@ function makeRenderer() {
|
|
|
934
1421
|
},
|
|
935
1422
|
totalLabel
|
|
936
1423
|
),
|
|
937
|
-
|
|
938
|
-
|
|
1424
|
+
renderColumnSpacer('left', leftColumnSpacerWidth, 'td'),
|
|
1425
|
+
columnMeta.map(function (colMeta) {
|
|
1426
|
+
var flatColKey = colMeta.actualKey.join(FLAT_KEY_SEPARATOR);
|
|
1427
|
+
var totalAggregator = viewportKey !== null ? pivotData.getPrecomputedAggregator(viewportColumnTotals[flatColKey], isColumnAggregationMode ? colMeta.aggregationKey : agg.key) : pivotData.getAggregator([], colMeta.actualKey, isColumnAggregationMode ? colMeta.aggregationKey : agg.key);
|
|
939
1428
|
var totalValue = totalAggregator.value();
|
|
940
1429
|
return _react2.default.createElement(
|
|
941
1430
|
'td',
|
|
942
1431
|
{
|
|
943
1432
|
className: 'pvtTotal',
|
|
944
|
-
key: 'total' + agg.key + '-' +
|
|
1433
|
+
key: 'total' + agg.key + '-' + colMeta.absoluteIndex,
|
|
945
1434
|
onClick: getClickHandler && getClickHandler(totalValue, [null], colMeta.actualKey),
|
|
946
1435
|
style: getCellStyle(totalValue, rowTotalColors(totalValue) || {})
|
|
947
1436
|
},
|
|
948
1437
|
formatCellValue(totalValue, totalAggregator, agg.key)
|
|
949
1438
|
);
|
|
950
1439
|
}),
|
|
1440
|
+
renderColumnSpacer('right', rightColumnSpacerWidth, 'td'),
|
|
951
1441
|
showTotalsColumn && _react2.default.createElement(
|
|
952
1442
|
'td',
|
|
953
1443
|
{
|
|
@@ -962,6 +1452,25 @@ function makeRenderer() {
|
|
|
962
1452
|
)
|
|
963
1453
|
);
|
|
964
1454
|
}
|
|
1455
|
+
}], [{
|
|
1456
|
+
key: 'getDerivedStateFromProps',
|
|
1457
|
+
value: function getDerivedStateFromProps(nextProps, previousState) {
|
|
1458
|
+
var nextViewportKey = _getViewportKeyForProps(nextProps);
|
|
1459
|
+
if (nextViewportKey === previousState.sourceViewportKey) {
|
|
1460
|
+
return null;
|
|
1461
|
+
}
|
|
1462
|
+
return {
|
|
1463
|
+
start: 0,
|
|
1464
|
+
end: INITIAL_ROW_WINDOW_END,
|
|
1465
|
+
rows: null,
|
|
1466
|
+
columnStart: 0,
|
|
1467
|
+
columnEnd: INITIAL_COLUMN_WINDOW_END,
|
|
1468
|
+
columnTotals: null,
|
|
1469
|
+
viewportKey: null,
|
|
1470
|
+
sourceViewportKey: nextViewportKey,
|
|
1471
|
+
scrollPending: false
|
|
1472
|
+
};
|
|
1473
|
+
}
|
|
965
1474
|
}]);
|
|
966
1475
|
|
|
967
1476
|
return TableRenderer;
|
|
@@ -1008,6 +1517,8 @@ function makeRenderer() {
|
|
|
1008
1517
|
// rendered before the row attribute columns.
|
|
1009
1518
|
TableRenderer.defaultProps.showNumericalOrder = false;
|
|
1010
1519
|
TableRenderer.propTypes.showNumericalOrder = _propTypes2.default.bool;
|
|
1520
|
+
TableRenderer.defaultProps.virtualizeRows = false;
|
|
1521
|
+
TableRenderer.propTypes.virtualizeRows = _propTypes2.default.bool;
|
|
1011
1522
|
return TableRenderer;
|
|
1012
1523
|
}
|
|
1013
1524
|
|