@datarailsshared/dr_renderer 1.2.462 → 1.3.1-27.merge

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/src/pivot.css CHANGED
@@ -5,6 +5,17 @@
5
5
  flex-direction: column;
6
6
  }
7
7
 
8
+ .pivot-wrapper .noData--table-many-rows {
9
+ display: flex;
10
+ flex-direction: column;
11
+ }
12
+ .pivot-wrapper .noData--table-many-rows > *:first-child {
13
+ display: flex;
14
+ align-items: center;
15
+ justify-content: center;
16
+ line-height: 25px;
17
+ }
18
+
8
19
  table.pvtTable {
9
20
  font-size: 8pt;
10
21
  text-align: left;
@@ -228,16 +239,27 @@ table.pvtTable.newPvtTable thead tr th {
228
239
  border-right: 1px solid #fff;
229
240
  }
230
241
 
231
- table.pvtTable.newPvtTable thead tr th .fa,
232
- table.pvtTable.newPvtTable thead tr th .dr-icon-add,
233
- table.pvtTable.newPvtTable thead tr th .dr-icon-minus {
234
- padding: 2px;
235
- background-color: #ffffff;
236
- border-radius: 2px;
237
- margin-right: 2px;
238
- margin-left: 1px;
239
- font-size: 8px;
240
- color: #151a41;
242
+ table.pvtTable.newPvtTable thead tr th i,
243
+ table.pvtTable.newPvtTable tbody tr th i {
244
+ position: relative;
245
+ bottom: -1px;
246
+ background-color: #ffffff;
247
+ border-radius: 2px;
248
+ margin-right: 2px;
249
+ margin-left: 1px;
250
+ font-weight: bold;
251
+ font-size: 10px;
252
+ color: #151a41;
253
+ }
254
+
255
+ table.pvtTable.newPvtTable tbody tr th i {
256
+ bottom: -2px;
257
+ background-color: #dfe6ec;
258
+ }
259
+
260
+ table.pvtTable.newPvtTable thead tr th .dr-icon-filter-old,
261
+ table.pvtTable.newPvtTable tbody tr th .dr-icon-filter-old {
262
+ font-weight: normal;
241
263
  }
242
264
 
243
265
  table.pvtTable.newPvtTable.colorized tr th.colTotal,
@@ -261,14 +283,6 @@ table.pvtTable.newPvtTable tbody tr td.rowTotal {
261
283
  border-color: #ffffff !important;
262
284
  }
263
285
 
264
- table.pvtTable.newPvtTable tbody tr th .fa {
265
- padding: 2px;
266
- background-color: #dfe6ec;
267
- border-radius: 2px;
268
- margin-right: 2px;
269
- font-size: 8px;
270
- }
271
-
272
286
  table.pvtTable.newPvtTable tbody tr th,
273
287
  table.pvtTable.newPvtTable tbody tr td {
274
288
  border: 1px solid #dfe6ec;
@@ -25,18 +25,18 @@ let getPublishedItemsRenderer = function (publishedItemsRenderer) {
25
25
  const body = iframeWindow.document.getElementsByTagName("body")[0];
26
26
 
27
27
  if (table && options.responsive) {
28
- publishedItemsRenderer.zoomTable(iframeWindow, table, body);
28
+ publishedItemsRenderer.zoomTable(iframeWindow, table);
29
29
  }
30
30
 
31
31
  publishedItemsRenderer.resizePublishedImage(publish_item_image, iframeWindow, body);
32
32
  }
33
33
 
34
- publishedItemsRenderer.zoomTable = function (iframeWindow, table, body) {
35
- const bodyZoom = parseFloat(body.style.zoom) || 1;
36
- const SCROLL_OFFSET = 16;
34
+ publishedItemsRenderer.zoomTable = function (iframeWindow, table) {
35
+ table.style.zoom = 1;
37
36
 
38
- const tableWidth = table.getBoundingClientRect().width * bodyZoom;
39
- const tableHeight = table.getBoundingClientRect().height * bodyZoom;
37
+ const SCROLL_OFFSET = 16;
38
+ const tableWidth = table.getBoundingClientRect().width;
39
+ const tableHeight = table.getBoundingClientRect().height;
40
40
  const root = iframeWindow.document.documentElement;
41
41
 
42
42
  let requiredZoom = (root.clientWidth - SCROLL_OFFSET) / tableWidth;
@@ -0,0 +1,96 @@
1
+ const lodash = require('lodash');
2
+
3
+ const DR_SCENARIO = {
4
+ SQ_Actuals: 'SQ_Actuals',
5
+ Forecast: 'Forecast',
6
+ };
7
+
8
+ function createSingleDataSeriesForForecast(chart_series, chartOptions, pivotData) {
9
+ const { actuals, forecast, smart_query } = chartOptions.chart;
10
+ const input = pivotData.input;
11
+
12
+ const hasSQActuals = input.some(item => item.Scenario && item.Scenario.indexOf(DR_SCENARIO.SQ_Actuals) !== -1);
13
+ chartOptions.isSmartQueriesEnabled = hasSQActuals;
14
+ if (!smart_query || !hasSQActuals) return null;
15
+
16
+ const midMonthOffset = 0.5
17
+ return chart_series.length === 1
18
+ ? buildChartSeriesFromPivotInputOnly(input, actuals, forecast, midMonthOffset)
19
+ : buildChartSeriesFromSeries(chart_series, actuals, forecast, midMonthOffset);
20
+ }
21
+
22
+ function buildChartSeriesFromPivotInputOnly(input, actuals, forecast, midMonthOffset) {
23
+ const filtered = input.filter(item =>
24
+ (item.Scenario === DR_SCENARIO.SQ_Actuals || item.Scenario === DR_SCENARIO.Forecast) &&
25
+ item.Amount !== 0
26
+ );
27
+
28
+ const data = filtered.map(item => ({
29
+ y: item.Amount,
30
+ name: item.Reporting_Month,
31
+ initialName: item.Reporting_Month,
32
+ type: item.Scenario,
33
+ })).sort((a, b) => new Date(a.name) - new Date(b.name));
34
+
35
+ const sqCount = input.filter(item => item.Scenario === DR_SCENARIO.SQ_Actuals).length;
36
+
37
+ return {
38
+ name: "Forecast Smart Query",
39
+ data,
40
+ zoneAxis: "x",
41
+ zones: [
42
+ { value: sqCount - midMonthOffset, dashStyle: actuals },
43
+ { dashStyle: forecast },
44
+ ],
45
+ };
46
+ }
47
+
48
+ function buildChartSeriesFromSeries(chart_series, actuals, forecast, midMonthOffset) {
49
+ const seriesA = lodash.find(chart_series, s => s.name && lodash.includes(s.name, DR_SCENARIO.SQ_Actuals));
50
+ const seriesB = lodash.find(chart_series, s => s.name && lodash.includes(s.name, DR_SCENARIO.Forecast));
51
+
52
+ if (!seriesA || !seriesB) return null;
53
+
54
+ const indexOfForecastFirstZero = lodash.findIndex(seriesB.data, function(value) {
55
+ return value.y === 0;
56
+ });
57
+ const indexOfActualsFirstZero = lodash.findIndex(seriesA.data, function(value) {
58
+ return value.y === 0;
59
+ });
60
+ const cutoffIndex = Math.max(indexOfForecastFirstZero, indexOfActualsFirstZero);
61
+
62
+
63
+ const minLength = Math.min(seriesA.data.length, seriesB.data.length);
64
+ const data = [];
65
+
66
+ for (let i = 0; i < minLength; i++) {
67
+ const pointA = seriesA.data[i];
68
+ const pointB = seriesB.data[i];
69
+
70
+ const yA = (pointA && pointA.y !== null && typeof pointA.y !== undefined) ? pointA.y : pointA;
71
+ const yB = (pointB && pointB.y !== null && typeof pointB.y !== undefined) ? pointB.y : pointB;
72
+
73
+ data.push({
74
+ x: i,
75
+ y: yA + yB,
76
+ name: pointA && pointA.name ? pointA.name : null,
77
+ initialName: (pointA && pointA.name) ? pointA.name : 'Point ' + (i + 1),
78
+ type: yA ? DR_SCENARIO.SQ_Actuals : DR_SCENARIO.Forecast,
79
+ });
80
+ }
81
+
82
+ return {
83
+ name: "Forecast Smart Query",
84
+ data,
85
+ zoneAxis: "x",
86
+ zones: [
87
+ { value: cutoffIndex - midMonthOffset, dashStyle: actuals },
88
+ { dashStyle: forecast },
89
+ ],
90
+ };
91
+ }
92
+
93
+ module.exports = {
94
+ createSingleDataSeriesForForecast,
95
+ DR_SCENARIO
96
+ };
@@ -147,4 +147,52 @@ describe('dr-renderer-helpers', () => {
147
147
  expect(svg.xCorr).toBe(0);
148
148
  });
149
149
  });
150
+
151
+ describe('disableLegendInteractionIfRequired', () => {
152
+ const notPieTypes = ['column', 'line', 'area', 'areaspline', 'scatter', 'spline', 'bar', 'waterfall'];
153
+
154
+ it('should not update legend settings', () => {
155
+ const chartOptionsMock = {
156
+ chart: {
157
+ type: 'column',
158
+ },
159
+ };
160
+ const additionOptionsMock = {
161
+ disable_legend_interaction: false,
162
+ };
163
+ drRendererHelpers.disableLegendInteractionIfRequired(chartOptionsMock, additionOptionsMock);
164
+ expect(chartOptionsMock.plotOptions).toBeFalsy();
165
+ expect(chartOptionsMock.legend).toBeFalsy();
166
+ });
167
+
168
+ it('should update legend styles and set click event (for pie chart)', () => {
169
+ const chartOptionsMock = {
170
+ chart: {
171
+ type: 'pie',
172
+ },
173
+ };
174
+ const additionOptionsMock = {
175
+ disable_legend_interaction: true,
176
+ };
177
+ drRendererHelpers.disableLegendInteractionIfRequired(chartOptionsMock, additionOptionsMock);
178
+ expect(chartOptionsMock.plotOptions.pie.point.events.legendItemClick).toEqual(jasmine.any(Function));
179
+ expect(chartOptionsMock.legend.itemStyle.cursor).toEqual('default');
180
+ });
181
+
182
+ notPieTypes.forEach((chartType) => {
183
+ it(`should update legend styles and set click event (for ${ chartType } chart)`, () => {
184
+ const chartOptionsMock = {
185
+ chart: {
186
+ type: chartType,
187
+ },
188
+ };
189
+ const additionOptionsMock = {
190
+ disable_legend_interaction: true,
191
+ };
192
+ drRendererHelpers.disableLegendInteractionIfRequired(chartOptionsMock, additionOptionsMock);
193
+ expect(chartOptionsMock.plotOptions.series.events.legendItemClick).toEqual(jasmine.any(Function));
194
+ expect(chartOptionsMock.legend.itemStyle.cursor).toEqual('default');
195
+ });
196
+ });
197
+ });
150
198
  });
@@ -32,6 +32,7 @@ describe("DrChartTooltip", () => {
32
32
  },
33
33
  container: {
34
34
  getBoundingClientRect: jest.fn().mockReturnValue(chartBBoxMock),
35
+ clientWidth: 800,
35
36
  },
36
37
  chartWidth: 800,
37
38
  chartHeight: 600,
@@ -349,6 +350,23 @@ describe("DrChartTooltip", () => {
349
350
  expect(arrowElMock.setAttribute).toHaveBeenCalledWith("style", `${commonStyles}${arrowTopBorderStyles}left:15px`);
350
351
  });
351
352
 
353
+ it("sets a top arrow position (tooltip is smaller than anchor) on a zoomed chart", () => {
354
+ chartMock.container.clientWidth = 1600;
355
+ tooltipBBoxMock.width = 40;
356
+ tooltipBBoxMock.height = 20;
357
+ anchorBBoxMock.width = 50;
358
+ anchorBBoxMock.height = 50;
359
+ anchorBBoxMock.x = 200;
360
+ anchorBBoxMock.y = 200;
361
+ positionMock = {
362
+ x: 205,
363
+ y: 180,
364
+ direction: "top",
365
+ };
366
+ instance.setArrowPosition(tooltipMock, positionMock, anchorMock, optionsMock);
367
+ expect(arrowElMock.setAttribute).toHaveBeenCalledWith("style", `${commonStyles}${arrowTopBorderStyles}left:22px`);
368
+ });
369
+
352
370
  it("sets a top arrow position (clamp left)", () => {
353
371
  tooltipBBoxMock.width = 100;
354
372
  tooltipBBoxMock.height = 20;
@@ -477,6 +495,23 @@ describe("DrChartTooltip", () => {
477
495
  expect(arrowElMock.setAttribute).toHaveBeenCalledWith("style", `${commonStyles}${arrowLeftBorderStyles}top:15px`);
478
496
  });
479
497
 
498
+ it("sets a left arrow position (tooltip is smaller than anchor) on a zoomed chart", () => {
499
+ chartMock.container.clientWidth = 1600;
500
+ tooltipBBoxMock.width = 20;
501
+ tooltipBBoxMock.height = 40;
502
+ anchorBBoxMock.width = 50;
503
+ anchorBBoxMock.height = 50;
504
+ anchorBBoxMock.x = 200;
505
+ anchorBBoxMock.y = 200;
506
+ positionMock = {
507
+ x: 180,
508
+ y: 205,
509
+ direction: "left",
510
+ };
511
+ instance.setArrowPosition(tooltipMock, positionMock, anchorMock, optionsMock);
512
+ expect(arrowElMock.setAttribute).toHaveBeenCalledWith("style", `${commonStyles}${arrowLeftBorderStyles}top:22px`);
513
+ });
514
+
480
515
  it("sets a left arrow position (clamp top)", () => {
481
516
  tooltipBBoxMock.width = 20;
482
517
  tooltipBBoxMock.height = 100;
@@ -593,6 +628,11 @@ describe("DrChartTooltip", () => {
593
628
  expect(instance.getCoords("top", tooltipMock, anchorMock, optionsMock)).toEqual({ x: 175, y: 170 });
594
629
  });
595
630
 
631
+ it("gets coordinates (top - without correction)", () => {
632
+ chartMock.container.clientWidth = 1600;
633
+ expect(instance.getCoords("top", tooltipMock, anchorMock, optionsMock)).toEqual({ x: 400, y: 370 });
634
+ });
635
+
596
636
  it("gets coordinates (top - bound to the chart - left)", () => {
597
637
  anchorBBoxMock.x = 0;
598
638
  expect(instance.getCoords("top", tooltipMock, anchorMock, optionsMock)).toEqual({ x: 8 /* offset */, y: 170 });
@@ -627,6 +667,11 @@ describe("DrChartTooltip", () => {
627
667
  expect(instance.getCoords("left", tooltipMock, anchorMock, optionsMock)).toEqual({ x: 90, y: 215 });
628
668
  });
629
669
 
670
+ it("gets coordinates (left - without correction)", () => {
671
+ chartMock.container.clientWidth = 1600;
672
+ expect(instance.getCoords("left", tooltipMock, anchorMock, optionsMock)).toEqual({ x: 290, y: 440 });
673
+ });
674
+
630
675
  it("gets coordinates (left - bound to the chart - bottom)", () => {
631
676
  anchorBBoxMock.y = 1000;
632
677
  expect(instance.getCoords("left", tooltipMock, anchorMock, optionsMock)).toEqual({ x: 90, y: 572 });
@@ -645,6 +690,11 @@ describe("DrChartTooltip", () => {
645
690
  expect(instance.getCoords("right", tooltipMock, anchorMock, optionsMock)).toEqual({ x: 260, y: 215 });
646
691
  });
647
692
 
693
+ it("gets coordinates (right - without correction)", () => {
694
+ chartMock.container.clientWidth = 1600;
695
+ expect(instance.getCoords("right", tooltipMock, anchorMock, optionsMock)).toEqual({ x: 510, y: 440 });
696
+ });
697
+
648
698
  it("gets coordinates (right - bound to the chart - bottom)", () => {
649
699
  anchorBBoxMock.y = 1000;
650
700
  expect(instance.getCoords("right", tooltipMock, anchorMock, optionsMock)).toEqual({