@hrforte/react-pivottable 2.2.0 → 2.2.1
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 +13 -1
- package/dist/PivotTableUI.js +4 -4
- package/dist/PivotTableUI.js.map +1 -1
- package/dist/TableRenderers.js +35 -1
- package/dist/TableRenderers.js.map +1 -1
- package/dist/__tests__/PivotTableUI-processing-test.js +4 -4
- package/dist/__tests__/PivotTableUI-processing-test.js.map +1 -1
- package/dist/__tests__/TableRenderers-showNumericalOrder-test.js +178 -0
- package/dist/__tests__/TableRenderers-showNumericalOrder-test.js.map +1 -0
- package/dist/pivottable.css +3 -0
- package/package.json +1 -1
package/dist/TableRenderers.js
CHANGED
|
@@ -398,6 +398,28 @@ function makeRenderer() {
|
|
|
398
398
|
};
|
|
399
399
|
// --- End row group header ---
|
|
400
400
|
|
|
401
|
+
// --- Optional "No." column (showNumericalOrder) ---
|
|
402
|
+
// When enabled every data row is prefixed with its 1-based index, in a
|
|
403
|
+
// column labelled "No." placed before the row attribute columns.
|
|
404
|
+
var showNumericalOrder = Boolean(this.props.showNumericalOrder);
|
|
405
|
+
var hasNumberColumn = showNumericalOrder && (rowAttrsToRender.length !== 0 || colAttrsToRender.length !== 0);
|
|
406
|
+
var numberColumnLabel = 'No.';
|
|
407
|
+
var renderedAggregationHeaderRow = isColumnAggregationMode && hasColumnAttributes;
|
|
408
|
+
// The "No." header cell is rendered in the first header row and spans
|
|
409
|
+
// every header row, so the repeated header rows (column attributes,
|
|
410
|
+
// 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);
|
|
412
|
+
var numberColumnInGroupRow = hasHeaderGroup && colAttrsToRender.length === 0 && rowAttrsToRender.length !== 0;
|
|
413
|
+
var renderNumberHeaderCell = function renderNumberHeaderCell() {
|
|
414
|
+
var rowSpan = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : numberColumnHeaderRowSpan;
|
|
415
|
+
return _react2.default.createElement(
|
|
416
|
+
'th',
|
|
417
|
+
{ className: 'pvtAxisLabel pvtRowNumber', rowSpan: rowSpan },
|
|
418
|
+
numberColumnLabel
|
|
419
|
+
);
|
|
420
|
+
};
|
|
421
|
+
// --- End "No." column ---
|
|
422
|
+
|
|
401
423
|
var rowKeys = pivotData.getRowKeys();
|
|
402
424
|
var baseRowKeys = hasMultipleAggregators && !isColumnAggregationMode && rowKeys.length === 0 ? [[]] : rowKeys;
|
|
403
425
|
var renderedRows = hasMultipleAggregators && !isColumnAggregationMode ? baseRowKeys.reduce(function (acc, rowKey) {
|
|
@@ -755,6 +777,7 @@ function makeRenderer() {
|
|
|
755
777
|
return _react2.default.createElement(
|
|
756
778
|
'tr',
|
|
757
779
|
{ key: 'colAttr' + j },
|
|
780
|
+
hasNumberColumn && j === 0 && renderNumberHeaderCell(),
|
|
758
781
|
shouldRenderRowHeaderPlaceholder && (isColumnAggregationMode || j === 0) && !(isColumnAggregationMode && hasColumnAttributes && rowAttrsToRender.length === 1) && (hasHeaderGroup && j === 0 && !isColumnAggregationMode ? renderGroupSegments(colAttrsToRender.length, headerGroupExtraSpan) : _react2.default.createElement('th', {
|
|
759
782
|
colSpan: isColumnAggregationMode && hasColumnAttributes ? rowAttrsToRender.length - 1 : rowAttrsToRender.length,
|
|
760
783
|
rowSpan: isColumnAggregationMode && hasColumnAttributes ? 1 : colAttrsToRender.length
|
|
@@ -797,6 +820,7 @@ function makeRenderer() {
|
|
|
797
820
|
hasHeaderGroup && colAttrsToRender.length === 0 && rowAttrsToRender.length !== 0 && _react2.default.createElement(
|
|
798
821
|
'tr',
|
|
799
822
|
null,
|
|
823
|
+
hasNumberColumn && renderNumberHeaderCell(),
|
|
800
824
|
renderGroupSegments(1, headerGroupExtraSpan),
|
|
801
825
|
_react2.default.createElement('th', null)
|
|
802
826
|
),
|
|
@@ -818,6 +842,7 @@ function makeRenderer() {
|
|
|
818
842
|
rowAttrsToRender.length !== 0 && !(isColumnAggregationMode && hasColumnAttributes) && _react2.default.createElement(
|
|
819
843
|
'tr',
|
|
820
844
|
null,
|
|
845
|
+
hasNumberColumn && colAttrsToRender.length === 0 && !numberColumnInGroupRow && renderNumberHeaderCell(),
|
|
821
846
|
rowAttrsToRender.map(function (r, i) {
|
|
822
847
|
var isRowAttr = i < rowAttrs.length;
|
|
823
848
|
var attr = isRowAttr ? rowAttrs[i] : null;
|
|
@@ -845,6 +870,11 @@ function makeRenderer() {
|
|
|
845
870
|
return _react2.default.createElement(
|
|
846
871
|
'tr',
|
|
847
872
|
{ key: 'rowKeyRow' + i },
|
|
873
|
+
hasNumberColumn && _react2.default.createElement(
|
|
874
|
+
'th',
|
|
875
|
+
{ className: 'pvtRowNumber', key: 'rowNumber' + i },
|
|
876
|
+
i + 1
|
|
877
|
+
),
|
|
848
878
|
displayKey.map(function (txt, j) {
|
|
849
879
|
var x = spanSize(rowKeyValues, i, j);
|
|
850
880
|
if (x === -1) {
|
|
@@ -900,7 +930,7 @@ function makeRenderer() {
|
|
|
900
930
|
'th',
|
|
901
931
|
{
|
|
902
932
|
className: 'pvtTotalLabel',
|
|
903
|
-
colSpan: rowAttrsToRender.length + (colAttrs.length === 0 || isColumnAggregationMode && hasColumnAttributes ? 0 : 1)
|
|
933
|
+
colSpan: rowAttrsToRender.length + (colAttrs.length === 0 || isColumnAggregationMode && hasColumnAttributes ? 0 : 1) + (hasNumberColumn ? 1 : 0)
|
|
904
934
|
},
|
|
905
935
|
totalLabel
|
|
906
936
|
),
|
|
@@ -974,6 +1004,10 @@ function makeRenderer() {
|
|
|
974
1004
|
DESC: _propTypes2.default.node,
|
|
975
1005
|
DEFAULT: _propTypes2.default.node
|
|
976
1006
|
});
|
|
1007
|
+
// When true, a "No." column with the 1-based index of each data row is
|
|
1008
|
+
// rendered before the row attribute columns.
|
|
1009
|
+
TableRenderer.defaultProps.showNumericalOrder = false;
|
|
1010
|
+
TableRenderer.propTypes.showNumericalOrder = _propTypes2.default.bool;
|
|
977
1011
|
return TableRenderer;
|
|
978
1012
|
}
|
|
979
1013
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/TableRenderers.jsx"],"names":["applyCellFormatting","spanSize","arr","i","j","x","asc","end","noDraw","len","length","asc1","end1","stop","buildHeaderGroupSegments","rowAttrs","rowGroupConfig","attrToGroup","forEach","label","match","name","map","group","undefined","span","groupLabelStyle","textAlign","redColorScaleGenerator","values","min","Math","apply","max","nonRed","round","backgroundColor","evaluateCondition","value","condition","type","conditionValue","numValue","parseFloat","numConditionValue","isNaN","trim","valueStr","String","conditionValueStr","toLowerCase","includes","valueStr2","conditionValueStr2","getConditionalFormattingStyle","conditionalFormatting","Array","isArray","rules","rule","style","Object","assign","mergeStyles","styles","filter","s","containsSpecialCharacters","str","trimmed","pureNumericPattern","test","shouldSkipFormattingForAggregation","aggregatorName","skipFormattingAggregations","cellFormatting","defaultFormatter","isNumeric","isFinite","hasFormattingRules","some","format","numericValue","matchingRule","formatter","digitsAfterDecimal","decimalPlaces","thousandsSep","decimalSep","prefix","suffix","showOriginal","makeRenderer","opts","TableRenderer","pivotData","PivotData","props","colAttrs","cols","rows","aggregations","getAggregations","primaryAggregation","getPrimaryAggregation","hasMultipleAggregators","tableOptions","aggregationDisplayMode","isColumnAggregationMode","rowAttrsToRender","concat","colAttrsToRender","hasColumnAttributes","showTotalsColumn","shouldRenderRowHeaderPlaceholder","hasHeaderGroup","Boolean","headerGroupSegments","headerGroupExtraSpan","renderGroupSegments","rowSpan","extraSpan","cells","seg","idx","push","rowKeys","getRowKeys","baseRowKeys","renderedRows","reduce","acc","rowKey","displayKey","agg","actualKey","aggregationKey","key","rowKeyValues","r","colKeys","getColKeys","baseColKeys","columnMeta","colKey","colKeyValues","col","renderAggregatorHeaderCells","colMeta","aggIndex","colSpan","valueCellColors","rowTotalColors","colTotalColors","heatmapMode","colorScaleGenerator","tableColorScaleGenerator","rowTotalValues","getAggregator","colTotalValues","allValues","c","colorScale","v","rowColorScales","rowValues","colColorScales","colValues","aggregationNameLookup","getCellStyle","heatmapStyle","conditionalStyle","formatCellValue","aggregator","bind","formatLabel","txt","parsed","formatRowLabel","index","isLastElement","rowAttrsLength","getClickHandler","clickCallback","filters","keys","attr","e","handleColSort","stopPropagation","onColSort","currentSort","colSorts","nextSort","handleRowSort","onRowSort","rowSorts","getSortButton","isCol","handleSort","sortIcon","colSortIcons","DEFAULT","rowSortIcons","totalRowAggregations","totalsLabelText","formattedColLabel","isRowAttr","rowMeta","totalAggregator","formattedTxt","aggregationKeyForCell","grandTotalAggregator","totalLabel","totalValue","React","PureComponent","defaultProps","propTypes","PropTypes","func","object","objectOf","oneOf","arrayOf","shape","string","isRequired","ASC","DESC","node","TSVExportRenderer","safeRowKeys","safeColKeys","rowEntries","headerRow","slice","join","result","row","entry","unshift","width","window","innerWidth","height","innerHeight","Table"],"mappings":"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","file":"TableRenderers.js","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport {PivotData, numberFormat} from './Utilities';\n\n// helper function for setting row/col-span in pivotTableRenderer\nconst spanSize = function(arr, i, j) {\n let x;\n if (i !== 0) {\n let asc, end;\n let noDraw = true;\n for (\n x = 0, end = j, asc = end >= 0;\n asc ? x <= end : x >= end;\n asc ? x++ : x--\n ) {\n if (arr[i - 1][x] !== arr[i][x]) {\n noDraw = false;\n }\n }\n if (noDraw) {\n return -1;\n }\n }\n let len = 0;\n while (i + len < arr.length) {\n let asc1, end1;\n let stop = false;\n for (\n x = 0, end1 = j, asc1 = end1 >= 0;\n asc1 ? x <= end1 : x >= end1;\n asc1 ? x++ : x--\n ) {\n if (arr[i][x] !== arr[i + len][x]) {\n stop = true;\n }\n }\n if (stop) {\n break;\n }\n len++;\n }\n return len;\n};\n\n// ==> Calculate the positions for GroupSegments <==\nfunction buildHeaderGroupSegments(rowAttrs, rowGroupConfig) {\n const attrToGroup = {};\n (rowGroupConfig || []).forEach(({label, match}) => {\n match.forEach(name => {\n attrToGroup[name] = label;\n });\n });\n\n // Mỗi attribute luôn là 1 segment riêng — không gộp colSpan nữa,\n // để label nhóm (vd \"AAA\") hiện lặp lại trên từng cột con.\n return rowAttrs.map(name => {\n // eslint-disable-next-line no-undefined\n const group = attrToGroup[name] !== undefined ? attrToGroup[name] : null;\n return {group, span: 1};\n });\n}\n\n// Style cho ô có nhãn nhóm trong group header\nconst groupLabelStyle = {\n textAlign: 'center',\n};\n\nfunction redColorScaleGenerator(values) {\n const min = Math.min.apply(Math, values);\n const max = Math.max.apply(Math, values);\n return x => {\n // eslint-disable-next-line no-magic-numbers\n const nonRed = 255 - Math.round((255 * (x - min)) / (max - min));\n return {backgroundColor: `rgb(255,${nonRed},${nonRed})`};\n };\n}\n\n// Conditional formatting evaluation function\nfunction evaluateCondition(value, condition) {\n if (!condition || !condition.type) {\n return false;\n }\n\n const {type, value: conditionValue} = condition;\n const numValue = typeof value === 'number' ? value : parseFloat(value);\n const numConditionValue =\n typeof conditionValue === 'number'\n ? conditionValue\n : parseFloat(conditionValue);\n\n switch (type) {\n case 'greaterThan':\n return (\n !isNaN(numValue) &&\n !isNaN(numConditionValue) &&\n numValue > numConditionValue\n );\n case 'lessThan':\n return (\n !isNaN(numValue) &&\n !isNaN(numConditionValue) &&\n numValue < numConditionValue\n );\n case 'greaterThanOrEqual':\n return (\n !isNaN(numValue) &&\n !isNaN(numConditionValue) &&\n numValue >= numConditionValue\n );\n case 'lessThanOrEqual':\n return (\n !isNaN(numValue) &&\n !isNaN(numConditionValue) &&\n numValue <= numConditionValue\n );\n case 'equal':\n if (typeof value === 'string' && typeof conditionValue === 'string') {\n return value === conditionValue;\n }\n return (\n !isNaN(numValue) &&\n !isNaN(numConditionValue) &&\n numValue === numConditionValue\n );\n case 'notEqual':\n if (typeof value === 'string' && typeof conditionValue === 'string') {\n return value !== conditionValue;\n }\n return (\n isNaN(numValue) ||\n isNaN(numConditionValue) ||\n numValue !== numConditionValue\n );\n case 'empty':\n // Check for null, undefined, empty string, whitespace-only strings, or NaN\n // eslint-disable-next-line no-undefined\n if (value === null || value === undefined) {\n return true;\n }\n if (typeof value === 'string') {\n return value.trim() === '';\n }\n if (typeof value === 'number') {\n return isNaN(value);\n }\n return false;\n case 'notEmpty':\n // Check that value is not null, undefined, empty/whitespace string, or NaN\n // eslint-disable-next-line no-undefined\n if (value === null || value === undefined) {\n return false;\n }\n if (typeof value === 'string') {\n return value.trim() !== '';\n }\n if (typeof value === 'number') {\n return !isNaN(value);\n }\n // Other types (boolean, object, etc.) are considered not empty\n return true;\n // eslint-disable-next-line no-case-declarations\n case 'contains':\n // Convert both values to strings for comparison\n // This handles cases where values are numbers (from aggregators) or conditionValue is parsed as number\n const valueStr = String(value || '');\n const conditionValueStr = String(conditionValue || '');\n if (valueStr && conditionValueStr) {\n return valueStr.toLowerCase().includes(conditionValueStr.toLowerCase());\n }\n return false;\n // eslint-disable-next-line no-case-declarations\n case 'notContains':\n // Convert both values to strings for comparison\n // This handles cases where values are numbers (from aggregators) or conditionValue is parsed as number\n const valueStr2 = String(value || '');\n const conditionValueStr2 = String(conditionValue || '');\n if (valueStr2 && conditionValueStr2) {\n return !valueStr2\n .toLowerCase()\n .includes(conditionValueStr2.toLowerCase());\n }\n return true;\n default:\n return false;\n }\n}\n\n// Apply conditional formatting rules to a value\nfunction getConditionalFormattingStyle(value, conditionalFormatting) {\n if (!conditionalFormatting || !Array.isArray(conditionalFormatting.rules)) {\n return {};\n }\n\n // Evaluate rules in order, return first matching rule's style\n for (const rule of conditionalFormatting.rules) {\n if (evaluateCondition(value, rule.condition)) {\n // Return a copy of the style object to avoid mutations\n return rule.style ? Object.assign({}, rule.style) : {};\n }\n }\n\n return {};\n}\n\n// Merge styles, with conditional formatting taking precedence\nfunction mergeStyles(...styles) {\n return Object.assign({}, ...styles.filter(s => s && typeof s === 'object'));\n}\n\n// Helper function to check if a string contains special characters (like -, /, etc.)\n// This prevents formatting of date strings or formatted strings\n// Only pure numeric strings (with optional decimal point and minus sign) should be formatted\nfunction containsSpecialCharacters(str) {\n if (typeof str !== 'string') {\n return false;\n }\n const trimmed = str.trim();\n // Check if string contains any special characters that indicate it's not a raw number\n // Allow: digits, decimal point, minus sign at start, plus sign at start, spaces\n // Disallow: hyphens in middle, slashes, and other special characters\n const pureNumericPattern = /^-?\\d*\\.?\\d+$/;\n return !pureNumericPattern.test(trimmed);\n}\n\n// Helper function to check if an aggregation should skip formatting\n// Aggregations like Count, First, Last should not be formatted\n// Aggregations like Sum, Average should be formatted\nfunction shouldSkipFormattingForAggregation(aggregatorName) {\n if (!aggregatorName) {\n return false;\n }\n\n const name = aggregatorName.toLowerCase();\n // Skip formatting for these aggregation types\n const skipFormattingAggregations = [\n 'count',\n 'count unique values',\n 'list unique values',\n 'first',\n 'last',\n 'minimum',\n 'maximum',\n ];\n return skipFormattingAggregations.includes(name);\n}\n\n// Apply cell formatting rules to a value\nexport function applyCellFormatting(\n value,\n cellFormatting,\n defaultFormatter,\n aggregatorName = null\n) {\n // Don't format if aggregation type should skip formatting (e.g., Count, First, Last)\n // Only use defaultFormatter if value is numeric, otherwise return as-is\n const isNumeric =\n (typeof value === 'number' && !isNaN(value) && isFinite(value)) ||\n (typeof value === 'string' &&\n value.trim() !== '' &&\n !containsSpecialCharacters(value) &&\n !isNaN(parseFloat(value)) &&\n isFinite(parseFloat(value)));\n if (shouldSkipFormattingForAggregation(aggregatorName)) {\n if (isNumeric && defaultFormatter) {\n return defaultFormatter(value);\n }\n // Return raw value for non-numeric values (dates, strings, etc.)\n return value;\n }\n\n // If no cellFormatting rules, always use default formatter to return to original format\n // This ensures values return to their original format when cellFormatting is cleared\n // Check for all possible cases: null, undefined, empty object, empty rules array\n const hasFormattingRules =\n cellFormatting &&\n typeof cellFormatting === 'object' &&\n Array.isArray(cellFormatting.rules) &&\n cellFormatting.rules.length > 0 &&\n cellFormatting.rules.some(rule => rule && rule.format);\n\n if (!hasFormattingRules) {\n // When cellFormatting rules are cleared, return the raw value (not formatted)\n // This ensures all cells (regular, Totals, Aggregation) return to their original unformatted state\n // Return the raw numeric value for numbers, or the value as-is for other types\n if (isNumeric) {\n // Return raw numeric value without any formatting\n if (typeof value === 'number') {\n return value;\n }\n // For string numbers, return the parsed numeric value\n return parseFloat(value);\n }\n // For non-numeric values (dates, strings, etc.), return as-is\n return value;\n }\n\n // Don't format if it contains special characters (dates, formatted strings, etc.)\n // Only check this when cellFormatting rules exist\n if (containsSpecialCharacters(value)) {\n return defaultFormatter ? defaultFormatter(value) : String(value);\n }\n\n // Check if value is a number - only apply custom formatting to raw numbers\n // Handle both number type and string numbers (e.g., \"123.45\")\n // Exclude strings with special characters from formatting\n let numericValue = value;\n\n // Convert string numbers to actual numbers for formatting\n if (isNumeric && typeof value === 'string') {\n numericValue = parseFloat(value);\n }\n\n // Use the first rule (all rules apply to all values)\n const matchingRule = cellFormatting.rules[0];\n\n // If we found a matching rule and value is numeric, apply its formatting\n if (matchingRule && matchingRule.format && isNumeric) {\n const format = matchingRule.format;\n const formatter = numberFormat({\n digitsAfterDecimal: 'decimalPlaces' in format ? format.decimalPlaces : 2,\n thousandsSep: 'thousandsSep' in format ? format.thousandsSep : ',',\n decimalSep: 'decimalSep' in format ? format.decimalSep : '.',\n prefix: 'prefix' in format ? format.prefix : '',\n suffix: 'suffix' in format ? format.suffix : '',\n showOriginal: 'showOriginal' in format ? format.showOriginal : false,\n });\n return formatter(numericValue);\n }\n\n // Not numeric or no matching rule, use default formatter\n return defaultFormatter ? defaultFormatter(value) : String(value);\n}\n\nfunction makeRenderer(opts = {}) {\n class TableRenderer extends React.PureComponent {\n render() {\n const pivotData = new PivotData(this.props);\n const colAttrs = pivotData.props.cols;\n const rowAttrs = pivotData.props.rows;\n const aggregations = pivotData.getAggregations();\n const primaryAggregation = pivotData.getPrimaryAggregation();\n const hasMultipleAggregators = aggregations.length > 1;\n const tableOptions = this.props.tableOptions || {};\n const aggregationDisplayMode =\n tableOptions.aggregationDisplayMode === 'column' ? 'column' : 'row';\n const isColumnAggregationMode =\n aggregationDisplayMode === 'column' && hasMultipleAggregators;\n const rowAttrsToRender =\n hasMultipleAggregators && !isColumnAggregationMode\n ? rowAttrs.concat(['Values'])\n : rowAttrs;\n const colAttrsToRender = colAttrs;\n const hasColumnAttributes = colAttrsToRender.length > 0;\n const showTotalsColumn = !isColumnAggregationMode;\n const shouldRenderRowHeaderPlaceholder = rowAttrsToRender.length !== 0;\n\n // --- Row group header (rowGroupConfig) ---\n const rowGroupConfig = this.props.rowGroupConfig;\n const hasHeaderGroup = Boolean(rowGroupConfig && rowGroupConfig.length);\n const headerGroupSegments = hasHeaderGroup\n ? buildHeaderGroupSegments(rowAttrs, rowGroupConfig)\n : [];\n // extraSpan accounts for the synthetic \"Values\" column added when there\n // are multiple aggregators shown as rows; it isn't part of any group.\n const headerGroupExtraSpan = rowAttrsToRender.length - rowAttrs.length;\n const renderGroupSegments = (rowSpan, extraSpan = 0) => {\n const cells = headerGroupSegments.map((seg, idx) => (\n <th\n key={`hgSeg${idx}`}\n colSpan={seg.span}\n rowSpan={rowSpan}\n // eslint-disable-next-line no-undefined\n style={seg.group ? groupLabelStyle : undefined}\n >\n {seg.group || ''}\n </th>\n ));\n if (extraSpan > 0) {\n cells.push(\n <th key=\"hgSegExtra\" colSpan={extraSpan} rowSpan={rowSpan} />\n );\n }\n return cells;\n };\n // --- End row group header ---\n\n const rowKeys = pivotData.getRowKeys();\n const baseRowKeys =\n hasMultipleAggregators &&\n !isColumnAggregationMode &&\n rowKeys.length === 0\n ? [[]]\n : rowKeys;\n const renderedRows =\n hasMultipleAggregators && !isColumnAggregationMode\n ? baseRowKeys.reduce((acc, rowKey) => {\n aggregations.forEach(agg => {\n acc.push({\n displayKey: rowKey.concat([agg.label || agg.aggregatorName]),\n actualKey: rowKey,\n aggregationKey: agg.key,\n });\n });\n return acc;\n }, [])\n : baseRowKeys.map(rowKey => ({\n displayKey: rowKey,\n actualKey: rowKey,\n aggregationKey: primaryAggregation.key,\n }));\n const rowKeyValues = renderedRows.map(r => r.displayKey);\n const colKeys = pivotData.getColKeys();\n const baseColKeys =\n isColumnAggregationMode && colKeys.length === 0 ? [[]] : colKeys;\n const columnMeta = isColumnAggregationMode\n ? baseColKeys.reduce((acc, colKey) => {\n aggregations.forEach(agg => {\n acc.push({\n displayKey: colKey.concat([agg.label || agg.aggregatorName]),\n actualKey: colKey,\n aggregationKey: agg.key,\n });\n });\n return acc;\n }, [])\n : colKeys.map(colKey => ({\n displayKey: colKey,\n actualKey: colKey,\n aggregationKey: primaryAggregation.key,\n }));\n const colKeyValues = columnMeta.map(col => col.displayKey);\n\n const renderAggregatorHeaderCells = () =>\n columnMeta.map((colMeta, idx) => {\n const label = colMeta.displayKey[colMeta.displayKey.length - 1] || '';\n // Calculate colspan/rowspan so aggregator headers line up with column groups\n // aggregator index is the last element in displayKey (after column attrs)\n const aggIndex = colAttrsToRender.length;\n // When there are column attributes, each aggregator should appear once per column group,\n // so each aggregator header should have colSpan = 1.\n // When there are no column attributes, use spanSize to merge identical aggregator labels.\n let colSpan;\n if (hasColumnAttributes) {\n // Each aggregator appears once per column group, so colSpan is always 1\n // This ensures aggregator headers are listed in each column group and align\n // correctly with the column groups above (which have colSpan = number of aggregators)\n colSpan = 1;\n } else {\n // Use spanSize to merge identical aggregator labels when there are no column attributes\n colSpan = spanSize(colKeyValues, idx, aggIndex);\n // If spanSize returned -1 it means this cell is merged into a previous one\n if (colSpan === -1) {\n return null;\n }\n }\n\n // When there are column attributes, rowSpan should account for the row header row\n // When there are no column attributes, rowSpan is 1\n const rowSpan =\n hasColumnAttributes && rowAttrsToRender.length !== 0 ? 1 : 1;\n\n return (\n <th\n className=\"pvtColLabel\"\n key={`agg-label-${idx}`}\n colSpan={colSpan}\n rowSpan={rowSpan}\n >\n {label}\n </th>\n );\n });\n\n let valueCellColors = () => {};\n let rowTotalColors = () => {};\n let colTotalColors = () => {};\n if (opts.heatmapMode && !hasMultipleAggregators) {\n const colorScaleGenerator = this.props.tableColorScaleGenerator;\n const rowTotalValues = colKeys.map(x =>\n pivotData.getAggregator([], x, primaryAggregation.key).value()\n );\n rowTotalColors = colorScaleGenerator(rowTotalValues);\n const colTotalValues = rowKeys.map(x =>\n pivotData.getAggregator(x, [], primaryAggregation.key).value()\n );\n colTotalColors = colorScaleGenerator(colTotalValues);\n\n if (opts.heatmapMode === 'full') {\n const allValues = [];\n rowKeys.map(r =>\n colKeys.map(c =>\n allValues.push(\n pivotData.getAggregator(r, c, primaryAggregation.key).value()\n )\n )\n );\n const colorScale = colorScaleGenerator(allValues);\n valueCellColors = (r, c, v) => colorScale(v);\n } else if (opts.heatmapMode === 'row') {\n const rowColorScales = {};\n rowKeys.map(r => {\n const rowValues = colKeys.map(x =>\n pivotData.getAggregator(r, x, primaryAggregation.key).value()\n );\n rowColorScales[r] = colorScaleGenerator(rowValues);\n });\n valueCellColors = (r, c, v) => rowColorScales[r](v);\n } else if (opts.heatmapMode === 'col') {\n const colColorScales = {};\n colKeys.map(c => {\n const colValues = rowKeys.map(x =>\n pivotData.getAggregator(x, c, primaryAggregation.key).value()\n );\n colColorScales[c] = colorScaleGenerator(colValues);\n });\n valueCellColors = (r, c, v) => colColorScales[c](v);\n }\n }\n\n // Get conditional formatting from tableOptions\n const conditionalFormatting = tableOptions.conditionalFormatting || null;\n\n // Get cell formatting from tableOptions\n const cellFormatting = tableOptions.cellFormatting || null;\n\n // Create lookup map from aggregationKey to aggregatorName\n const aggregationNameLookup = {};\n aggregations.forEach(agg => {\n aggregationNameLookup[agg.key] = agg.aggregatorName;\n });\n\n // Helper function to get cell style with conditional formatting\n const getCellStyle = (value, heatmapStyle = {}) => {\n const conditionalStyle = getConditionalFormattingStyle(\n value,\n conditionalFormatting\n );\n return mergeStyles(heatmapStyle, conditionalStyle);\n };\n\n // Helper function to format cell value with cell formatting rules\n const formatCellValue = (value, aggregator, aggregationKey) => {\n const aggregatorName = aggregationKey\n ? aggregationNameLookup[aggregationKey]\n : null;\n\n return applyCellFormatting(\n value,\n cellFormatting,\n aggregator.format.bind(aggregator),\n aggregatorName\n );\n };\n\n // Helper function to format label text if it's numeric\n // Used for both row and column labels\n const formatLabel = txt => {\n // Check if txt is numeric (number or numeric string)\n // Also exclude 'null' string which is used for missing values\n if (txt === 'null' || txt === null || typeof txt === 'undefined') {\n return txt;\n }\n\n // Don't format if it contains special characters (dates, formatted strings, etc.)\n if (containsSpecialCharacters(txt)) {\n return txt;\n }\n\n // Check if txt is numeric (number or numeric string)\n // A string is numeric if it can be parsed as a finite number\n // Exclude strings with special characters from formatting\n let isNumeric = false;\n let numericValue = null;\n\n if (typeof txt === 'number') {\n isNumeric = !isNaN(txt) && isFinite(txt);\n if (isNumeric) {\n numericValue = txt;\n }\n } else if (\n typeof txt === 'string' &&\n txt.trim() !== '' &&\n txt !== 'null' &&\n !containsSpecialCharacters(txt)\n ) {\n const parsed = parseFloat(txt.trim());\n isNumeric = !isNaN(parsed) && isFinite(parsed);\n if (isNumeric) {\n numericValue = parsed;\n }\n }\n\n if (\n isNumeric &&\n numericValue !== null &&\n cellFormatting &&\n Array.isArray(cellFormatting.rules) &&\n cellFormatting.rules.length > 0\n ) {\n const matchingRule = cellFormatting.rules[0];\n if (matchingRule && matchingRule.format) {\n const format = matchingRule.format;\n const formatter = numberFormat({\n digitsAfterDecimal:\n 'decimalPlaces' in format ? format.decimalPlaces : 2,\n thousandsSep:\n 'thousandsSep' in format ? format.thousandsSep : ',',\n decimalSep: 'decimalSep' in format ? format.decimalSep : '.',\n prefix: 'prefix' in format ? format.prefix : '',\n suffix: 'suffix' in format ? format.suffix : '',\n showOriginal:\n 'showOriginal' in format ? format.showOriginal : false,\n });\n return formatter(numericValue);\n }\n }\n\n // Not numeric or no formatting rules, return as-is\n return txt;\n };\n\n // Helper function to format row label text if it's numeric\n // Only formats if it's a numeric value, not aggregation labels\n const formatRowLabel = (\n txt,\n index,\n isLastElement,\n hasMultipleAggregators,\n rowAttrsLength\n ) => {\n // Don't format the last element if it's an aggregation label (when multiple aggregators)\n // The last element is an aggregation label only if:\n // 1. There are multiple aggregators\n // 2. AND it's beyond the row attributes (index >= rowAttrsLength)\n if (\n hasMultipleAggregators &&\n isLastElement &&\n index >= rowAttrsLength\n ) {\n return txt;\n }\n\n return formatLabel(txt);\n };\n\n const getClickHandler =\n tableOptions && tableOptions.clickCallback\n ? (value, rowValues, colValues) => {\n const filters = {};\n for (const i of Object.keys(colAttrs || {})) {\n const attr = colAttrs[i];\n if (colValues[i] !== null) {\n filters[attr] = colValues[i];\n }\n }\n for (const i of Object.keys(rowAttrs || {})) {\n const attr = rowAttrs[i];\n if (rowValues[i] !== null) {\n filters[attr] = rowValues[i];\n }\n }\n return e =>\n tableOptions.clickCallback(e, value, filters, pivotData);\n }\n : null;\n\n const handleColSort = (attr, e) => {\n e.stopPropagation();\n if (this.props.onColSort) {\n const currentSort = this.props.colSorts && this.props.colSorts[attr];\n let nextSort = 'ASC';\n if (currentSort === 'ASC') {\n nextSort = 'DESC';\n } else if (currentSort === 'DESC') {\n nextSort = null;\n }\n this.props.onColSort(attr, nextSort);\n }\n };\n\n const handleRowSort = (attr, e) => {\n e.stopPropagation();\n if (this.props.onRowSort) {\n const currentSort = this.props.rowSorts && this.props.rowSorts[attr];\n let nextSort = 'ASC';\n if (currentSort === 'ASC') {\n nextSort = 'DESC';\n } else if (currentSort === 'DESC') {\n nextSort = null;\n }\n this.props.onRowSort(attr, nextSort);\n }\n };\n\n const getSortButton = (attr, isCol) => {\n const currentSort = isCol\n ? this.props.colSorts && this.props.colSorts[attr]\n : this.props.rowSorts && this.props.rowSorts[attr];\n const handleSort = isCol ? handleColSort : handleRowSort;\n let sortIcon = '';\n if (currentSort !== null) {\n if (isCol) {\n sortIcon =\n this.props.colSortIcons[currentSort] ||\n this.props.colSortIcons.DEFAULT;\n } else {\n sortIcon =\n this.props.rowSortIcons[currentSort] ||\n this.props.rowSortIcons.DEFAULT;\n }\n }\n return (\n <button\n type=\"button\"\n className=\"pvtSortButton\"\n onClick={e => handleSort(attr, e)}\n title={\n currentSort === 'ASC'\n ? 'Sort Descending'\n : currentSort === 'DESC'\n ? 'Clear Sort'\n : 'Sort Ascending'\n }\n >\n {sortIcon}\n </button>\n );\n };\n\n const totalRowAggregations = isColumnAggregationMode\n ? [primaryAggregation]\n : hasMultipleAggregators\n ? aggregations\n : [primaryAggregation];\n const totalsLabelText = 'Totals';\n\n return (\n <table className=\"pvtTable\">\n <thead>\n {colAttrsToRender.map(function(c, j) {\n return (\n <tr key={`colAttr${j}`}>\n {shouldRenderRowHeaderPlaceholder &&\n (isColumnAggregationMode || j === 0) &&\n !(\n isColumnAggregationMode &&\n hasColumnAttributes &&\n rowAttrsToRender.length === 1\n ) &&\n (hasHeaderGroup && j === 0 && !isColumnAggregationMode ? (\n renderGroupSegments(\n colAttrsToRender.length,\n headerGroupExtraSpan\n )\n ) : (\n <th\n colSpan={\n isColumnAggregationMode && hasColumnAttributes\n ? rowAttrsToRender.length - 1\n : rowAttrsToRender.length\n }\n rowSpan={\n isColumnAggregationMode && hasColumnAttributes\n ? 1\n : colAttrsToRender.length\n }\n />\n ))}\n {c ? (\n <th className=\"pvtAxisLabel\">\n {c}\n {colAttrs.includes(c) && getSortButton(c, true)}\n </th>\n ) : null}\n {colKeyValues.map(function(colKey, i) {\n const x = spanSize(colKeyValues, i, j);\n\n if (x === -1) {\n return null;\n }\n\n const formattedColLabel = formatLabel(colKey[j]);\n return (\n <th\n className=\"pvtColLabel\"\n key={`colKey${i}`}\n colSpan={x}\n rowSpan={\n j === colAttrsToRender.length - 1 &&\n rowAttrsToRender.length !== 0 &&\n !isColumnAggregationMode\n ? 2\n : 1\n }\n >\n {formattedColLabel}\n </th>\n );\n })}\n\n {showTotalsColumn && j === 0 && (\n <th\n className=\"pvtTotalLabel\"\n rowSpan={\n colAttrsToRender.length +\n (rowAttrsToRender.length === 0 ? 0 : 1)\n }\n >\n {totalsLabelText}\n </th>\n )}\n </tr>\n );\n })}\n\n {hasHeaderGroup &&\n colAttrsToRender.length === 0 &&\n rowAttrsToRender.length !== 0 && (\n <tr>\n {renderGroupSegments(1, headerGroupExtraSpan)}\n <th />\n </tr>\n )}\n\n {isColumnAggregationMode && hasColumnAttributes && (\n <tr>\n {rowAttrsToRender.length !== 0 &&\n rowAttrsToRender.map((r, i) => {\n const isRowAttr = i < rowAttrs.length;\n const attr = isRowAttr ? rowAttrs[i] : null;\n return (\n <th className=\"pvtAxisLabel\" key={`rowAttr-agg-${i}`}>\n {r}\n {isRowAttr && attr && getSortButton(attr, false)}\n </th>\n );\n })}\n {renderAggregatorHeaderCells()}\n </tr>\n )}\n\n {rowAttrsToRender.length !== 0 &&\n !(isColumnAggregationMode && hasColumnAttributes) && (\n <tr>\n {rowAttrsToRender.map((r, i) => {\n const isRowAttr = i < rowAttrs.length;\n const attr = isRowAttr ? rowAttrs[i] : null;\n return (\n <th className=\"pvtAxisLabel\" key={`rowAttr${i}`}>\n {r}\n {isRowAttr && attr && getSortButton(attr, false)}\n </th>\n );\n })}\n {isColumnAggregationMode && !hasColumnAttributes\n ? renderAggregatorHeaderCells()\n : null}\n {showTotalsColumn && (\n <th className=\"pvtTotalLabel\">\n {colAttrs.length === 0 ? totalsLabelText : null}\n </th>\n )}\n </tr>\n )}\n </thead>\n\n <tbody>\n {renderedRows.map(function(rowMeta, i) {\n const totalAggregator = pivotData.getAggregator(\n rowMeta.actualKey,\n [],\n rowMeta.aggregationKey\n );\n const displayKey = rowMeta.displayKey;\n return (\n <tr key={`rowKeyRow${i}`}>\n {displayKey.map(function(txt, j) {\n const x = spanSize(rowKeyValues, i, j);\n if (x === -1) {\n return null;\n }\n const isLastElement = j === displayKey.length - 1;\n const formattedTxt = formatRowLabel(\n txt,\n j,\n isLastElement,\n hasMultipleAggregators,\n rowAttrs.length\n );\n return (\n <th\n key={`rowKeyLabel${i}-${j}`}\n className=\"pvtRowLabel\"\n rowSpan={x}\n colSpan={\n showTotalsColumn &&\n j === rowAttrsToRender.length - 1 &&\n colAttrsToRender.length !== 0\n ? 2\n : 1\n }\n >\n {formattedTxt}\n </th>\n );\n })}\n {columnMeta.map(function(colMeta, j) {\n const aggregationKeyForCell = isColumnAggregationMode\n ? colMeta.aggregationKey\n : rowMeta.aggregationKey;\n const aggregator = pivotData.getAggregator(\n rowMeta.actualKey,\n colMeta.actualKey,\n aggregationKeyForCell\n );\n const value = aggregator.value();\n const heatmapStyle =\n valueCellColors(\n rowMeta.actualKey,\n colMeta.actualKey,\n value\n ) || {};\n return (\n <td\n className=\"pvtVal\"\n key={`pvtVal${i}-${j}`}\n onClick={\n getClickHandler &&\n getClickHandler(\n value,\n rowMeta.actualKey,\n colMeta.actualKey\n )\n }\n style={getCellStyle(value, heatmapStyle)}\n >\n {formatCellValue(\n value,\n aggregator,\n aggregationKeyForCell\n )}\n </td>\n );\n })}\n {showTotalsColumn && (\n <td\n className=\"pvtTotal\"\n onClick={\n getClickHandler &&\n getClickHandler(\n totalAggregator.value(),\n rowMeta.actualKey,\n [null]\n )\n }\n style={getCellStyle(\n totalAggregator.value(),\n colTotalColors(totalAggregator.value()) || {}\n )}\n >\n {formatCellValue(\n totalAggregator.value(),\n totalAggregator,\n rowMeta.aggregationKey\n )}\n </td>\n )}\n </tr>\n );\n })}\n\n {totalRowAggregations.map(function(agg) {\n const grandTotalAggregator = pivotData.getAggregator(\n [],\n [],\n isColumnAggregationMode ? primaryAggregation.key : agg.key\n );\n const totalLabel =\n hasMultipleAggregators && !isColumnAggregationMode\n ? `Totals – ${agg.label || agg.aggregatorName}`\n : totalsLabelText;\n return (\n <tr key={`totalRow-${agg.key}`}>\n <th\n className=\"pvtTotalLabel\"\n colSpan={\n rowAttrsToRender.length +\n (colAttrs.length === 0 ||\n (isColumnAggregationMode && hasColumnAttributes)\n ? 0\n : 1)\n }\n >\n {totalLabel}\n </th>\n\n {columnMeta.map(function(colMeta, i) {\n const totalAggregator = pivotData.getAggregator(\n [],\n colMeta.actualKey,\n isColumnAggregationMode ? colMeta.aggregationKey : agg.key\n );\n const totalValue = totalAggregator.value();\n return (\n <td\n className=\"pvtTotal\"\n key={`total${agg.key}-${i}`}\n onClick={\n getClickHandler &&\n getClickHandler(totalValue, [null], colMeta.actualKey)\n }\n style={getCellStyle(\n totalValue,\n rowTotalColors(totalValue) || {}\n )}\n >\n {formatCellValue(totalValue, totalAggregator, agg.key)}\n </td>\n );\n })}\n\n {showTotalsColumn && (\n <td\n onClick={\n getClickHandler &&\n getClickHandler(\n grandTotalAggregator.value(),\n [null],\n [null]\n )\n }\n className=\"pvtGrandTotal\"\n style={getCellStyle(grandTotalAggregator.value(), {})}\n >\n {formatCellValue(\n grandTotalAggregator.value(),\n grandTotalAggregator,\n isColumnAggregationMode\n ? primaryAggregation.key\n : agg.key\n )}\n </td>\n )}\n </tr>\n );\n })}\n </tbody>\n </table>\n );\n }\n }\n\n TableRenderer.defaultProps = PivotData.defaultProps;\n TableRenderer.propTypes = PivotData.propTypes;\n TableRenderer.defaultProps.tableColorScaleGenerator = redColorScaleGenerator;\n TableRenderer.defaultProps.tableOptions = {};\n TableRenderer.defaultProps.colSorts = {};\n TableRenderer.defaultProps.rowSorts = {};\n TableRenderer.defaultProps.rowGroupConfig = null;\n TableRenderer.propTypes.tableColorScaleGenerator = PropTypes.func;\n TableRenderer.propTypes.tableOptions = PropTypes.object;\n TableRenderer.propTypes.colSorts = PropTypes.objectOf(\n PropTypes.oneOf(['ASC', 'DESC'])\n );\n TableRenderer.propTypes.rowSorts = PropTypes.objectOf(\n PropTypes.oneOf(['ASC', 'DESC'])\n );\n TableRenderer.propTypes.onColSort = PropTypes.func;\n TableRenderer.propTypes.onRowSort = PropTypes.func;\n TableRenderer.propTypes.rowGroupConfig = PropTypes.arrayOf(\n PropTypes.shape({\n label: PropTypes.string.isRequired,\n match: PropTypes.arrayOf(PropTypes.string).isRequired,\n })\n );\n TableRenderer.defaultProps.colSortIcons = {\n ASC: '→',\n DESC: '←',\n DEFAULT: '↔',\n };\n TableRenderer.defaultProps.rowSortIcons = {\n ASC: '↑',\n DESC: '↓',\n DEFAULT: '⇅',\n };\n TableRenderer.propTypes.colSortIcons = PropTypes.shape({\n ASC: PropTypes.node,\n DESC: PropTypes.node,\n DEFAULT: PropTypes.node,\n });\n TableRenderer.propTypes.rowSortIcons = PropTypes.shape({\n ASC: PropTypes.node,\n DESC: PropTypes.node,\n DEFAULT: PropTypes.node,\n });\n return TableRenderer;\n}\n\nclass TSVExportRenderer extends React.PureComponent {\n render() {\n const pivotData = new PivotData(this.props);\n const rowAttrs = pivotData.props.rows;\n const aggregations = pivotData.getAggregations();\n const hasMultipleAggregators = aggregations.length > 1;\n const rowKeys = pivotData.getRowKeys();\n const colKeys = pivotData.getColKeys();\n const safeRowKeys = rowKeys.length === 0 ? [[]] : rowKeys;\n const safeColKeys = colKeys.length === 0 ? [[]] : colKeys;\n\n const rowEntries = hasMultipleAggregators\n ? safeRowKeys.reduce((acc, rowKey) => {\n aggregations.forEach(agg => {\n acc.push({rowKey, aggregationKey: agg.key, label: agg.label});\n });\n return acc;\n }, [])\n : safeRowKeys.map(rowKey => ({\n rowKey,\n aggregationKey: aggregations[0].key,\n label: aggregations[0].label || aggregations[0].aggregatorName,\n }));\n\n const headerRow = rowAttrs.slice();\n if (hasMultipleAggregators) {\n headerRow.push('Values');\n }\n if (safeColKeys.length === 1 && safeColKeys[0].length === 0) {\n headerRow.push(\n hasMultipleAggregators\n ? 'Value'\n : aggregations[0].label || aggregations[0].aggregatorName\n );\n } else {\n safeColKeys.map(c => headerRow.push(c.join('-')));\n }\n\n const result = rowEntries.map(entry => {\n const row = entry.rowKey.map(x => x);\n if (hasMultipleAggregators) {\n row.push(entry.label || '');\n }\n safeColKeys.map(colKey => {\n const v = pivotData\n .getAggregator(entry.rowKey, colKey, entry.aggregationKey)\n .value();\n row.push(v ? v : '');\n });\n return row;\n });\n\n result.unshift(headerRow);\n\n return (\n <textarea\n value={result.map(r => r.join('\\t')).join('\\n')}\n style={{width: window.innerWidth / 2, height: window.innerHeight / 2}}\n readOnly={true}\n />\n );\n }\n}\n\nTSVExportRenderer.defaultProps = PivotData.defaultProps;\nTSVExportRenderer.propTypes = PivotData.propTypes;\n\nexport default {\n Table: makeRenderer(),\n 'Table Heatmap': makeRenderer({heatmapMode: 'full'}),\n 'Table Col Heatmap': makeRenderer({heatmapMode: 'col'}),\n 'Table Row Heatmap': makeRenderer({heatmapMode: 'row'}),\n 'Exportable TSV': TSVExportRenderer,\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/TableRenderers.jsx"],"names":["applyCellFormatting","spanSize","arr","i","j","x","asc","end","noDraw","len","length","asc1","end1","stop","buildHeaderGroupSegments","rowAttrs","rowGroupConfig","attrToGroup","forEach","label","match","name","map","group","undefined","span","groupLabelStyle","textAlign","redColorScaleGenerator","values","min","Math","apply","max","nonRed","round","backgroundColor","evaluateCondition","value","condition","type","conditionValue","numValue","parseFloat","numConditionValue","isNaN","trim","valueStr","String","conditionValueStr","toLowerCase","includes","valueStr2","conditionValueStr2","getConditionalFormattingStyle","conditionalFormatting","Array","isArray","rules","rule","style","Object","assign","mergeStyles","styles","filter","s","containsSpecialCharacters","str","trimmed","pureNumericPattern","test","shouldSkipFormattingForAggregation","aggregatorName","skipFormattingAggregations","cellFormatting","defaultFormatter","isNumeric","isFinite","hasFormattingRules","some","format","numericValue","matchingRule","formatter","digitsAfterDecimal","decimalPlaces","thousandsSep","decimalSep","prefix","suffix","showOriginal","makeRenderer","opts","TableRenderer","pivotData","PivotData","props","colAttrs","cols","rows","aggregations","getAggregations","primaryAggregation","getPrimaryAggregation","hasMultipleAggregators","tableOptions","aggregationDisplayMode","isColumnAggregationMode","rowAttrsToRender","concat","colAttrsToRender","hasColumnAttributes","showTotalsColumn","shouldRenderRowHeaderPlaceholder","hasHeaderGroup","Boolean","headerGroupSegments","headerGroupExtraSpan","renderGroupSegments","rowSpan","extraSpan","cells","seg","idx","push","showNumericalOrder","hasNumberColumn","numberColumnLabel","renderedAggregationHeaderRow","numberColumnHeaderRowSpan","numberColumnInGroupRow","renderNumberHeaderCell","rowKeys","getRowKeys","baseRowKeys","renderedRows","reduce","acc","rowKey","displayKey","agg","actualKey","aggregationKey","key","rowKeyValues","r","colKeys","getColKeys","baseColKeys","columnMeta","colKey","colKeyValues","col","renderAggregatorHeaderCells","colMeta","aggIndex","colSpan","valueCellColors","rowTotalColors","colTotalColors","heatmapMode","colorScaleGenerator","tableColorScaleGenerator","rowTotalValues","getAggregator","colTotalValues","allValues","c","colorScale","v","rowColorScales","rowValues","colColorScales","colValues","aggregationNameLookup","getCellStyle","heatmapStyle","conditionalStyle","formatCellValue","aggregator","bind","formatLabel","txt","parsed","formatRowLabel","index","isLastElement","rowAttrsLength","getClickHandler","clickCallback","filters","keys","attr","e","handleColSort","stopPropagation","onColSort","currentSort","colSorts","nextSort","handleRowSort","onRowSort","rowSorts","getSortButton","isCol","handleSort","sortIcon","colSortIcons","DEFAULT","rowSortIcons","totalRowAggregations","totalsLabelText","formattedColLabel","isRowAttr","rowMeta","totalAggregator","formattedTxt","aggregationKeyForCell","grandTotalAggregator","totalLabel","totalValue","React","PureComponent","defaultProps","propTypes","PropTypes","func","object","objectOf","oneOf","arrayOf","shape","string","isRequired","ASC","DESC","node","bool","TSVExportRenderer","safeRowKeys","safeColKeys","rowEntries","headerRow","slice","join","result","row","entry","unshift","width","window","innerWidth","height","innerHeight","Table"],"mappings":"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","file":"TableRenderers.js","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport {PivotData, numberFormat} from './Utilities';\n\n// helper function for setting row/col-span in pivotTableRenderer\nconst spanSize = function(arr, i, j) {\n let x;\n if (i !== 0) {\n let asc, end;\n let noDraw = true;\n for (\n x = 0, end = j, asc = end >= 0;\n asc ? x <= end : x >= end;\n asc ? x++ : x--\n ) {\n if (arr[i - 1][x] !== arr[i][x]) {\n noDraw = false;\n }\n }\n if (noDraw) {\n return -1;\n }\n }\n let len = 0;\n while (i + len < arr.length) {\n let asc1, end1;\n let stop = false;\n for (\n x = 0, end1 = j, asc1 = end1 >= 0;\n asc1 ? x <= end1 : x >= end1;\n asc1 ? x++ : x--\n ) {\n if (arr[i][x] !== arr[i + len][x]) {\n stop = true;\n }\n }\n if (stop) {\n break;\n }\n len++;\n }\n return len;\n};\n\n// ==> Calculate the positions for GroupSegments <==\nfunction buildHeaderGroupSegments(rowAttrs, rowGroupConfig) {\n const attrToGroup = {};\n (rowGroupConfig || []).forEach(({label, match}) => {\n match.forEach(name => {\n attrToGroup[name] = label;\n });\n });\n\n // Mỗi attribute luôn là 1 segment riêng — không gộp colSpan nữa,\n // để label nhóm (vd \"AAA\") hiện lặp lại trên từng cột con.\n return rowAttrs.map(name => {\n // eslint-disable-next-line no-undefined\n const group = attrToGroup[name] !== undefined ? attrToGroup[name] : null;\n return {group, span: 1};\n });\n}\n\n// Style cho ô có nhãn nhóm trong group header\nconst groupLabelStyle = {\n textAlign: 'center',\n};\n\nfunction redColorScaleGenerator(values) {\n const min = Math.min.apply(Math, values);\n const max = Math.max.apply(Math, values);\n return x => {\n // eslint-disable-next-line no-magic-numbers\n const nonRed = 255 - Math.round((255 * (x - min)) / (max - min));\n return {backgroundColor: `rgb(255,${nonRed},${nonRed})`};\n };\n}\n\n// Conditional formatting evaluation function\nfunction evaluateCondition(value, condition) {\n if (!condition || !condition.type) {\n return false;\n }\n\n const {type, value: conditionValue} = condition;\n const numValue = typeof value === 'number' ? value : parseFloat(value);\n const numConditionValue =\n typeof conditionValue === 'number'\n ? conditionValue\n : parseFloat(conditionValue);\n\n switch (type) {\n case 'greaterThan':\n return (\n !isNaN(numValue) &&\n !isNaN(numConditionValue) &&\n numValue > numConditionValue\n );\n case 'lessThan':\n return (\n !isNaN(numValue) &&\n !isNaN(numConditionValue) &&\n numValue < numConditionValue\n );\n case 'greaterThanOrEqual':\n return (\n !isNaN(numValue) &&\n !isNaN(numConditionValue) &&\n numValue >= numConditionValue\n );\n case 'lessThanOrEqual':\n return (\n !isNaN(numValue) &&\n !isNaN(numConditionValue) &&\n numValue <= numConditionValue\n );\n case 'equal':\n if (typeof value === 'string' && typeof conditionValue === 'string') {\n return value === conditionValue;\n }\n return (\n !isNaN(numValue) &&\n !isNaN(numConditionValue) &&\n numValue === numConditionValue\n );\n case 'notEqual':\n if (typeof value === 'string' && typeof conditionValue === 'string') {\n return value !== conditionValue;\n }\n return (\n isNaN(numValue) ||\n isNaN(numConditionValue) ||\n numValue !== numConditionValue\n );\n case 'empty':\n // Check for null, undefined, empty string, whitespace-only strings, or NaN\n // eslint-disable-next-line no-undefined\n if (value === null || value === undefined) {\n return true;\n }\n if (typeof value === 'string') {\n return value.trim() === '';\n }\n if (typeof value === 'number') {\n return isNaN(value);\n }\n return false;\n case 'notEmpty':\n // Check that value is not null, undefined, empty/whitespace string, or NaN\n // eslint-disable-next-line no-undefined\n if (value === null || value === undefined) {\n return false;\n }\n if (typeof value === 'string') {\n return value.trim() !== '';\n }\n if (typeof value === 'number') {\n return !isNaN(value);\n }\n // Other types (boolean, object, etc.) are considered not empty\n return true;\n // eslint-disable-next-line no-case-declarations\n case 'contains':\n // Convert both values to strings for comparison\n // This handles cases where values are numbers (from aggregators) or conditionValue is parsed as number\n const valueStr = String(value || '');\n const conditionValueStr = String(conditionValue || '');\n if (valueStr && conditionValueStr) {\n return valueStr.toLowerCase().includes(conditionValueStr.toLowerCase());\n }\n return false;\n // eslint-disable-next-line no-case-declarations\n case 'notContains':\n // Convert both values to strings for comparison\n // This handles cases where values are numbers (from aggregators) or conditionValue is parsed as number\n const valueStr2 = String(value || '');\n const conditionValueStr2 = String(conditionValue || '');\n if (valueStr2 && conditionValueStr2) {\n return !valueStr2\n .toLowerCase()\n .includes(conditionValueStr2.toLowerCase());\n }\n return true;\n default:\n return false;\n }\n}\n\n// Apply conditional formatting rules to a value\nfunction getConditionalFormattingStyle(value, conditionalFormatting) {\n if (!conditionalFormatting || !Array.isArray(conditionalFormatting.rules)) {\n return {};\n }\n\n // Evaluate rules in order, return first matching rule's style\n for (const rule of conditionalFormatting.rules) {\n if (evaluateCondition(value, rule.condition)) {\n // Return a copy of the style object to avoid mutations\n return rule.style ? Object.assign({}, rule.style) : {};\n }\n }\n\n return {};\n}\n\n// Merge styles, with conditional formatting taking precedence\nfunction mergeStyles(...styles) {\n return Object.assign({}, ...styles.filter(s => s && typeof s === 'object'));\n}\n\n// Helper function to check if a string contains special characters (like -, /, etc.)\n// This prevents formatting of date strings or formatted strings\n// Only pure numeric strings (with optional decimal point and minus sign) should be formatted\nfunction containsSpecialCharacters(str) {\n if (typeof str !== 'string') {\n return false;\n }\n const trimmed = str.trim();\n // Check if string contains any special characters that indicate it's not a raw number\n // Allow: digits, decimal point, minus sign at start, plus sign at start, spaces\n // Disallow: hyphens in middle, slashes, and other special characters\n const pureNumericPattern = /^-?\\d*\\.?\\d+$/;\n return !pureNumericPattern.test(trimmed);\n}\n\n// Helper function to check if an aggregation should skip formatting\n// Aggregations like Count, First, Last should not be formatted\n// Aggregations like Sum, Average should be formatted\nfunction shouldSkipFormattingForAggregation(aggregatorName) {\n if (!aggregatorName) {\n return false;\n }\n\n const name = aggregatorName.toLowerCase();\n // Skip formatting for these aggregation types\n const skipFormattingAggregations = [\n 'count',\n 'count unique values',\n 'list unique values',\n 'first',\n 'last',\n 'minimum',\n 'maximum',\n ];\n return skipFormattingAggregations.includes(name);\n}\n\n// Apply cell formatting rules to a value\nexport function applyCellFormatting(\n value,\n cellFormatting,\n defaultFormatter,\n aggregatorName = null\n) {\n // Don't format if aggregation type should skip formatting (e.g., Count, First, Last)\n // Only use defaultFormatter if value is numeric, otherwise return as-is\n const isNumeric =\n (typeof value === 'number' && !isNaN(value) && isFinite(value)) ||\n (typeof value === 'string' &&\n value.trim() !== '' &&\n !containsSpecialCharacters(value) &&\n !isNaN(parseFloat(value)) &&\n isFinite(parseFloat(value)));\n if (shouldSkipFormattingForAggregation(aggregatorName)) {\n if (isNumeric && defaultFormatter) {\n return defaultFormatter(value);\n }\n // Return raw value for non-numeric values (dates, strings, etc.)\n return value;\n }\n\n // If no cellFormatting rules, always use default formatter to return to original format\n // This ensures values return to their original format when cellFormatting is cleared\n // Check for all possible cases: null, undefined, empty object, empty rules array\n const hasFormattingRules =\n cellFormatting &&\n typeof cellFormatting === 'object' &&\n Array.isArray(cellFormatting.rules) &&\n cellFormatting.rules.length > 0 &&\n cellFormatting.rules.some(rule => rule && rule.format);\n\n if (!hasFormattingRules) {\n // When cellFormatting rules are cleared, return the raw value (not formatted)\n // This ensures all cells (regular, Totals, Aggregation) return to their original unformatted state\n // Return the raw numeric value for numbers, or the value as-is for other types\n if (isNumeric) {\n // Return raw numeric value without any formatting\n if (typeof value === 'number') {\n return value;\n }\n // For string numbers, return the parsed numeric value\n return parseFloat(value);\n }\n // For non-numeric values (dates, strings, etc.), return as-is\n return value;\n }\n\n // Don't format if it contains special characters (dates, formatted strings, etc.)\n // Only check this when cellFormatting rules exist\n if (containsSpecialCharacters(value)) {\n return defaultFormatter ? defaultFormatter(value) : String(value);\n }\n\n // Check if value is a number - only apply custom formatting to raw numbers\n // Handle both number type and string numbers (e.g., \"123.45\")\n // Exclude strings with special characters from formatting\n let numericValue = value;\n\n // Convert string numbers to actual numbers for formatting\n if (isNumeric && typeof value === 'string') {\n numericValue = parseFloat(value);\n }\n\n // Use the first rule (all rules apply to all values)\n const matchingRule = cellFormatting.rules[0];\n\n // If we found a matching rule and value is numeric, apply its formatting\n if (matchingRule && matchingRule.format && isNumeric) {\n const format = matchingRule.format;\n const formatter = numberFormat({\n digitsAfterDecimal: 'decimalPlaces' in format ? format.decimalPlaces : 2,\n thousandsSep: 'thousandsSep' in format ? format.thousandsSep : ',',\n decimalSep: 'decimalSep' in format ? format.decimalSep : '.',\n prefix: 'prefix' in format ? format.prefix : '',\n suffix: 'suffix' in format ? format.suffix : '',\n showOriginal: 'showOriginal' in format ? format.showOriginal : false,\n });\n return formatter(numericValue);\n }\n\n // Not numeric or no matching rule, use default formatter\n return defaultFormatter ? defaultFormatter(value) : String(value);\n}\n\nfunction makeRenderer(opts = {}) {\n class TableRenderer extends React.PureComponent {\n render() {\n const pivotData = new PivotData(this.props);\n const colAttrs = pivotData.props.cols;\n const rowAttrs = pivotData.props.rows;\n const aggregations = pivotData.getAggregations();\n const primaryAggregation = pivotData.getPrimaryAggregation();\n const hasMultipleAggregators = aggregations.length > 1;\n const tableOptions = this.props.tableOptions || {};\n const aggregationDisplayMode =\n tableOptions.aggregationDisplayMode === 'column' ? 'column' : 'row';\n const isColumnAggregationMode =\n aggregationDisplayMode === 'column' && hasMultipleAggregators;\n const rowAttrsToRender =\n hasMultipleAggregators && !isColumnAggregationMode\n ? rowAttrs.concat(['Values'])\n : rowAttrs;\n const colAttrsToRender = colAttrs;\n const hasColumnAttributes = colAttrsToRender.length > 0;\n const showTotalsColumn = !isColumnAggregationMode;\n const shouldRenderRowHeaderPlaceholder = rowAttrsToRender.length !== 0;\n\n // --- Row group header (rowGroupConfig) ---\n const rowGroupConfig = this.props.rowGroupConfig;\n const hasHeaderGroup = Boolean(rowGroupConfig && rowGroupConfig.length);\n const headerGroupSegments = hasHeaderGroup\n ? buildHeaderGroupSegments(rowAttrs, rowGroupConfig)\n : [];\n // extraSpan accounts for the synthetic \"Values\" column added when there\n // are multiple aggregators shown as rows; it isn't part of any group.\n const headerGroupExtraSpan = rowAttrsToRender.length - rowAttrs.length;\n const renderGroupSegments = (rowSpan, extraSpan = 0) => {\n const cells = headerGroupSegments.map((seg, idx) => (\n <th\n key={`hgSeg${idx}`}\n colSpan={seg.span}\n rowSpan={rowSpan}\n // eslint-disable-next-line no-undefined\n style={seg.group ? groupLabelStyle : undefined}\n >\n {seg.group || ''}\n </th>\n ));\n if (extraSpan > 0) {\n cells.push(\n <th key=\"hgSegExtra\" colSpan={extraSpan} rowSpan={rowSpan} />\n );\n }\n return cells;\n };\n // --- End row group header ---\n\n // --- Optional \"No.\" column (showNumericalOrder) ---\n // When enabled every data row is prefixed with its 1-based index, in a\n // column labelled \"No.\" placed before the row attribute columns.\n const showNumericalOrder = Boolean(this.props.showNumericalOrder);\n const hasNumberColumn =\n showNumericalOrder &&\n (rowAttrsToRender.length !== 0 || colAttrsToRender.length !== 0);\n const numberColumnLabel = 'No.';\n const renderedAggregationHeaderRow =\n isColumnAggregationMode && hasColumnAttributes;\n // The \"No.\" header cell is rendered in the first header row and spans\n // every header row, so the repeated header rows (column attributes,\n // aggregator labels, row group labels) stay aligned with the body.\n const numberColumnHeaderRowSpan =\n colAttrsToRender.length +\n (renderedAggregationHeaderRow ? 1 : 0) +\n (rowAttrsToRender.length !== 0 && !renderedAggregationHeaderRow\n ? 1\n : 0) +\n (hasHeaderGroup &&\n colAttrsToRender.length === 0 &&\n rowAttrsToRender.length !== 0\n ? 1\n : 0);\n const numberColumnInGroupRow =\n hasHeaderGroup &&\n colAttrsToRender.length === 0 &&\n rowAttrsToRender.length !== 0;\n const renderNumberHeaderCell = (rowSpan = numberColumnHeaderRowSpan) => (\n <th className=\"pvtAxisLabel pvtRowNumber\" rowSpan={rowSpan}>\n {numberColumnLabel}\n </th>\n );\n // --- End \"No.\" column ---\n\n const rowKeys = pivotData.getRowKeys();\n const baseRowKeys =\n hasMultipleAggregators &&\n !isColumnAggregationMode &&\n rowKeys.length === 0\n ? [[]]\n : rowKeys;\n const renderedRows =\n hasMultipleAggregators && !isColumnAggregationMode\n ? baseRowKeys.reduce((acc, rowKey) => {\n aggregations.forEach(agg => {\n acc.push({\n displayKey: rowKey.concat([agg.label || agg.aggregatorName]),\n actualKey: rowKey,\n aggregationKey: agg.key,\n });\n });\n return acc;\n }, [])\n : baseRowKeys.map(rowKey => ({\n displayKey: rowKey,\n actualKey: rowKey,\n aggregationKey: primaryAggregation.key,\n }));\n const rowKeyValues = renderedRows.map(r => r.displayKey);\n const colKeys = pivotData.getColKeys();\n const baseColKeys =\n isColumnAggregationMode && colKeys.length === 0 ? [[]] : colKeys;\n const columnMeta = isColumnAggregationMode\n ? baseColKeys.reduce((acc, colKey) => {\n aggregations.forEach(agg => {\n acc.push({\n displayKey: colKey.concat([agg.label || agg.aggregatorName]),\n actualKey: colKey,\n aggregationKey: agg.key,\n });\n });\n return acc;\n }, [])\n : colKeys.map(colKey => ({\n displayKey: colKey,\n actualKey: colKey,\n aggregationKey: primaryAggregation.key,\n }));\n const colKeyValues = columnMeta.map(col => col.displayKey);\n\n const renderAggregatorHeaderCells = () =>\n columnMeta.map((colMeta, idx) => {\n const label = colMeta.displayKey[colMeta.displayKey.length - 1] || '';\n // Calculate colspan/rowspan so aggregator headers line up with column groups\n // aggregator index is the last element in displayKey (after column attrs)\n const aggIndex = colAttrsToRender.length;\n // When there are column attributes, each aggregator should appear once per column group,\n // so each aggregator header should have colSpan = 1.\n // When there are no column attributes, use spanSize to merge identical aggregator labels.\n let colSpan;\n if (hasColumnAttributes) {\n // Each aggregator appears once per column group, so colSpan is always 1\n // This ensures aggregator headers are listed in each column group and align\n // correctly with the column groups above (which have colSpan = number of aggregators)\n colSpan = 1;\n } else {\n // Use spanSize to merge identical aggregator labels when there are no column attributes\n colSpan = spanSize(colKeyValues, idx, aggIndex);\n // If spanSize returned -1 it means this cell is merged into a previous one\n if (colSpan === -1) {\n return null;\n }\n }\n\n // When there are column attributes, rowSpan should account for the row header row\n // When there are no column attributes, rowSpan is 1\n const rowSpan =\n hasColumnAttributes && rowAttrsToRender.length !== 0 ? 1 : 1;\n\n return (\n <th\n className=\"pvtColLabel\"\n key={`agg-label-${idx}`}\n colSpan={colSpan}\n rowSpan={rowSpan}\n >\n {label}\n </th>\n );\n });\n\n let valueCellColors = () => {};\n let rowTotalColors = () => {};\n let colTotalColors = () => {};\n if (opts.heatmapMode && !hasMultipleAggregators) {\n const colorScaleGenerator = this.props.tableColorScaleGenerator;\n const rowTotalValues = colKeys.map(x =>\n pivotData.getAggregator([], x, primaryAggregation.key).value()\n );\n rowTotalColors = colorScaleGenerator(rowTotalValues);\n const colTotalValues = rowKeys.map(x =>\n pivotData.getAggregator(x, [], primaryAggregation.key).value()\n );\n colTotalColors = colorScaleGenerator(colTotalValues);\n\n if (opts.heatmapMode === 'full') {\n const allValues = [];\n rowKeys.map(r =>\n colKeys.map(c =>\n allValues.push(\n pivotData.getAggregator(r, c, primaryAggregation.key).value()\n )\n )\n );\n const colorScale = colorScaleGenerator(allValues);\n valueCellColors = (r, c, v) => colorScale(v);\n } else if (opts.heatmapMode === 'row') {\n const rowColorScales = {};\n rowKeys.map(r => {\n const rowValues = colKeys.map(x =>\n pivotData.getAggregator(r, x, primaryAggregation.key).value()\n );\n rowColorScales[r] = colorScaleGenerator(rowValues);\n });\n valueCellColors = (r, c, v) => rowColorScales[r](v);\n } else if (opts.heatmapMode === 'col') {\n const colColorScales = {};\n colKeys.map(c => {\n const colValues = rowKeys.map(x =>\n pivotData.getAggregator(x, c, primaryAggregation.key).value()\n );\n colColorScales[c] = colorScaleGenerator(colValues);\n });\n valueCellColors = (r, c, v) => colColorScales[c](v);\n }\n }\n\n // Get conditional formatting from tableOptions\n const conditionalFormatting = tableOptions.conditionalFormatting || null;\n\n // Get cell formatting from tableOptions\n const cellFormatting = tableOptions.cellFormatting || null;\n\n // Create lookup map from aggregationKey to aggregatorName\n const aggregationNameLookup = {};\n aggregations.forEach(agg => {\n aggregationNameLookup[agg.key] = agg.aggregatorName;\n });\n\n // Helper function to get cell style with conditional formatting\n const getCellStyle = (value, heatmapStyle = {}) => {\n const conditionalStyle = getConditionalFormattingStyle(\n value,\n conditionalFormatting\n );\n return mergeStyles(heatmapStyle, conditionalStyle);\n };\n\n // Helper function to format cell value with cell formatting rules\n const formatCellValue = (value, aggregator, aggregationKey) => {\n const aggregatorName = aggregationKey\n ? aggregationNameLookup[aggregationKey]\n : null;\n\n return applyCellFormatting(\n value,\n cellFormatting,\n aggregator.format.bind(aggregator),\n aggregatorName\n );\n };\n\n // Helper function to format label text if it's numeric\n // Used for both row and column labels\n const formatLabel = txt => {\n // Check if txt is numeric (number or numeric string)\n // Also exclude 'null' string which is used for missing values\n if (txt === 'null' || txt === null || typeof txt === 'undefined') {\n return txt;\n }\n\n // Don't format if it contains special characters (dates, formatted strings, etc.)\n if (containsSpecialCharacters(txt)) {\n return txt;\n }\n\n // Check if txt is numeric (number or numeric string)\n // A string is numeric if it can be parsed as a finite number\n // Exclude strings with special characters from formatting\n let isNumeric = false;\n let numericValue = null;\n\n if (typeof txt === 'number') {\n isNumeric = !isNaN(txt) && isFinite(txt);\n if (isNumeric) {\n numericValue = txt;\n }\n } else if (\n typeof txt === 'string' &&\n txt.trim() !== '' &&\n txt !== 'null' &&\n !containsSpecialCharacters(txt)\n ) {\n const parsed = parseFloat(txt.trim());\n isNumeric = !isNaN(parsed) && isFinite(parsed);\n if (isNumeric) {\n numericValue = parsed;\n }\n }\n\n if (\n isNumeric &&\n numericValue !== null &&\n cellFormatting &&\n Array.isArray(cellFormatting.rules) &&\n cellFormatting.rules.length > 0\n ) {\n const matchingRule = cellFormatting.rules[0];\n if (matchingRule && matchingRule.format) {\n const format = matchingRule.format;\n const formatter = numberFormat({\n digitsAfterDecimal:\n 'decimalPlaces' in format ? format.decimalPlaces : 2,\n thousandsSep:\n 'thousandsSep' in format ? format.thousandsSep : ',',\n decimalSep: 'decimalSep' in format ? format.decimalSep : '.',\n prefix: 'prefix' in format ? format.prefix : '',\n suffix: 'suffix' in format ? format.suffix : '',\n showOriginal:\n 'showOriginal' in format ? format.showOriginal : false,\n });\n return formatter(numericValue);\n }\n }\n\n // Not numeric or no formatting rules, return as-is\n return txt;\n };\n\n // Helper function to format row label text if it's numeric\n // Only formats if it's a numeric value, not aggregation labels\n const formatRowLabel = (\n txt,\n index,\n isLastElement,\n hasMultipleAggregators,\n rowAttrsLength\n ) => {\n // Don't format the last element if it's an aggregation label (when multiple aggregators)\n // The last element is an aggregation label only if:\n // 1. There are multiple aggregators\n // 2. AND it's beyond the row attributes (index >= rowAttrsLength)\n if (\n hasMultipleAggregators &&\n isLastElement &&\n index >= rowAttrsLength\n ) {\n return txt;\n }\n\n return formatLabel(txt);\n };\n\n const getClickHandler =\n tableOptions && tableOptions.clickCallback\n ? (value, rowValues, colValues) => {\n const filters = {};\n for (const i of Object.keys(colAttrs || {})) {\n const attr = colAttrs[i];\n if (colValues[i] !== null) {\n filters[attr] = colValues[i];\n }\n }\n for (const i of Object.keys(rowAttrs || {})) {\n const attr = rowAttrs[i];\n if (rowValues[i] !== null) {\n filters[attr] = rowValues[i];\n }\n }\n return e =>\n tableOptions.clickCallback(e, value, filters, pivotData);\n }\n : null;\n\n const handleColSort = (attr, e) => {\n e.stopPropagation();\n if (this.props.onColSort) {\n const currentSort = this.props.colSorts && this.props.colSorts[attr];\n let nextSort = 'ASC';\n if (currentSort === 'ASC') {\n nextSort = 'DESC';\n } else if (currentSort === 'DESC') {\n nextSort = null;\n }\n this.props.onColSort(attr, nextSort);\n }\n };\n\n const handleRowSort = (attr, e) => {\n e.stopPropagation();\n if (this.props.onRowSort) {\n const currentSort = this.props.rowSorts && this.props.rowSorts[attr];\n let nextSort = 'ASC';\n if (currentSort === 'ASC') {\n nextSort = 'DESC';\n } else if (currentSort === 'DESC') {\n nextSort = null;\n }\n this.props.onRowSort(attr, nextSort);\n }\n };\n\n const getSortButton = (attr, isCol) => {\n const currentSort = isCol\n ? this.props.colSorts && this.props.colSorts[attr]\n : this.props.rowSorts && this.props.rowSorts[attr];\n const handleSort = isCol ? handleColSort : handleRowSort;\n let sortIcon = '';\n if (currentSort !== null) {\n if (isCol) {\n sortIcon =\n this.props.colSortIcons[currentSort] ||\n this.props.colSortIcons.DEFAULT;\n } else {\n sortIcon =\n this.props.rowSortIcons[currentSort] ||\n this.props.rowSortIcons.DEFAULT;\n }\n }\n return (\n <button\n type=\"button\"\n className=\"pvtSortButton\"\n onClick={e => handleSort(attr, e)}\n title={\n currentSort === 'ASC'\n ? 'Sort Descending'\n : currentSort === 'DESC'\n ? 'Clear Sort'\n : 'Sort Ascending'\n }\n >\n {sortIcon}\n </button>\n );\n };\n\n const totalRowAggregations = isColumnAggregationMode\n ? [primaryAggregation]\n : hasMultipleAggregators\n ? aggregations\n : [primaryAggregation];\n const totalsLabelText = 'Totals';\n\n return (\n <table className=\"pvtTable\">\n <thead>\n {colAttrsToRender.map(function(c, j) {\n return (\n <tr key={`colAttr${j}`}>\n {hasNumberColumn && j === 0 && renderNumberHeaderCell()}\n {shouldRenderRowHeaderPlaceholder &&\n (isColumnAggregationMode || j === 0) &&\n !(\n isColumnAggregationMode &&\n hasColumnAttributes &&\n rowAttrsToRender.length === 1\n ) &&\n (hasHeaderGroup && j === 0 && !isColumnAggregationMode ? (\n renderGroupSegments(\n colAttrsToRender.length,\n headerGroupExtraSpan\n )\n ) : (\n <th\n colSpan={\n isColumnAggregationMode && hasColumnAttributes\n ? rowAttrsToRender.length - 1\n : rowAttrsToRender.length\n }\n rowSpan={\n isColumnAggregationMode && hasColumnAttributes\n ? 1\n : colAttrsToRender.length\n }\n />\n ))}\n {c ? (\n <th className=\"pvtAxisLabel\">\n {c}\n {colAttrs.includes(c) && getSortButton(c, true)}\n </th>\n ) : null}\n {colKeyValues.map(function(colKey, i) {\n const x = spanSize(colKeyValues, i, j);\n\n if (x === -1) {\n return null;\n }\n\n const formattedColLabel = formatLabel(colKey[j]);\n return (\n <th\n className=\"pvtColLabel\"\n key={`colKey${i}`}\n colSpan={x}\n rowSpan={\n j === colAttrsToRender.length - 1 &&\n rowAttrsToRender.length !== 0 &&\n !isColumnAggregationMode\n ? 2\n : 1\n }\n >\n {formattedColLabel}\n </th>\n );\n })}\n\n {showTotalsColumn && j === 0 && (\n <th\n className=\"pvtTotalLabel\"\n rowSpan={\n colAttrsToRender.length +\n (rowAttrsToRender.length === 0 ? 0 : 1)\n }\n >\n {totalsLabelText}\n </th>\n )}\n </tr>\n );\n })}\n\n {hasHeaderGroup &&\n colAttrsToRender.length === 0 &&\n rowAttrsToRender.length !== 0 && (\n <tr>\n {hasNumberColumn && renderNumberHeaderCell()}\n {renderGroupSegments(1, headerGroupExtraSpan)}\n <th />\n </tr>\n )}\n\n {isColumnAggregationMode && hasColumnAttributes && (\n <tr>\n {rowAttrsToRender.length !== 0 &&\n rowAttrsToRender.map((r, i) => {\n const isRowAttr = i < rowAttrs.length;\n const attr = isRowAttr ? rowAttrs[i] : null;\n return (\n <th className=\"pvtAxisLabel\" key={`rowAttr-agg-${i}`}>\n {r}\n {isRowAttr && attr && getSortButton(attr, false)}\n </th>\n );\n })}\n {renderAggregatorHeaderCells()}\n </tr>\n )}\n\n {rowAttrsToRender.length !== 0 &&\n !(isColumnAggregationMode && hasColumnAttributes) && (\n <tr>\n {hasNumberColumn &&\n colAttrsToRender.length === 0 &&\n !numberColumnInGroupRow &&\n renderNumberHeaderCell()}\n {rowAttrsToRender.map((r, i) => {\n const isRowAttr = i < rowAttrs.length;\n const attr = isRowAttr ? rowAttrs[i] : null;\n return (\n <th className=\"pvtAxisLabel\" key={`rowAttr${i}`}>\n {r}\n {isRowAttr && attr && getSortButton(attr, false)}\n </th>\n );\n })}\n {isColumnAggregationMode && !hasColumnAttributes\n ? renderAggregatorHeaderCells()\n : null}\n {showTotalsColumn && (\n <th className=\"pvtTotalLabel\">\n {colAttrs.length === 0 ? totalsLabelText : null}\n </th>\n )}\n </tr>\n )}\n </thead>\n\n <tbody>\n {renderedRows.map(function(rowMeta, i) {\n const totalAggregator = pivotData.getAggregator(\n rowMeta.actualKey,\n [],\n rowMeta.aggregationKey\n );\n const displayKey = rowMeta.displayKey;\n return (\n <tr key={`rowKeyRow${i}`}>\n {hasNumberColumn && (\n <th className=\"pvtRowNumber\" key={`rowNumber${i}`}>\n {i + 1}\n </th>\n )}\n {displayKey.map(function(txt, j) {\n const x = spanSize(rowKeyValues, i, j);\n if (x === -1) {\n return null;\n }\n const isLastElement = j === displayKey.length - 1;\n const formattedTxt = formatRowLabel(\n txt,\n j,\n isLastElement,\n hasMultipleAggregators,\n rowAttrs.length\n );\n return (\n <th\n key={`rowKeyLabel${i}-${j}`}\n className=\"pvtRowLabel\"\n rowSpan={x}\n colSpan={\n showTotalsColumn &&\n j === rowAttrsToRender.length - 1 &&\n colAttrsToRender.length !== 0\n ? 2\n : 1\n }\n >\n {formattedTxt}\n </th>\n );\n })}\n {columnMeta.map(function(colMeta, j) {\n const aggregationKeyForCell = isColumnAggregationMode\n ? colMeta.aggregationKey\n : rowMeta.aggregationKey;\n const aggregator = pivotData.getAggregator(\n rowMeta.actualKey,\n colMeta.actualKey,\n aggregationKeyForCell\n );\n const value = aggregator.value();\n const heatmapStyle =\n valueCellColors(\n rowMeta.actualKey,\n colMeta.actualKey,\n value\n ) || {};\n return (\n <td\n className=\"pvtVal\"\n key={`pvtVal${i}-${j}`}\n onClick={\n getClickHandler &&\n getClickHandler(\n value,\n rowMeta.actualKey,\n colMeta.actualKey\n )\n }\n style={getCellStyle(value, heatmapStyle)}\n >\n {formatCellValue(\n value,\n aggregator,\n aggregationKeyForCell\n )}\n </td>\n );\n })}\n {showTotalsColumn && (\n <td\n className=\"pvtTotal\"\n onClick={\n getClickHandler &&\n getClickHandler(\n totalAggregator.value(),\n rowMeta.actualKey,\n [null]\n )\n }\n style={getCellStyle(\n totalAggregator.value(),\n colTotalColors(totalAggregator.value()) || {}\n )}\n >\n {formatCellValue(\n totalAggregator.value(),\n totalAggregator,\n rowMeta.aggregationKey\n )}\n </td>\n )}\n </tr>\n );\n })}\n\n {totalRowAggregations.map(function(agg) {\n const grandTotalAggregator = pivotData.getAggregator(\n [],\n [],\n isColumnAggregationMode ? primaryAggregation.key : agg.key\n );\n const totalLabel =\n hasMultipleAggregators && !isColumnAggregationMode\n ? `Totals – ${agg.label || agg.aggregatorName}`\n : totalsLabelText;\n return (\n <tr key={`totalRow-${agg.key}`}>\n <th\n className=\"pvtTotalLabel\"\n colSpan={\n rowAttrsToRender.length +\n (colAttrs.length === 0 ||\n (isColumnAggregationMode && hasColumnAttributes)\n ? 0\n : 1) +\n (hasNumberColumn ? 1 : 0)\n }\n >\n {totalLabel}\n </th>\n\n {columnMeta.map(function(colMeta, i) {\n const totalAggregator = pivotData.getAggregator(\n [],\n colMeta.actualKey,\n isColumnAggregationMode ? colMeta.aggregationKey : agg.key\n );\n const totalValue = totalAggregator.value();\n return (\n <td\n className=\"pvtTotal\"\n key={`total${agg.key}-${i}`}\n onClick={\n getClickHandler &&\n getClickHandler(totalValue, [null], colMeta.actualKey)\n }\n style={getCellStyle(\n totalValue,\n rowTotalColors(totalValue) || {}\n )}\n >\n {formatCellValue(totalValue, totalAggregator, agg.key)}\n </td>\n );\n })}\n\n {showTotalsColumn && (\n <td\n onClick={\n getClickHandler &&\n getClickHandler(\n grandTotalAggregator.value(),\n [null],\n [null]\n )\n }\n className=\"pvtGrandTotal\"\n style={getCellStyle(grandTotalAggregator.value(), {})}\n >\n {formatCellValue(\n grandTotalAggregator.value(),\n grandTotalAggregator,\n isColumnAggregationMode\n ? primaryAggregation.key\n : agg.key\n )}\n </td>\n )}\n </tr>\n );\n })}\n </tbody>\n </table>\n );\n }\n }\n\n TableRenderer.defaultProps = PivotData.defaultProps;\n TableRenderer.propTypes = PivotData.propTypes;\n TableRenderer.defaultProps.tableColorScaleGenerator = redColorScaleGenerator;\n TableRenderer.defaultProps.tableOptions = {};\n TableRenderer.defaultProps.colSorts = {};\n TableRenderer.defaultProps.rowSorts = {};\n TableRenderer.defaultProps.rowGroupConfig = null;\n TableRenderer.propTypes.tableColorScaleGenerator = PropTypes.func;\n TableRenderer.propTypes.tableOptions = PropTypes.object;\n TableRenderer.propTypes.colSorts = PropTypes.objectOf(\n PropTypes.oneOf(['ASC', 'DESC'])\n );\n TableRenderer.propTypes.rowSorts = PropTypes.objectOf(\n PropTypes.oneOf(['ASC', 'DESC'])\n );\n TableRenderer.propTypes.onColSort = PropTypes.func;\n TableRenderer.propTypes.onRowSort = PropTypes.func;\n TableRenderer.propTypes.rowGroupConfig = PropTypes.arrayOf(\n PropTypes.shape({\n label: PropTypes.string.isRequired,\n match: PropTypes.arrayOf(PropTypes.string).isRequired,\n })\n );\n TableRenderer.defaultProps.colSortIcons = {\n ASC: '→',\n DESC: '←',\n DEFAULT: '↔',\n };\n TableRenderer.defaultProps.rowSortIcons = {\n ASC: '↑',\n DESC: '↓',\n DEFAULT: '⇅',\n };\n TableRenderer.propTypes.colSortIcons = PropTypes.shape({\n ASC: PropTypes.node,\n DESC: PropTypes.node,\n DEFAULT: PropTypes.node,\n });\n TableRenderer.propTypes.rowSortIcons = PropTypes.shape({\n ASC: PropTypes.node,\n DESC: PropTypes.node,\n DEFAULT: PropTypes.node,\n });\n // When true, a \"No.\" column with the 1-based index of each data row is\n // rendered before the row attribute columns.\n TableRenderer.defaultProps.showNumericalOrder = false;\n TableRenderer.propTypes.showNumericalOrder = PropTypes.bool;\n return TableRenderer;\n}\n\nclass TSVExportRenderer extends React.PureComponent {\n render() {\n const pivotData = new PivotData(this.props);\n const rowAttrs = pivotData.props.rows;\n const aggregations = pivotData.getAggregations();\n const hasMultipleAggregators = aggregations.length > 1;\n const rowKeys = pivotData.getRowKeys();\n const colKeys = pivotData.getColKeys();\n const safeRowKeys = rowKeys.length === 0 ? [[]] : rowKeys;\n const safeColKeys = colKeys.length === 0 ? [[]] : colKeys;\n\n const rowEntries = hasMultipleAggregators\n ? safeRowKeys.reduce((acc, rowKey) => {\n aggregations.forEach(agg => {\n acc.push({rowKey, aggregationKey: agg.key, label: agg.label});\n });\n return acc;\n }, [])\n : safeRowKeys.map(rowKey => ({\n rowKey,\n aggregationKey: aggregations[0].key,\n label: aggregations[0].label || aggregations[0].aggregatorName,\n }));\n\n const headerRow = rowAttrs.slice();\n if (hasMultipleAggregators) {\n headerRow.push('Values');\n }\n if (safeColKeys.length === 1 && safeColKeys[0].length === 0) {\n headerRow.push(\n hasMultipleAggregators\n ? 'Value'\n : aggregations[0].label || aggregations[0].aggregatorName\n );\n } else {\n safeColKeys.map(c => headerRow.push(c.join('-')));\n }\n\n const result = rowEntries.map(entry => {\n const row = entry.rowKey.map(x => x);\n if (hasMultipleAggregators) {\n row.push(entry.label || '');\n }\n safeColKeys.map(colKey => {\n const v = pivotData\n .getAggregator(entry.rowKey, colKey, entry.aggregationKey)\n .value();\n row.push(v ? v : '');\n });\n return row;\n });\n\n result.unshift(headerRow);\n\n return (\n <textarea\n value={result.map(r => r.join('\\t')).join('\\n')}\n style={{width: window.innerWidth / 2, height: window.innerHeight / 2}}\n readOnly={true}\n />\n );\n }\n}\n\nTSVExportRenderer.defaultProps = PivotData.defaultProps;\nTSVExportRenderer.propTypes = PivotData.propTypes;\n\nexport default {\n Table: makeRenderer(),\n 'Table Heatmap': makeRenderer({heatmapMode: 'full'}),\n 'Table Col Heatmap': makeRenderer({heatmapMode: 'col'}),\n 'Table Row Heatmap': makeRenderer({heatmapMode: 'row'}),\n 'Exportable TSV': TSVExportRenderer,\n};\n"]}
|
|
@@ -23,7 +23,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
|
|
|
23
23
|
// React 19 needs to be told that this environment supports `act`.
|
|
24
24
|
global.IS_REACT_ACT_ENVIRONMENT = true;
|
|
25
25
|
|
|
26
|
-
// `
|
|
26
|
+
// `showProcessing` is a debugging/testing hook that forces the loading
|
|
27
27
|
// overlay on top of the rendered table without running a real worker
|
|
28
28
|
// computation, so the overlay can be inspected while consuming the package.
|
|
29
29
|
var records = [{ name: 'Nick', gender: 'male', colour: 'blue', trials: 103 }, { name: 'Jane', gender: 'female', colour: 'red', trials: 95 }, { name: 'John', gender: 'male', colour: 'blue', trials: 112 }, { name: 'Carol', gender: 'female', colour: 'yellow', trials: 102 }];
|
|
@@ -43,7 +43,7 @@ function rerenderPivot(root, props) {
|
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
describe(' PivotTableUI
|
|
46
|
+
describe(' PivotTableUI showProcessing', function () {
|
|
47
47
|
var containers = void 0;
|
|
48
48
|
|
|
49
49
|
beforeEach(function () {
|
|
@@ -79,7 +79,7 @@ describe(' PivotTableUI isShowProcessing', function () {
|
|
|
79
79
|
expect(node.querySelector('.pvtTable')).not.toBeNull();
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
-
it('renders the overlay on top of the table when
|
|
82
|
+
it('renders the overlay on top of the table when showProcessing is true', function () {
|
|
83
83
|
var _mount2 = mount(baseProps),
|
|
84
84
|
node = _mount2.node,
|
|
85
85
|
root = _mount2.root;
|
|
@@ -89,7 +89,7 @@ describe(' PivotTableUI isShowProcessing', function () {
|
|
|
89
89
|
expect(node.querySelector('.pvtTable')).not.toBeNull();
|
|
90
90
|
expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();
|
|
91
91
|
|
|
92
|
-
rerenderPivot(root, Object.assign({}, baseProps, {
|
|
92
|
+
rerenderPivot(root, Object.assign({}, baseProps, { showProcessing: true }));
|
|
93
93
|
|
|
94
94
|
var overlay = node.querySelector('.pvtLoadingOverlay');
|
|
95
95
|
expect(overlay).not.toBeNull();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/__tests__/PivotTableUI-processing-test.js"],"names":["global","IS_REACT_ACT_ENVIRONMENT","records","name","gender","colour","trials","baseProps","data","rows","cols","aggregatorName","vals","rendererName","rerenderPivot","root","props","render","React","createElement","PivotTableUI","describe","containers","beforeEach","afterEach","forEach","container","unmount","node","remove","mount","document","body","appendChild","entry","push","it","expect","querySelector","toBeNull","not","Object","assign","isShowProcessing","overlay","textContent","toBe","PivotLoadingOverlay","wait","Promise","setTimeout","resolve","ms","actAsync","reject","callback","then","workerInstances","FakeWorker","url","posted","onmessage","message","previousWorker","Worker","workerThreshold","restore","worker","toBeDefined","computeMsg","find","m","type","result","id","catch","error"],"mappings":"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","file":"PivotTableUI-processing-test.js","sourcesContent":["import React, {act} from 'react';\nimport {createRoot} from 'react-dom/client';\nimport PivotTableUI, {PivotLoadingOverlay} from '../PivotTableUI';\nimport {\n computePivotState,\n createWorkerConfig,\n materializeData,\n} from '../pivotCompute';\n/* eslint-disable no-magic-numbers */\n\n// React 19 needs to be told that this environment supports `act`.\nglobal.IS_REACT_ACT_ENVIRONMENT = true;\n\n// `isShowProcessing` is a debugging/testing hook that forces the loading\n// overlay on top of the rendered table without running a real worker\n// computation, so the overlay can be inspected while consuming the package.\nconst records = [\n {name: 'Nick', gender: 'male', colour: 'blue', trials: 103},\n {name: 'Jane', gender: 'female', colour: 'red', trials: 95},\n {name: 'John', gender: 'male', colour: 'blue', trials: 112},\n {name: 'Carol', gender: 'female', colour: 'yellow', trials: 102},\n];\n\nconst baseProps = {\n data: records,\n rows: ['name'],\n cols: [],\n aggregatorName: 'Count',\n vals: [],\n rendererName: 'Table',\n};\n\nfunction rerenderPivot(root, props) {\n act(() => {\n root.render(React.createElement(PivotTableUI, props));\n });\n}\n\ndescribe(' PivotTableUI isShowProcessing', function() {\n let containers;\n\n beforeEach(function() {\n containers = [];\n });\n\n afterEach(function() {\n containers.forEach(container => {\n act(() => {\n container.root.unmount();\n });\n container.node.remove();\n });\n });\n\n const mount = props => {\n const node = document.createElement('div');\n document.body.appendChild(node);\n const root = createRoot(node);\n act(() => {\n root.render(React.createElement(PivotTableUI, props));\n });\n const entry = {node, root};\n containers.push(entry);\n return entry;\n };\n\n it('does not render the overlay by default', function() {\n const {node} = mount(baseProps);\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n });\n\n it('renders the overlay on top of the table when isShowProcessing is true', function() {\n const {node, root} = mount(baseProps);\n // Table is rendered from the real data first (no overlay).\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n\n rerenderPivot(root, Object.assign({}, baseProps, {isShowProcessing: true}));\n\n const overlay = node.querySelector('.pvtLoadingOverlay');\n expect(overlay).not.toBeNull();\n // The overlay is layered on top of the table: the table must survive.\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n // Only a spinner and a label: progress percentages were removed, the\n // overlay simply stays until the worker posts its result event.\n expect(overlay.querySelector('.pvtLoadingSpinner')).not.toBeNull();\n expect(overlay.querySelector('.pvtLoadingText').textContent).toBe(\n 'Processing…'\n );\n expect(overlay.querySelector('.pvtLoadingBar')).toBeNull();\n expect(overlay.querySelector('.pvtLoadingPercent')).toBeNull();\n\n // Turning the flag back off removes the overlay.\n rerenderPivot(root, baseProps);\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n });\n\n it('renders a spinner without any percentage markup', function() {\n const node = document.createElement('div');\n act(() => {\n createRoot(node).render(\n React.createElement(PivotLoadingOverlay, null)\n );\n });\n expect(node.querySelector('.pvtLoadingOverlay')).not.toBeNull();\n expect(node.querySelector('.pvtLoadingSpinner')).not.toBeNull();\n expect(node.querySelector('.pvtLoadingBarWrap')).toBeNull();\n expect(node.querySelector('.pvtLoadingPercent')).toBeNull();\n expect(node.querySelector('.pvtLoadingText').textContent).toBe(\n 'Processing…'\n );\n });\n\n it('hides the overlay only after the worker responds and the table renders', function() {\n const wait = ms => new Promise(resolve => setTimeout(resolve, ms));\n // React's act() returns a non-standard thenable whose .then() does not\n // return a promise, so it cannot be chained directly - wrap it first.\n const actAsync = callback =>\n new Promise((resolve, reject) => act(callback).then(resolve, reject));\n const workerInstances = [];\n class FakeWorker {\n constructor(url) {\n this.url = url;\n this.posted = [];\n this.onmessage = null;\n workerInstances.push(this);\n }\n\n postMessage(message) {\n this.posted.push(message);\n }\n\n terminate() {}\n }\n\n const previousWorker = global.Worker;\n global.Worker = FakeWorker;\n\n // workerThreshold: 2 makes this small dataset worker-eligible.\n const props = Object.assign({}, baseProps, {workerThreshold: 2});\n const {node} = mount(props);\n\n const restore = () => {\n global.Worker = previousWorker;\n };\n\n // The overlay is up while the computation is pending.\n expect(node.querySelector('.pvtLoadingOverlay')).not.toBeNull();\n\n // Wait out the dispatch debounce so the request reaches the worker.\n return actAsync(() => wait(80))\n .then(() => {\n const worker = workerInstances[0];\n expect(worker).toBeDefined();\n const computeMsg = worker.posted.find(m => m.type === 'pivot:compute');\n expect(computeMsg).toBeDefined();\n // The worker has not answered yet: the overlay must stay up.\n expect(node.querySelector('.pvtLoadingOverlay')).not.toBeNull();\n\n // Worker finishes and posts its result event.\n const result = computePivotState(\n materializeData(records, {}),\n createWorkerConfig(props)\n );\n return actAsync(() => {\n worker.onmessage({\n data: {type: 'pivot:result', id: computeMsg.id, result},\n });\n return wait(0);\n });\n })\n .then(() => {\n // The overlay is gone only now - and the freshly computed table is\n // already on screen in the same state where the overlay disappeared.\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n restore();\n })\n .catch(error => {\n restore();\n throw error;\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/__tests__/PivotTableUI-processing-test.js"],"names":["global","IS_REACT_ACT_ENVIRONMENT","records","name","gender","colour","trials","baseProps","data","rows","cols","aggregatorName","vals","rendererName","rerenderPivot","root","props","render","React","createElement","PivotTableUI","describe","containers","beforeEach","afterEach","forEach","container","unmount","node","remove","mount","document","body","appendChild","entry","push","it","expect","querySelector","toBeNull","not","Object","assign","showProcessing","overlay","textContent","toBe","PivotLoadingOverlay","wait","Promise","setTimeout","resolve","ms","actAsync","reject","callback","then","workerInstances","FakeWorker","url","posted","onmessage","message","previousWorker","Worker","workerThreshold","restore","worker","toBeDefined","computeMsg","find","m","type","result","id","catch","error"],"mappings":"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","file":"PivotTableUI-processing-test.js","sourcesContent":["import React, {act} from 'react';\nimport {createRoot} from 'react-dom/client';\nimport PivotTableUI, {PivotLoadingOverlay} from '../PivotTableUI';\nimport {\n computePivotState,\n createWorkerConfig,\n materializeData,\n} from '../pivotCompute';\n/* eslint-disable no-magic-numbers */\n\n// React 19 needs to be told that this environment supports `act`.\nglobal.IS_REACT_ACT_ENVIRONMENT = true;\n\n// `showProcessing` is a debugging/testing hook that forces the loading\n// overlay on top of the rendered table without running a real worker\n// computation, so the overlay can be inspected while consuming the package.\nconst records = [\n {name: 'Nick', gender: 'male', colour: 'blue', trials: 103},\n {name: 'Jane', gender: 'female', colour: 'red', trials: 95},\n {name: 'John', gender: 'male', colour: 'blue', trials: 112},\n {name: 'Carol', gender: 'female', colour: 'yellow', trials: 102},\n];\n\nconst baseProps = {\n data: records,\n rows: ['name'],\n cols: [],\n aggregatorName: 'Count',\n vals: [],\n rendererName: 'Table',\n};\n\nfunction rerenderPivot(root, props) {\n act(() => {\n root.render(React.createElement(PivotTableUI, props));\n });\n}\n\ndescribe(' PivotTableUI showProcessing', function() {\n let containers;\n\n beforeEach(function() {\n containers = [];\n });\n\n afterEach(function() {\n containers.forEach(container => {\n act(() => {\n container.root.unmount();\n });\n container.node.remove();\n });\n });\n\n const mount = props => {\n const node = document.createElement('div');\n document.body.appendChild(node);\n const root = createRoot(node);\n act(() => {\n root.render(React.createElement(PivotTableUI, props));\n });\n const entry = {node, root};\n containers.push(entry);\n return entry;\n };\n\n it('does not render the overlay by default', function() {\n const {node} = mount(baseProps);\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n });\n\n it('renders the overlay on top of the table when showProcessing is true', function() {\n const {node, root} = mount(baseProps);\n // Table is rendered from the real data first (no overlay).\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n\n rerenderPivot(root, Object.assign({}, baseProps, {showProcessing: true}));\n\n const overlay = node.querySelector('.pvtLoadingOverlay');\n expect(overlay).not.toBeNull();\n // The overlay is layered on top of the table: the table must survive.\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n // Only a spinner and a label: progress percentages were removed, the\n // overlay simply stays until the worker posts its result event.\n expect(overlay.querySelector('.pvtLoadingSpinner')).not.toBeNull();\n expect(overlay.querySelector('.pvtLoadingText').textContent).toBe(\n 'Processing…'\n );\n expect(overlay.querySelector('.pvtLoadingBar')).toBeNull();\n expect(overlay.querySelector('.pvtLoadingPercent')).toBeNull();\n\n // Turning the flag back off removes the overlay.\n rerenderPivot(root, baseProps);\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n });\n\n it('renders a spinner without any percentage markup', function() {\n const node = document.createElement('div');\n act(() => {\n createRoot(node).render(\n React.createElement(PivotLoadingOverlay, null)\n );\n });\n expect(node.querySelector('.pvtLoadingOverlay')).not.toBeNull();\n expect(node.querySelector('.pvtLoadingSpinner')).not.toBeNull();\n expect(node.querySelector('.pvtLoadingBarWrap')).toBeNull();\n expect(node.querySelector('.pvtLoadingPercent')).toBeNull();\n expect(node.querySelector('.pvtLoadingText').textContent).toBe(\n 'Processing…'\n );\n });\n\n it('hides the overlay only after the worker responds and the table renders', function() {\n const wait = ms => new Promise(resolve => setTimeout(resolve, ms));\n // React's act() returns a non-standard thenable whose .then() does not\n // return a promise, so it cannot be chained directly - wrap it first.\n const actAsync = callback =>\n new Promise((resolve, reject) => act(callback).then(resolve, reject));\n const workerInstances = [];\n class FakeWorker {\n constructor(url) {\n this.url = url;\n this.posted = [];\n this.onmessage = null;\n workerInstances.push(this);\n }\n\n postMessage(message) {\n this.posted.push(message);\n }\n\n terminate() {}\n }\n\n const previousWorker = global.Worker;\n global.Worker = FakeWorker;\n\n // workerThreshold: 2 makes this small dataset worker-eligible.\n const props = Object.assign({}, baseProps, {workerThreshold: 2});\n const {node} = mount(props);\n\n const restore = () => {\n global.Worker = previousWorker;\n };\n\n // The overlay is up while the computation is pending.\n expect(node.querySelector('.pvtLoadingOverlay')).not.toBeNull();\n\n // Wait out the dispatch debounce so the request reaches the worker.\n return actAsync(() => wait(80))\n .then(() => {\n const worker = workerInstances[0];\n expect(worker).toBeDefined();\n const computeMsg = worker.posted.find(m => m.type === 'pivot:compute');\n expect(computeMsg).toBeDefined();\n // The worker has not answered yet: the overlay must stay up.\n expect(node.querySelector('.pvtLoadingOverlay')).not.toBeNull();\n\n // Worker finishes and posts its result event.\n const result = computePivotState(\n materializeData(records, {}),\n createWorkerConfig(props)\n );\n return actAsync(() => {\n worker.onmessage({\n data: {type: 'pivot:result', id: computeMsg.id, result},\n });\n return wait(0);\n });\n })\n .then(() => {\n // The overlay is gone only now - and the freshly computed table is\n // already on screen in the same state where the overlay disappeared.\n expect(node.querySelector('.pvtLoadingOverlay')).toBeNull();\n expect(node.querySelector('.pvtTable')).not.toBeNull();\n restore();\n })\n .catch(error => {\n restore();\n throw error;\n });\n });\n});\n"]}
|