@datarailsshared/dr_renderer 1.5.150 → 1.5.159
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/package.json +5 -2
- package/src/charts/dr_donut_chart.d.ts +79 -0
- package/src/charts/dr_donut_chart.js +7 -2
- package/src/charts/dr_gauge_categories_summary_chart.d.ts +136 -0
- package/src/charts/dr_gauge_chart.d.ts +18 -0
- package/src/charts/dr_gauge_chart.js +31 -0
- package/src/dr-renderer-helpers.d.ts +18 -0
- package/src/dr-renderer-helpers.js +2 -2
- package/src/dr_pivottable.d.ts +2 -0
- package/src/dr_pivottable.js +32 -75
- package/src/errors.js +1 -0
- package/src/{types/graph-table-renderer.d.ts → graph-table-renderer.d.ts} +57 -4
- package/src/graph-table-renderer.js +74 -2
- package/src/highcharts_renderer.d.ts +5 -0
- package/src/highcharts_renderer.js +1 -0
- package/src/index.d.ts +83 -86
- package/src/index.js +77 -3
- package/src/novix_renderer.d.ts +2 -0
- package/src/novix_renderer.js +7 -0
- package/src/options/builders.js +1 -0
- package/src/options/constants.js +1 -0
- package/src/options/elements.js +1 -0
- package/src/options/helpers.js +1 -0
- package/src/options/index.js +1 -0
- package/src/options/presets.js +1 -0
- package/src/pivot-table/freeze-panes/constants.d.ts +26 -0
- package/src/pivot-table/freeze-panes/constants.js +42 -0
- package/src/pivot-table/freeze-panes/freeze-panes.css +282 -0
- package/src/pivot-table/freeze-panes/index.d.ts +115 -0
- package/src/pivot-table/freeze-panes/index.js +143 -0
- package/src/pivot-table/freeze-panes/sticky-strategy.d.ts +38 -0
- package/src/pivot-table/freeze-panes/sticky-strategy.js +247 -0
- package/src/pivot-table/freeze-panes/transform-strategy.d.ts +61 -0
- package/src/pivot-table/freeze-panes/transform-strategy.js +131 -0
- package/src/pivot.css +2 -98
- package/src/published_items_renderer.d.ts +10 -0
- package/src/seriesPointStyles-helper.d.ts +2 -0
- package/src/smart_queries_helper.d.ts +12 -0
- package/src/value.formatter.d.ts +3 -0
- package/tests/dr-renderer-helpers.test.js +29 -0
- package/tests/pivot-table/freeze-panes/constants.test.js +92 -0
- package/tests/pivot-table/freeze-panes/index.test.js +193 -0
- package/tests/pivot-table/freeze-panes/sticky-strategy.test.js +542 -0
- package/tests/pivot-table/freeze-panes/transform-strategy.test.js +304 -0
- package/tsconfig.json +7 -10
- package/src/types/index.d.ts +0 -12
- package/tsconfig.tsbuildinfo +0 -1
- /package/src/{types/errors.d.ts → errors.d.ts} +0 -0
- /package/src/{types/options → options}/builders.d.ts +0 -0
- /package/src/{types/options → options}/constants.d.ts +0 -0
- /package/src/{types/options → options}/elements.d.ts +0 -0
- /package/src/{types/options → options}/helpers.d.ts +0 -0
- /package/src/{types/options → options}/index.d.ts +0 -0
- /package/src/{types/options → options}/presets.d.ts +0 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Sticky-based freeze panes strategy.
|
|
4
|
+
* Uses CSS position: sticky to keep headers in place during scrolling.
|
|
5
|
+
* @module @datarailsshared/dr_renderer/pivot-table/freeze-panes/sticky-strategy
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { STICKY_CSS_CLASSES, FREEZE_PANES_THRESHOLD, FREEZE_PANES_THRESHOLD_CHECK_DEBOUNCE_MS } = require('./constants');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* CSS class strings for freeze pane elements.
|
|
12
|
+
* @typedef {import('./index').FreezePanesClassStrings} FreezePanesClassStrings
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Table information for freeze panes initialization.
|
|
17
|
+
* @typedef {import('./index').FreezePanesTableInfo} FreezePanesTableInfo
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Result of freeze panes initialization.
|
|
22
|
+
* @typedef {import('./index').FreezePanesInitResult} FreezePanesInitResult
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Threshold check result indicating which freeze behaviors are enabled.
|
|
27
|
+
* @typedef {Object} ThresholdResult
|
|
28
|
+
* @property {boolean} freezeRows - Whether rows should be frozen (vertical sticky).
|
|
29
|
+
* @property {boolean} freezeColumns - Whether columns should be frozen (horizontal sticky).
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Creates a debounced version of a function.
|
|
34
|
+
* @param {() => void} func - The function to debounce.
|
|
35
|
+
* @param {number} wait - The number of milliseconds to delay.
|
|
36
|
+
* @returns {() => void} The debounced function.
|
|
37
|
+
*/
|
|
38
|
+
function debounce(func, wait) {
|
|
39
|
+
/** @type {ReturnType<typeof setTimeout> | undefined} */
|
|
40
|
+
let timeout;
|
|
41
|
+
return function executedFunction() {
|
|
42
|
+
clearTimeout(timeout);
|
|
43
|
+
timeout = setTimeout(() => func(), wait);
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Gets class strings for sticky mode.
|
|
49
|
+
* @param {boolean} enabled - Whether freeze panes is enabled.
|
|
50
|
+
* @returns {FreezePanesClassStrings} Object with horizontal, vertical, and axis class strings.
|
|
51
|
+
*/
|
|
52
|
+
function getClassStrings(enabled) {
|
|
53
|
+
if (!enabled) {
|
|
54
|
+
return { horizontal: '', vertical: '', axis: '' };
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
horizontal: ' ' + STICKY_CSS_CLASSES.HORIZONTAL,
|
|
58
|
+
vertical: ' ' + STICKY_CSS_CLASSES.VERTICAL,
|
|
59
|
+
axis: ' ' + STICKY_CSS_CLASSES.AXIS,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Applies the sticky container class to enable proper sticky behavior.
|
|
65
|
+
* @param {HTMLElement} container - The container element.
|
|
66
|
+
* @returns {void}
|
|
67
|
+
*/
|
|
68
|
+
function applyContainerClass(container) {
|
|
69
|
+
container.classList.add(STICKY_CSS_CLASSES.CONTAINER);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Calculates the width of each frozen column level by examining cells with rowcol classes.
|
|
74
|
+
* This handles subtotal rows where multiple <tr> elements share the same row class.
|
|
75
|
+
* @param {HTMLTableSectionElement} tbody - The table body element.
|
|
76
|
+
* @param {number} rowAttrsLength - Number of row attributes (frozen columns).
|
|
77
|
+
* @returns {number[]} Array of widths for each column level.
|
|
78
|
+
*/
|
|
79
|
+
function getColumnWidths(tbody, rowAttrsLength) {
|
|
80
|
+
if (!tbody || rowAttrsLength === 0) return [];
|
|
81
|
+
|
|
82
|
+
const widths = new Array(rowAttrsLength).fill(0);
|
|
83
|
+
|
|
84
|
+
const horizontalCells = tbody.querySelectorAll('.' + STICKY_CSS_CLASSES.HORIZONTAL);
|
|
85
|
+
|
|
86
|
+
horizontalCells.forEach(function (cell) {
|
|
87
|
+
if (cell.classList.contains('pvtRowSubtotal')) return;
|
|
88
|
+
|
|
89
|
+
for (let i = 0; i < rowAttrsLength; i++) {
|
|
90
|
+
if (cell.classList.contains('rowcol' + i)) {
|
|
91
|
+
widths[i] = Math.max(widths[i], /** @type {HTMLElement} */(cell).offsetWidth);
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
return widths;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Checks if freeze panes should be disabled based on threshold.
|
|
102
|
+
* @param {HTMLElement} container - The container element.
|
|
103
|
+
* @param {HTMLTableElement} table - The table element.
|
|
104
|
+
* @param {number} rowAttrsLength - Number of row attributes (columns in row headers).
|
|
105
|
+
* @returns {ThresholdResult} Object with freezeRows and freezeColumns booleans.
|
|
106
|
+
*/
|
|
107
|
+
function checkThreshold(container, table, rowAttrsLength) {
|
|
108
|
+
const containerWidth = container.clientWidth;
|
|
109
|
+
const containerHeight = container.clientHeight;
|
|
110
|
+
|
|
111
|
+
if (containerWidth === 0 || containerHeight === 0) {
|
|
112
|
+
return { freezeRows: true, freezeColumns: true };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
let frozenRowsHeight = 0;
|
|
116
|
+
const thead = table.querySelector('thead');
|
|
117
|
+
if (thead) {
|
|
118
|
+
const headerRows = thead.querySelectorAll('tr');
|
|
119
|
+
headerRows.forEach(function (row) {
|
|
120
|
+
frozenRowsHeight += row.offsetHeight;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let frozenColumnsWidth = 0;
|
|
125
|
+
const tbody = table.querySelector('tbody');
|
|
126
|
+
if (tbody && rowAttrsLength > 0) {
|
|
127
|
+
const columnWidths = getColumnWidths(tbody, rowAttrsLength);
|
|
128
|
+
frozenColumnsWidth = columnWidths.reduce(function (sum, width) {
|
|
129
|
+
return sum + width;
|
|
130
|
+
}, 0);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
freezeRows: frozenRowsHeight / containerHeight < FREEZE_PANES_THRESHOLD,
|
|
135
|
+
freezeColumns: rowAttrsLength === 0 || frozenColumnsWidth / containerWidth < FREEZE_PANES_THRESHOLD
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Calculates and applies sticky positions for multi-level headers.
|
|
141
|
+
* @param {HTMLTableElement} table - The table element.
|
|
142
|
+
* @param {number} rowAttrsLength - Number of row attributes (columns in row headers).
|
|
143
|
+
* @param {ThresholdResult} [options] - Options for freeze panes.
|
|
144
|
+
* @returns {void}
|
|
145
|
+
*/
|
|
146
|
+
function calculateStickyPositions(table, rowAttrsLength, options) {
|
|
147
|
+
if (!table) return;
|
|
148
|
+
|
|
149
|
+
const freezeRows = options ? options.freezeRows : true;
|
|
150
|
+
const freezeColumns = options ? options.freezeColumns : true;
|
|
151
|
+
|
|
152
|
+
const thead = table.querySelector('thead');
|
|
153
|
+
|
|
154
|
+
if (thead && freezeRows) {
|
|
155
|
+
const headerRows = thead.querySelectorAll('tr');
|
|
156
|
+
let topOffset = 0;
|
|
157
|
+
headerRows.forEach(function (row) {
|
|
158
|
+
const cells = row.querySelectorAll('th, td');
|
|
159
|
+
let leftOffset = 0;
|
|
160
|
+
|
|
161
|
+
cells.forEach(function (cell) {
|
|
162
|
+
if (cell.classList.contains(STICKY_CSS_CLASSES.VERTICAL) ||
|
|
163
|
+
cell.classList.contains(STICKY_CSS_CLASSES.AXIS)) {
|
|
164
|
+
/** @type {HTMLElement} */ (cell).style.top = topOffset + 'px';
|
|
165
|
+
}
|
|
166
|
+
if (cell.classList.contains(STICKY_CSS_CLASSES.AXIS) && freezeColumns) {
|
|
167
|
+
/** @type {HTMLElement} */ (cell).style.left = leftOffset + 'px';
|
|
168
|
+
leftOffset += /** @type {HTMLElement} */ (cell).offsetWidth;
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
topOffset += row.offsetHeight;
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const tbody = table.querySelector('tbody');
|
|
177
|
+
if (tbody && rowAttrsLength > 0 && freezeColumns) {
|
|
178
|
+
const columnWidths = getColumnWidths(tbody, rowAttrsLength);
|
|
179
|
+
const leftOffsets = [0];
|
|
180
|
+
for (let i = 1; i < rowAttrsLength; i++) {
|
|
181
|
+
leftOffsets[i] = leftOffsets[i - 1] + columnWidths[i - 1];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const horizontalCells = tbody.querySelectorAll('.' + STICKY_CSS_CLASSES.HORIZONTAL);
|
|
185
|
+
horizontalCells.forEach(function (cell) {
|
|
186
|
+
for (let i = 0; i < rowAttrsLength; i++) {
|
|
187
|
+
if (cell.classList.contains('rowcol' + i)) {
|
|
188
|
+
/** @type {HTMLElement} */ (cell).style.left = leftOffsets[i] + 'px';
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Applies threshold check and toggles freeze panes classes accordingly.
|
|
198
|
+
* @param {HTMLElement} container - The container element.
|
|
199
|
+
* @param {HTMLTableElement} table - The table element.
|
|
200
|
+
* @param {number} rowAttrsLength - Number of row attributes (columns in row headers).
|
|
201
|
+
* @returns {void}
|
|
202
|
+
*/
|
|
203
|
+
function applyThreshold(container, table, rowAttrsLength) {
|
|
204
|
+
const thresholdResult = checkThreshold(container, table, rowAttrsLength);
|
|
205
|
+
|
|
206
|
+
table.classList.toggle(STICKY_CSS_CLASSES.ROWS_DISABLED, !thresholdResult.freezeRows);
|
|
207
|
+
table.classList.toggle(STICKY_CSS_CLASSES.COLUMNS_DISABLED, !thresholdResult.freezeColumns);
|
|
208
|
+
calculateStickyPositions(table, rowAttrsLength, thresholdResult);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Initializes the sticky strategy.
|
|
213
|
+
* @param {HTMLElement} container - The container element.
|
|
214
|
+
* @param {FreezePanesTableInfo} tableInfo - Table information.
|
|
215
|
+
* @returns {FreezePanesInitResult} Object with destroy function to clean up the observer.
|
|
216
|
+
*/
|
|
217
|
+
function initialize(container, tableInfo) {
|
|
218
|
+
applyContainerClass(container);
|
|
219
|
+
|
|
220
|
+
const table = /** @type {HTMLTableElement | null} */ (container.querySelector('table.pvtTable'));
|
|
221
|
+
|
|
222
|
+
if (!table) {
|
|
223
|
+
return { destroy: function () { } };
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const rowAttrsLength = tableInfo.rowAttrsLength || 0;
|
|
227
|
+
|
|
228
|
+
applyThreshold(container, table, rowAttrsLength);
|
|
229
|
+
|
|
230
|
+
const debouncedApplyThreshold = debounce(function () {
|
|
231
|
+
applyThreshold(container, table, rowAttrsLength);
|
|
232
|
+
}, FREEZE_PANES_THRESHOLD_CHECK_DEBOUNCE_MS);
|
|
233
|
+
|
|
234
|
+
const resizeObserver = new ResizeObserver(debouncedApplyThreshold);
|
|
235
|
+
resizeObserver.observe(container);
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
destroy: function () {
|
|
239
|
+
resizeObserver.disconnect();
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
module.exports = {
|
|
245
|
+
getClassStrings,
|
|
246
|
+
initialize,
|
|
247
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS class strings for freeze pane elements.
|
|
3
|
+
*/
|
|
4
|
+
export type FreezePanesClassStrings = import("./index").FreezePanesClassStrings;
|
|
5
|
+
/**
|
|
6
|
+
* Table information for freeze panes initialization.
|
|
7
|
+
*/
|
|
8
|
+
export type FreezePanesTableInfo = import("./index").FreezePanesTableInfo;
|
|
9
|
+
/**
|
|
10
|
+
* Result of freeze panes initialization.
|
|
11
|
+
*/
|
|
12
|
+
export type FreezePanesInitResult = import("./index").FreezePanesInitResult;
|
|
13
|
+
/**
|
|
14
|
+
* Mapping of axis types to CSS class names.
|
|
15
|
+
*/
|
|
16
|
+
export type AxisToClassMap = {
|
|
17
|
+
/**
|
|
18
|
+
* - CSS class for horizontal freeze.
|
|
19
|
+
*/
|
|
20
|
+
X: string;
|
|
21
|
+
/**
|
|
22
|
+
* - CSS class for vertical freeze.
|
|
23
|
+
*/
|
|
24
|
+
Y: string;
|
|
25
|
+
/**
|
|
26
|
+
* - CSS class for both axes freeze.
|
|
27
|
+
*/
|
|
28
|
+
XY: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* CSS class strings for freeze pane elements.
|
|
32
|
+
* @typedef {import('./index').FreezePanesClassStrings} FreezePanesClassStrings
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* Table information for freeze panes initialization.
|
|
36
|
+
* @typedef {import('./index').FreezePanesTableInfo} FreezePanesTableInfo
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* Result of freeze panes initialization.
|
|
40
|
+
* @typedef {import('./index').FreezePanesInitResult} FreezePanesInitResult
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* Mapping of axis types to CSS class names.
|
|
44
|
+
* @typedef {Object} AxisToClassMap
|
|
45
|
+
* @property {string} X - CSS class for horizontal freeze.
|
|
46
|
+
* @property {string} Y - CSS class for vertical freeze.
|
|
47
|
+
* @property {string} XY - CSS class for both axes freeze.
|
|
48
|
+
*/
|
|
49
|
+
/**
|
|
50
|
+
* Gets class strings for transform mode.
|
|
51
|
+
* @param {boolean} enabled - Whether freeze panes is enabled.
|
|
52
|
+
* @returns {FreezePanesClassStrings} Object with horizontal, vertical, and axis class strings.
|
|
53
|
+
*/
|
|
54
|
+
export function getClassStrings(enabled: boolean): FreezePanesClassStrings;
|
|
55
|
+
/**
|
|
56
|
+
* Initializes the transform strategy.
|
|
57
|
+
* @param {HTMLElement} container - The container element.
|
|
58
|
+
* @param {FreezePanesTableInfo} [_tableInfo] - Table information (unused in transform strategy).
|
|
59
|
+
* @returns {FreezePanesInitResult} Object with destroy function to clean up the scroll handler.
|
|
60
|
+
*/
|
|
61
|
+
export function initialize(container: HTMLElement, _tableInfo?: FreezePanesTableInfo): FreezePanesInitResult;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Transform-based freeze panes strategy.
|
|
4
|
+
* Uses CSS transforms to keep headers in place during scrolling.
|
|
5
|
+
* @module @datarailsshared/dr_renderer/pivot-table/freeze-panes/transform-strategy
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { TRANSFORM_CSS_CLASSES } = require('./constants');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* CSS class strings for freeze pane elements.
|
|
12
|
+
* @typedef {import('./index').FreezePanesClassStrings} FreezePanesClassStrings
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Table information for freeze panes initialization.
|
|
17
|
+
* @typedef {import('./index').FreezePanesTableInfo} FreezePanesTableInfo
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Result of freeze panes initialization.
|
|
22
|
+
* @typedef {import('./index').FreezePanesInitResult} FreezePanesInitResult
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Mapping of axis types to CSS class names.
|
|
27
|
+
* @typedef {Object} AxisToClassMap
|
|
28
|
+
* @property {string} X - CSS class for horizontal freeze.
|
|
29
|
+
* @property {string} Y - CSS class for vertical freeze.
|
|
30
|
+
* @property {string} XY - CSS class for both axes freeze.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Gets class strings for transform mode.
|
|
35
|
+
* @param {boolean} enabled - Whether freeze panes is enabled.
|
|
36
|
+
* @returns {FreezePanesClassStrings} Object with horizontal, vertical, and axis class strings.
|
|
37
|
+
*/
|
|
38
|
+
function getClassStrings(enabled) {
|
|
39
|
+
if (!enabled) {
|
|
40
|
+
return { horizontal: '', vertical: '', axis: '' };
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
horizontal: ' ' + TRANSFORM_CSS_CLASSES.HORIZONTAL,
|
|
44
|
+
vertical: ' ' + TRANSFORM_CSS_CLASSES.VERTICAL,
|
|
45
|
+
axis: ' ' + TRANSFORM_CSS_CLASSES.AXIS,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Mapping of axis types to class names.
|
|
51
|
+
* @type {AxisToClassMap}
|
|
52
|
+
*/
|
|
53
|
+
const elementToTransform = {
|
|
54
|
+
X: ' ' + TRANSFORM_CSS_CLASSES.HORIZONTAL,
|
|
55
|
+
Y: ' ' + TRANSFORM_CSS_CLASSES.VERTICAL,
|
|
56
|
+
XY: ' ' + TRANSFORM_CSS_CLASSES.AXIS,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Selects all freezable elements within a container.
|
|
61
|
+
* @param {HTMLElement} wrapper - The container element.
|
|
62
|
+
* @returns {HTMLElement[]} Array of freezable elements.
|
|
63
|
+
*/
|
|
64
|
+
function selectFreezableElements(wrapper) {
|
|
65
|
+
const selectString = Object.values(elementToTransform)
|
|
66
|
+
.map(function(item) {
|
|
67
|
+
return '.' + item.replace(' ', '');
|
|
68
|
+
})
|
|
69
|
+
.join(',');
|
|
70
|
+
return /** @type {HTMLElement[]} */ (Array.from(wrapper.querySelectorAll(selectString)));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Creates a scroll handler for freeze panes.
|
|
75
|
+
* @param {HTMLElement[]} freezableElements - Elements to transform on scroll.
|
|
76
|
+
* @returns {(event: Event) => void} Scroll event handler.
|
|
77
|
+
*/
|
|
78
|
+
function createScrollHandler(freezableElements) {
|
|
79
|
+
return function(event) {
|
|
80
|
+
const target = /** @type {HTMLElement & { dataset: DOMStringMap }} */ (event.target);
|
|
81
|
+
if (target.dataset.canFreezePanes) return;
|
|
82
|
+
|
|
83
|
+
const wrapper = target;
|
|
84
|
+
|
|
85
|
+
const translateY = 'translate(0px, ' + wrapper.scrollTop + 'px)';
|
|
86
|
+
const translateX = 'translate(' + wrapper.scrollLeft + 'px, 0px)';
|
|
87
|
+
const translateXY = 'translate(' + wrapper.scrollLeft + 'px, ' + wrapper.scrollTop + 'px)';
|
|
88
|
+
|
|
89
|
+
freezableElements.forEach(function(element) {
|
|
90
|
+
let currentTranslate = translateY;
|
|
91
|
+
currentTranslate = element.className.includes(elementToTransform.X) ? translateX : currentTranslate;
|
|
92
|
+
currentTranslate = element.className.includes(elementToTransform.XY) ? translateXY : currentTranslate;
|
|
93
|
+
element.style.transform = currentTranslate;
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Attaches a scroll handler to the container for freeze panes.
|
|
100
|
+
* @param {HTMLElement} container - The container element to attach the scroll handler to.
|
|
101
|
+
* @returns {HTMLElement[]} Array of freezable elements for later cleanup.
|
|
102
|
+
*/
|
|
103
|
+
function attachScrollHandler(container) {
|
|
104
|
+
const freezableElements = selectFreezableElements(container);
|
|
105
|
+
container.onscroll = createScrollHandler(freezableElements);
|
|
106
|
+
return freezableElements;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Initializes the transform strategy.
|
|
111
|
+
* @param {HTMLElement} container - The container element.
|
|
112
|
+
* @param {FreezePanesTableInfo} [_tableInfo] - Table information (unused in transform strategy).
|
|
113
|
+
* @returns {FreezePanesInitResult} Object with destroy function to clean up the scroll handler.
|
|
114
|
+
*/
|
|
115
|
+
function initialize(container, _tableInfo) {
|
|
116
|
+
const freezableElements = attachScrollHandler(container);
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
destroy: function() {
|
|
120
|
+
container.onscroll = null;
|
|
121
|
+
freezableElements.forEach(function(element) {
|
|
122
|
+
element.style.transform = '';
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
module.exports = {
|
|
129
|
+
getClassStrings,
|
|
130
|
+
initialize,
|
|
131
|
+
};
|
package/src/pivot.css
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@import './pivot-table/freeze-panes/freeze-panes.css';
|
|
2
|
+
|
|
1
3
|
.pvtUi { color: #333; }
|
|
2
4
|
|
|
3
5
|
.pivot-wrapper {
|
|
@@ -146,21 +148,6 @@ table.pvtTable .pvtAxisLabel {
|
|
|
146
148
|
white-space: nowrap;
|
|
147
149
|
}
|
|
148
150
|
|
|
149
|
-
table.pvtTable .axis-freeze-pane {
|
|
150
|
-
position: relative;
|
|
151
|
-
z-index: 100;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
table.pvtTable .vertical-freeze-pane {
|
|
155
|
-
position: relative;
|
|
156
|
-
z-index: 50;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
table.pvtTable .horizontal-freeze-pane {
|
|
160
|
-
position: relative;
|
|
161
|
-
z-index: 50;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
151
|
.pvtRowSubtotal {
|
|
165
152
|
background-color: #EFEFEF !important;
|
|
166
153
|
font-weight:bold;
|
|
@@ -283,89 +270,6 @@ table.pvtTable.newPvtTable tbody tr td {
|
|
|
283
270
|
vertical-align: middle;
|
|
284
271
|
}
|
|
285
272
|
|
|
286
|
-
table.pvtTable thead tr th.axis-freeze-pane:before,
|
|
287
|
-
table.pvtTable thead tr th.vertical-freeze-pane:before,
|
|
288
|
-
table.pvtTable.newPvtTable thead tr th.axis-freeze-pane:before,
|
|
289
|
-
table.pvtTable.newPvtTable thead tr th.vertical-freeze-pane:before {
|
|
290
|
-
content: '';
|
|
291
|
-
width: calc(100% + 1px);
|
|
292
|
-
height: 1px;
|
|
293
|
-
background: white;
|
|
294
|
-
position: absolute;
|
|
295
|
-
top: -1px;
|
|
296
|
-
left: 0;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
table.pvtTable thead tr th.axis-freeze-pane:before,
|
|
300
|
-
table.pvtTable thead tr th.vertical-freeze-pane:before {
|
|
301
|
-
background: #cdcdcd;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
table.pvtTable thead tr th.axis-freeze-pane:after,
|
|
305
|
-
table.pvtTable thead tr th.vertical-freeze-pane:after,
|
|
306
|
-
table.pvtTable.newPvtTable thead tr th.axis-freeze-pane:after,
|
|
307
|
-
table.pvtTable.newPvtTable thead tr th.vertical-freeze-pane:after {
|
|
308
|
-
content: '';
|
|
309
|
-
width: 1px;
|
|
310
|
-
height: 100%;
|
|
311
|
-
background: white;
|
|
312
|
-
position: absolute;
|
|
313
|
-
right: -1px;
|
|
314
|
-
top: 0;
|
|
315
|
-
}
|
|
316
|
-
table.pvtTable thead tr th.axis-freeze-pane:after,
|
|
317
|
-
table.pvtTable thead tr th.vertical-freeze-pane:after {
|
|
318
|
-
background: #cdcdcd;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
table.pvtTable tbody tr th.horizontal-freeze-pane:before,
|
|
322
|
-
table.pvtTable tbody tr td.horizontal-freeze-pane:before,
|
|
323
|
-
table.pvtTable.newPvtTable tbody tr th.horizontal-freeze-pane:before,
|
|
324
|
-
table.pvtTable.newPvtTable tbody tr td.horizontal-freeze-pane:before {
|
|
325
|
-
content: '';
|
|
326
|
-
width: calc(100% + 1px);
|
|
327
|
-
height: 1px;
|
|
328
|
-
background: #dfe6ec;
|
|
329
|
-
position: absolute;
|
|
330
|
-
top: -1px;
|
|
331
|
-
left: 0;
|
|
332
|
-
}
|
|
333
|
-
table.pvtTable tbody tr th.horizontal-freeze-pane:before,
|
|
334
|
-
table.pvtTable tbody tr td.horizontal-freeze-pane:before {
|
|
335
|
-
background: #cdcdcd;
|
|
336
|
-
}
|
|
337
|
-
table.pvtTable tbody tr th.colTotal.horizontal-freeze-pane:before,
|
|
338
|
-
table.pvtTable tbody tr td.colTotal.horizontal-freeze-pane:before {
|
|
339
|
-
background: transparent;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
table.pvtTable tbody tr th.horizontal-freeze-pane:after,
|
|
343
|
-
table.pvtTable tbody tr td.horizontal-freeze-pane:after,
|
|
344
|
-
table.pvtTable.newPvtTable tbody tr th.horizontal-freeze-pane:after,
|
|
345
|
-
table.pvtTable.newPvtTable tbody tr td.horizontal-freeze-pane:after {
|
|
346
|
-
content: '';
|
|
347
|
-
width: 1px;
|
|
348
|
-
height: 100%;
|
|
349
|
-
background: #dfe6ec;
|
|
350
|
-
position: absolute;
|
|
351
|
-
right: -1px;
|
|
352
|
-
top: 0;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
table.pvtTable tbody tr th.horizontal-freeze-pane:after,
|
|
356
|
-
table.pvtTable tbody tr td.horizontal-freeze-pane:after {
|
|
357
|
-
background: #cdcdcd;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
table.pvtTable.newPvtTable tbody tr th.horizontal-freeze-pane.colTotal:after {
|
|
361
|
-
background: #fff;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
table.pvtTable.colorized:not(.newPvtTable) tbody tr th.horizontal-freeze-pane,
|
|
365
|
-
table.pvtTable.newPvtTable.colorized tbody tr th.horizontal-freeze-pane:not(.highlighted):not(.colTotal) {
|
|
366
|
-
background-color: #fff !important;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
273
|
table.pvtTable.newPvtTable tbody tr th {
|
|
370
274
|
vertical-align: top;
|
|
371
275
|
padding-top: 2.5px;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export = getPublishedItemsRenderer;
|
|
2
|
+
declare function getPublishedItemsRenderer(publishedItemsRenderer: any): void;
|
|
3
|
+
declare class getPublishedItemsRenderer {
|
|
4
|
+
constructor(publishedItemsRenderer: any);
|
|
5
|
+
document: {};
|
|
6
|
+
scope: {};
|
|
7
|
+
options: {};
|
|
8
|
+
isScenarioMode: any;
|
|
9
|
+
settings: {};
|
|
10
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param tree {DRPivotData['tree']}
|
|
3
|
+
* @param rowKey {string[]} ['6+6', 'Forecast 6+6 Mid'] OR ['6+6', 'SQ_Actuals']
|
|
4
|
+
* @param flatColKey {string} 'Jan-25'
|
|
5
|
+
* @returns {object|null} A aggregator object of SQ_Actuals or null if not found
|
|
6
|
+
*/
|
|
7
|
+
export function getSqAggregator(tree: DRPivotData["tree"], rowKey: string[], flatColKey: string): object | null;
|
|
8
|
+
export function handleForecastSeries(chart_series: any, chartOptions: any, pivotData: any): any;
|
|
9
|
+
export namespace DR_SCENARIO {
|
|
10
|
+
let SQ_Actuals: string;
|
|
11
|
+
let Forecast: string;
|
|
12
|
+
}
|
|
@@ -196,4 +196,33 @@ describe('dr-renderer-helpers', () => {
|
|
|
196
196
|
});
|
|
197
197
|
});
|
|
198
198
|
});
|
|
199
|
+
|
|
200
|
+
describe('isShowingEmptyValues', () => {
|
|
201
|
+
it('should return true when additionOptions is undefined', () => {
|
|
202
|
+
expect(drRendererHelpers.isShowingEmptyValues(undefined)).toBe(true);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it('should return true when additionOptions is null', () => {
|
|
206
|
+
expect(drRendererHelpers.isShowingEmptyValues(null)).toBe(true);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('should return true when additionOptions.chart is undefined', () => {
|
|
210
|
+
expect(drRendererHelpers.isShowingEmptyValues({})).toBe(true);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('should return true when dislay_empty_values is not false', () => {
|
|
214
|
+
expect(drRendererHelpers.isShowingEmptyValues({ chart: {} })).toBe(true);
|
|
215
|
+
expect(drRendererHelpers.isShowingEmptyValues({ chart: { dislay_empty_values: true } })).toBe(true);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('should return false when dislay_empty_values is false', () => {
|
|
219
|
+
expect(drRendererHelpers.isShowingEmptyValues({ chart: { dislay_empty_values: false } })).toBe(false);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
describe('DELIMER', () => {
|
|
224
|
+
it('should be " , "', () => {
|
|
225
|
+
expect(drRendererHelpers.DELIMER).toBe(' , ');
|
|
226
|
+
});
|
|
227
|
+
});
|
|
199
228
|
});
|