@datarailsshared/dr_renderer 1.4.57 → 1.4.59

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datarailsshared/dr_renderer",
3
- "version": "1.4.57",
3
+ "version": "1.4.59",
4
4
  "description": "DataRails charts and tables renderer",
5
5
  "keywords": [
6
6
  "datarails",
@@ -1983,14 +1983,10 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
1983
1983
  };
1984
1984
 
1985
1985
  highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart = function (pivotData, chartOptions, additionOptions, opts) {
1986
-
1987
1986
  var pie_drill_down_series = [],
1988
1987
  row_n_keys = pivotData.getRowKeys(),
1989
1988
  col_n_keys = pivotData.getColKeys();
1990
1989
 
1991
- var num_cols = col_n_keys.length;
1992
- var num_rows = row_n_keys.length;
1993
-
1994
1990
  const othersName = highchartsRenderer.getOthersName(opts);
1995
1991
 
1996
1992
  lodash.forEach(col_n_keys, function (col_n_value) {
@@ -2009,19 +2005,17 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
2009
2005
  col_ob.name = highchartsRenderer.getFormattedColKey(col_ob.initialName, pivotData);
2010
2006
  col_ob.data = [];
2011
2007
  lodash.forEach(row_n_keys, function (row_n_value) {
2012
- var agg = pivotData.getAggregator(row_n_value, col_n_value);
2008
+ // always takes the first key during drilldown,
2009
+ // we are only supporting one level drilldown but pivot table could have multiple nested row keys
2010
+ const rowKey = [row_n_value[0]];
2011
+ var agg = pivotData.getAggregator(rowKey, col_n_value);
2013
2012
  var val = agg.value();
2014
- if (val != null && row_n_value[0]) {
2013
+ if (val != null && rowKey[0]) {
2015
2014
  if ($.isNumeric(val)) {
2016
2015
  val = parseFloat(val);
2017
- // if (val > -1 && val < 1) {
2018
- // val = parseFloat(val.toPrecision(4));
2019
- // } else {
2020
- // val = parseFloat(val.toFixed(2));
2021
- // }
2022
2016
  }
2023
2017
 
2024
- const row_initial_name = row_n_value[0] === highchartsRenderer.DR_OTHERS_KEY ? othersName : row_n_value[0];
2018
+ const row_initial_name = rowKey[0] === highchartsRenderer.DR_OTHERS_KEY ? othersName : rowKey;
2025
2019
  const row_name = highchartsRenderer.getFormattedRowKey(row_initial_name, pivotData);
2026
2020
  col_ob.data.push({
2027
2021
  name: row_name,
@@ -2031,6 +2025,10 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
2031
2025
  }
2032
2026
  });
2033
2027
  if (col_ob.data.length) {
2028
+ // filtering out when there are multiple data series
2029
+ col_ob.data = lodash.uniqBy(col_ob.data, item =>
2030
+ Array.isArray(item.name) ? item.name.join(highchartsRenderer.delimer) : item.name
2031
+ );
2034
2032
  pie_drill_down_series.push(col_ob);
2035
2033
  }
2036
2034
  }
@@ -3195,95 +3193,6 @@ let getHighchartsRenderer = function ($, document, Highcharts, default_colors, h
3195
3193
  return highchartsRenderer.ptCreateElementAndDraw(chartOptions, opts);
3196
3194
  };
3197
3195
 
3198
- highchartsRenderer.ptRenderColumnWithDrilldown = function (pivotData, opts, drilldownFunc) {
3199
- var chartOptions = {};
3200
- var additionOptions = opts.chartOptions ? opts.chartOptions : highchartsRenderer.getDefaultValueForChart('column-chart-drilldown');
3201
-
3202
-
3203
- chartOptions.chart = {
3204
- type: 'column',
3205
- events: {
3206
- 'drilldown': function (e) {
3207
- highchartsRenderer.modifyEventPointForDrilldown(e);
3208
- if (drilldownFunc)
3209
- drilldownFunc(e, this, "drilldown");
3210
-
3211
- },
3212
- 'drillup': function (e) {
3213
- if (drilldownFunc)
3214
- drilldownFunc(e, this, "drillup");
3215
-
3216
- }
3217
-
3218
- }
3219
- };
3220
- if (disableAnimation) {
3221
- chartOptions.chart.animation = false;
3222
- }
3223
- highchartsRenderer.setTitleAndSubTitle(chartOptions, opts, additionOptions);
3224
-
3225
- chartOptions.yAxis = {
3226
- min: null,
3227
- max: null,
3228
- title: {
3229
- text: additionOptions && additionOptions.axisY ? additionOptions.axisY.name : ''
3230
- },
3231
- labels: {
3232
- formatter: highchartsRenderer.defaultValueLabelsFormatter(pivotData, opts)
3233
- }
3234
- };
3235
- if (additionOptions) {
3236
- highchartsRenderer.setYAxisMinMax(chartOptions.yAxis, additionOptions.axisY);
3237
- }
3238
-
3239
- chartOptions.legend = {enabled: false};
3240
-
3241
- chartOptions.plotOptions = {
3242
- series: {
3243
- animation: !disableAnimation,
3244
- borderWidth: 0,
3245
- cropThreshold: 1000,
3246
- dataLabels: {
3247
- allowOverlap: additionOptions && additionOptions.label ? additionOptions.label.overlap : false,
3248
- enabled: additionOptions && additionOptions.label ? additionOptions.label.show : true,
3249
- formatter: highchartsRenderer.defaultDataLabelFormatter(pivotData, opts),
3250
- style: highchartsRenderer.getDataLabelsStyle(additionOptions)
3251
- }
3252
- },
3253
- column: {
3254
- borderRadius: 1,
3255
- }
3256
- };
3257
-
3258
- chartOptions.tooltip = {
3259
- formatter: function () {
3260
- var y = parseFloat(this.y);
3261
- var agg = pivotData.getAggregator([], []);
3262
- if (agg) {
3263
- return '<b>' + this.point.name + '</b>: ' + agg.format(y, true);
3264
- } else {
3265
- return '<b>' + this.point.name + '</b>: ' + y.toLocaleString();
3266
- }
3267
- },
3268
- };
3269
-
3270
- chartOptions.xAxis = {
3271
- type: 'category',
3272
- };
3273
- chartOptions = highchartsRenderer.prepareAxisX(chartOptions, additionOptions, pivotData.getColKeys());
3274
- chartOptions.series = highchartsRenderer.ptCreateSeriesToDrillDownChart(pivotData, chartOptions, additionOptions, opts);
3275
- //if (drilldownFunc)
3276
- // chartOptions.drilldown = {}
3277
- //else
3278
- chartOptions.drilldown = highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart(pivotData, chartOptions, additionOptions, opts);
3279
-
3280
- highchartsRenderer.handleGridLines(additionOptions, chartOptions)
3281
-
3282
- helpers.disableLegendInteractionIfRequired(chartOptions, additionOptions);
3283
-
3284
- return highchartsRenderer.ptCreateElementAndDraw(chartOptions, opts);
3285
- };
3286
-
3287
3196
  highchartsRenderer.ptRenderBar = function (pivotData, opts) {
3288
3197
  var chartOptions = {};
3289
3198
  var rowAttrs = pivotData.rowAttrs;
@@ -0,0 +1,491 @@
1
+ import * as JQuery from "jquery";
2
+ import * as lodash from 'lodash';
3
+ import moment from 'moment/min/moment.min';
4
+ import initPivotTable from "../src/pivottable";
5
+ import initDRPivotTable from "../src/dr_pivottable";
6
+
7
+ const getHighchartsRenderer = require('../src/highcharts_renderer');
8
+ const DataFormatter = require('../src/dataformatter');
9
+
10
+ global.$ = JQuery;
11
+ global.lodash = lodash;
12
+
13
+ const Highcharts = {
14
+ Color: jest.fn(),
15
+ chart: jest.fn(),
16
+ setOptions: jest.fn(),
17
+ wrap: jest.fn(),
18
+ Tooltip: {
19
+ prototype: {
20
+ hide: jest.fn()
21
+ }
22
+ },
23
+ Point: {
24
+ prototype: {
25
+ setState: jest.fn()
26
+ }
27
+ },
28
+ Series: {
29
+ prototype: {
30
+ setState: jest.fn()
31
+ }
32
+ },
33
+ defaultOptions: {
34
+ global: {
35
+ useUTC: false
36
+ }
37
+ },
38
+ merge: jest.fn((target, source) => Object.assign({}, target, source))
39
+ };
40
+
41
+ const _document = {
42
+ createElement: jest.fn(() => ({
43
+ style: {},
44
+ setAttribute: jest.fn(),
45
+ appendChild: jest.fn()
46
+ })),
47
+ body: {
48
+ appendChild: jest.fn()
49
+ }
50
+ };
51
+
52
+ function createMockAggregator(value) {
53
+ return {
54
+ value: () => value
55
+ };
56
+ }
57
+
58
+
59
+ let highchartsRenderer = {};
60
+
61
+ describe('ptCreateDrillDownSeriesToDrilldownChart', () => {
62
+ let mockPivotData;
63
+ let mockChartOptions;
64
+ let mockAdditionOptions;
65
+ let mockOpts;
66
+
67
+ beforeAll(() => {
68
+ const _window = {
69
+ DataFormatter: DataFormatter
70
+ };
71
+
72
+ initPivotTable(JQuery, _window, _document);
73
+ initDRPivotTable(JQuery, _window, _document);
74
+
75
+ const DEFAULT_USER_COLORS = ['#7cb5ec', '#434348', '#90ed7d', '#f7a35c', '#8085e9', '#f15c80', '#e4d354', '#2b908f', '#f45b5b', '#91e8e1'];
76
+ highchartsRenderer = getHighchartsRenderer(JQuery, _document, Highcharts, lodash.cloneDeep(DEFAULT_USER_COLORS), highchartsRenderer, DataFormatter, lodash, moment, false);
77
+ });
78
+
79
+ beforeEach(() => {
80
+ const createMockAggregator = (value) => ({
81
+ value: () => value
82
+ });
83
+
84
+ mockPivotData = {
85
+ getRowKeys: jest.fn(() => [
86
+ ['CITY SERVICE DEPTS'],
87
+ ['MID-SOUTH'],
88
+ ['NORTH TX'],
89
+ ['SOUTH TX'],
90
+ ['VIRGINIA'],
91
+ ['CAROLINA']
92
+ ]),
93
+ getColKeys: jest.fn(() => [
94
+ ['003-NATIONAL ACCOUNTS'],
95
+ ['015-MEMPHIS'],
96
+ ['016-WICHITA FALLS'],
97
+ ['017-AMARILLO'],
98
+ ['019-AUSTIN'],
99
+ ['020-NORFOLK'],
100
+ ['023-NEWPORT NEWS'],
101
+ ['035-CHARLOTTE CITY SERVICE']
102
+ ]),
103
+ getAggregator: jest.fn((rowKey, colKey) => {
104
+ const rowStr = Array.isArray(rowKey) ? rowKey[0] : rowKey;
105
+ const colStr = Array.isArray(colKey) ? colKey[0] : colKey;
106
+
107
+ const dataMap = {
108
+ 'CITY SERVICE DEPTS,003-NATIONAL ACCOUNTS': 305550.96,
109
+ 'MID-SOUTH,015-MEMPHIS': 78827.94,
110
+ 'NORTH TX,016-WICHITA FALLS': 28926.52,
111
+ 'NORTH TX,017-AMARILLO': 92653.77,
112
+ 'SOUTH TX,019-AUSTIN': 103645.51,
113
+ 'VIRGINIA,020-NORFOLK': 0,
114
+ 'VIRGINIA,023-NEWPORT NEWS': 19997.5,
115
+ 'CAROLINA,035-CHARLOTTE CITY SERVICE': 124248.97
116
+ };
117
+
118
+ const key = `${rowStr},${colStr}`;
119
+ const value = dataMap[key] || null;
120
+
121
+ return createMockAggregator(value);
122
+ }),
123
+ colFormats: [
124
+ {
125
+ type: "Text",
126
+ name: "Br number & Name",
127
+ format: null,
128
+ val_not_convert: []
129
+ }
130
+ ],
131
+ rowFormats: [
132
+ {
133
+ type: "Text",
134
+ name: "Area",
135
+ format: null,
136
+ val_not_convert: []
137
+ }
138
+ ]
139
+ };
140
+
141
+ mockChartOptions = {
142
+ chart: {
143
+ type: 'pie'
144
+ }
145
+ };
146
+
147
+ mockAdditionOptions = {
148
+ dataLabels: {
149
+ color: '#151a41'
150
+ }
151
+ };
152
+
153
+ mockOpts = {
154
+ total_value_options: {
155
+ filter_options: {
156
+ filteredOutFieldName: 'Others'
157
+ }
158
+ }
159
+ };
160
+
161
+ jest.spyOn(highchartsRenderer, 'getFormattedColKey').mockImplementation((name) => name);
162
+ jest.spyOn(highchartsRenderer, 'getFormattedRowKey').mockImplementation((name) => Array.isArray(name) ? name : [name]);
163
+ jest.spyOn(highchartsRenderer, 'moveSeriesToSecondYAxisIfNeeded').mockImplementation(() => {});
164
+ jest.spyOn(highchartsRenderer, 'getDataLabelsStylesForDrillDown').mockReturnValue({
165
+ activeDataLabelStyle: {
166
+ color: '#151a41'
167
+ }
168
+ });
169
+ });
170
+
171
+ afterEach(() => {
172
+ jest.restoreAllMocks();
173
+ });
174
+
175
+ describe('with valid pivot data', () => {
176
+ it('should create drill-down series correctly', () => {
177
+ const result = highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart(
178
+ mockPivotData,
179
+ mockChartOptions,
180
+ mockAdditionOptions,
181
+ mockOpts
182
+ );
183
+
184
+ // Verify the structure of the result
185
+ expect(result).toHaveProperty('activeDataLabelStyle');
186
+ expect(result).toHaveProperty('series');
187
+ expect(result.activeDataLabelStyle).toEqual({
188
+ color: '#151a41'
189
+ });
190
+
191
+ // Verify series structure
192
+ expect(Array.isArray(result.series)).toBe(true);
193
+ expect(result.series.length).toBe(7);
194
+
195
+ // Check first series (003-NATIONAL ACCOUNTS)
196
+ const firstSeries = result.series[0];
197
+ expect(firstSeries).toMatchObject({
198
+ id: '003-NATIONAL ACCOUNTS',
199
+ initialName: '003-NATIONAL ACCOUNTS',
200
+ name: '003-NATIONAL ACCOUNTS',
201
+ data: expect.any(Array)
202
+ });
203
+
204
+ // Verify data points in first series
205
+ expect(firstSeries.data).toHaveLength(1);
206
+ expect(firstSeries.data[0]).toMatchObject({
207
+ name: ['CITY SERVICE DEPTS'],
208
+ initialName: ['CITY SERVICE DEPTS'],
209
+ y: 305550.96
210
+ });
211
+ });
212
+
213
+ it('should handle numeric column IDs correctly', () => {
214
+ // Test with numeric column keys
215
+ mockPivotData.getColKeys.mockReturnValue([
216
+ [123],
217
+ [456]
218
+ ]);
219
+
220
+ mockPivotData.getAggregator.mockImplementation(() => createMockAggregator(100));
221
+
222
+ const result = highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart(
223
+ mockPivotData,
224
+ mockChartOptions,
225
+ mockAdditionOptions,
226
+ mockOpts
227
+ );
228
+
229
+ expect(result.series[0].id).toBe(123);
230
+ expect(result.series[1].id).toBe(456);
231
+ });
232
+
233
+ it('should handle boolean column IDs correctly', () => {
234
+ // Test with boolean column keys
235
+ mockPivotData.getColKeys.mockReturnValue([
236
+ [true],
237
+ [false]
238
+ ]);
239
+
240
+ mockPivotData.getAggregator.mockImplementation(() => createMockAggregator(100));
241
+
242
+ const result = highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart(
243
+ mockPivotData,
244
+ mockChartOptions,
245
+ mockAdditionOptions,
246
+ mockOpts
247
+ );
248
+
249
+ expect(result.series[0].id).toBe('true');
250
+ expect(result.series[1].id).toBe('false');
251
+ });
252
+
253
+ it('should filter out null values', () => {
254
+ mockPivotData.getAggregator.mockImplementation((rowKey, colKey) => {
255
+ const rowStr = Array.isArray(rowKey) ? rowKey[0] : rowKey;
256
+ const colStr = Array.isArray(colKey) ? colKey[0] : colKey;
257
+
258
+ // Return null for specific combinations
259
+ if (rowStr === 'CITY SERVICE DEPTS' && colStr === '015-MEMPHIS') {
260
+ return { value: () => null };
261
+ }
262
+
263
+ return { value: () => 100 };
264
+ });
265
+
266
+ const result = highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart(
267
+ mockPivotData,
268
+ mockChartOptions,
269
+ mockAdditionOptions,
270
+ mockOpts
271
+ );
272
+
273
+ // Find the series for '015-MEMPHIS'
274
+ const memphisSeries = result.series.find(s => s.id === '015-MEMPHIS');
275
+
276
+ // Should not include data point with null value
277
+ expect(memphisSeries.data).not.toContainEqual(
278
+ expect.objectContaining({
279
+ name: ['CITY SERVICE DEPTS']
280
+ })
281
+ );
282
+ });
283
+
284
+ it('should handle undefined column keys', () => {
285
+ mockPivotData.getColKeys.mockReturnValue([
286
+ [undefined],
287
+ ['valid-key']
288
+ ]);
289
+
290
+ mockPivotData.getAggregator.mockImplementation((rowKey, colKey) => {
291
+ return { value: () => 100 }; // Return valid value for all combinations
292
+ });
293
+
294
+ const result = highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart(
295
+ mockPivotData,
296
+ mockChartOptions,
297
+ mockAdditionOptions,
298
+ mockOpts
299
+ );
300
+
301
+ // Should only process series with defined column keys (undefined keys are filtered out)
302
+ expect(result.series).toHaveLength(1);
303
+ expect(result.series[0].id).toBe('valid-key');
304
+ });
305
+
306
+ it('should handle empty row keys', () => {
307
+ mockPivotData.getRowKeys.mockReturnValue([
308
+ [null],
309
+ [''],
310
+ ['valid-row']
311
+ ]);
312
+
313
+ mockPivotData.getAggregator.mockImplementation((rowKey) => {
314
+ const rowStr = Array.isArray(rowKey) ? rowKey[0] : rowKey;
315
+ if (!rowStr) {
316
+ return { value: () => 100 };
317
+ }
318
+ return { value: () => 200 };
319
+ });
320
+
321
+ const result = highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart(
322
+ mockPivotData,
323
+ mockChartOptions,
324
+ mockAdditionOptions,
325
+ mockOpts
326
+ );
327
+
328
+ // Should filter out data points with null/empty row keys
329
+ result.series.forEach(series => {
330
+ series.data.forEach(dataPoint => {
331
+ expect(dataPoint.name[0]).toBeTruthy();
332
+ });
333
+ });
334
+ });
335
+
336
+ it('should convert string numbers to float', () => {
337
+ mockPivotData.getAggregator.mockImplementation(() => ({
338
+ value: () => '123.45' // Return string number
339
+ }));
340
+
341
+ const result = highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart(
342
+ mockPivotData,
343
+ mockChartOptions,
344
+ mockAdditionOptions,
345
+ mockOpts
346
+ );
347
+
348
+ result.series.forEach(series => {
349
+ series.data.forEach(dataPoint => {
350
+ expect(typeof dataPoint.y).toBe('number');
351
+ expect(dataPoint.y).toBe(123.45);
352
+ });
353
+ });
354
+ });
355
+
356
+ it('should remove duplicate data points', () => {
357
+ // Mock duplicate row keys
358
+ mockPivotData.getRowKeys.mockReturnValue([
359
+ ['DUPLICATE'],
360
+ ['DUPLICATE'],
361
+ ['UNIQUE']
362
+ ]);
363
+
364
+ mockPivotData.getAggregator.mockImplementation(() => ({
365
+ value: () => 100
366
+ }));
367
+
368
+ // Mock getFormattedRowKey to return same name for duplicates
369
+ jest.spyOn(highchartsRenderer, 'getFormattedRowKey').mockImplementation((name) => {
370
+ if (Array.isArray(name) && name[0] === 'DUPLICATE') {
371
+ return ['DUPLICATE'];
372
+ }
373
+ return Array.isArray(name) ? name : [name];
374
+ });
375
+
376
+ const result = highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart(
377
+ mockPivotData,
378
+ mockChartOptions,
379
+ mockAdditionOptions,
380
+ mockOpts
381
+ );
382
+
383
+ // Each series should have unique data points
384
+ result.series.forEach(series => {
385
+ const names = series.data.map(d => d.name.join(','));
386
+ const uniqueNames = [...new Set(names)];
387
+ expect(names.length).toBe(uniqueNames.length);
388
+ });
389
+ });
390
+
391
+ it('should call helper functions with correct parameters', () => {
392
+ highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart(
393
+ mockPivotData,
394
+ mockChartOptions,
395
+ mockAdditionOptions,
396
+ mockOpts
397
+ );
398
+
399
+ expect(highchartsRenderer.moveSeriesToSecondYAxisIfNeeded).toHaveBeenCalledWith(
400
+ expect.any(Array),
401
+ mockPivotData,
402
+ mockChartOptions,
403
+ mockAdditionOptions,
404
+ mockOpts
405
+ );
406
+ expect(highchartsRenderer.getDataLabelsStylesForDrillDown).toHaveBeenCalledWith(mockAdditionOptions);
407
+ });
408
+ });
409
+
410
+ describe('edge cases', () => {
411
+ it('should handle empty column keys', () => {
412
+ mockPivotData.getColKeys.mockReturnValue([]);
413
+
414
+ const result = highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart(
415
+ mockPivotData,
416
+ mockChartOptions,
417
+ mockAdditionOptions,
418
+ mockOpts
419
+ );
420
+
421
+ expect(result.series).toHaveLength(0);
422
+ });
423
+
424
+ it('should handle empty row keys', () => {
425
+ mockPivotData.getRowKeys.mockReturnValue([]);
426
+
427
+ const result = highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart(
428
+ mockPivotData,
429
+ mockChartOptions,
430
+ mockAdditionOptions,
431
+ mockOpts
432
+ );
433
+
434
+ // Series should exist but have no data
435
+ result.series.forEach(series => {
436
+ expect(series.data).toHaveLength(0);
437
+ });
438
+ });
439
+
440
+ it('should filter out series with no data', () => {
441
+ // Mock aggregator to return null for all combinations
442
+ mockPivotData.getAggregator.mockImplementation(() => ({
443
+ value: () => null
444
+ }));
445
+
446
+ const result = highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart(
447
+ mockPivotData,
448
+ mockChartOptions,
449
+ mockAdditionOptions,
450
+ mockOpts
451
+ );
452
+
453
+ expect(result.series).toHaveLength(0);
454
+ });
455
+ });
456
+
457
+ describe('with Others key handling', () => {
458
+ it('should replace DR_OTHERS_KEY with othersName', () => {
459
+ // Mock DR_OTHERS_KEY constant
460
+ highchartsRenderer.DR_OTHERS_KEY = 'DR_OTHERS_KEY';
461
+
462
+ mockPivotData.getColKeys.mockReturnValue([
463
+ ['DR_OTHERS_KEY'],
464
+ ['normal-key']
465
+ ]);
466
+
467
+ mockPivotData.getRowKeys.mockReturnValue([
468
+ ['DR_OTHERS_KEY'],
469
+ ['normal-row']
470
+ ]);
471
+
472
+ // Mock aggregator to return valid data
473
+ mockPivotData.getAggregator.mockImplementation((rowKey, colKey) => {
474
+ return { value: () => 100 }; // Return valid value for all combinations
475
+ });
476
+
477
+ const result = highchartsRenderer.ptCreateDrillDownSeriesToDrilldownChart(
478
+ mockPivotData,
479
+ mockChartOptions,
480
+ mockAdditionOptions,
481
+ mockOpts
482
+ );
483
+
484
+ // Check that DR_OTHERS_KEY is replaced with Others name
485
+ const othersColSeries = result.series.find(s => s.initialName === 'Others');
486
+ expect(othersColSeries).toBeDefined();
487
+ expect(othersColSeries.name).toBe('Others');
488
+ });
489
+ });
490
+ });
491
+