sea-chart 2.0.8 → 2.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/tooltip/index.js +92 -0
- package/dist/components/types-dialog/index.js +2 -4
- package/dist/constants/index.js +1 -1
- package/dist/view/wrapper/bar-compare.js +345 -0
- package/dist/view/wrapper/bar-custom-stack.js +403 -0
- package/dist/view/wrapper/bar-group.js +46 -19
- package/dist/view/wrapper/bar-stack.js +40 -15
- package/dist/view/wrapper/bar.js +36 -26
- package/dist/view/wrapper/chart-component.js +425 -133
- package/dist/view/wrapper/horizontal-bar-group.js +282 -0
- package/dist/view/wrapper/horizontal-bar.js +266 -0
- package/dist/view/wrapper/index.js +41 -0
- package/package.json +2 -1
|
@@ -13,6 +13,7 @@ var _dtableUtils = require("dtable-utils");
|
|
|
13
13
|
var _utils = require("../../utils");
|
|
14
14
|
var _constants = require("../../constants");
|
|
15
15
|
var _intl = _interopRequireDefault(require("../../intl"));
|
|
16
|
+
var _columnUtils = require("../../utils/column-utils");
|
|
16
17
|
require("../../assets/css/sea-chart-d3-tooltip.css");
|
|
17
18
|
class ChartComponent extends _react.Component {
|
|
18
19
|
constructor(props) {
|
|
@@ -51,14 +52,22 @@ class ChartComponent extends _react.Component {
|
|
|
51
52
|
this.initChart = function (container, id) {
|
|
52
53
|
let initConfig = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
53
54
|
const {
|
|
54
|
-
width,
|
|
55
|
-
height
|
|
55
|
+
width: containerWidth,
|
|
56
|
+
height: containerHeight
|
|
56
57
|
} = container.getBoundingClientRect();
|
|
58
|
+
const {
|
|
59
|
+
marginLeft = 0,
|
|
60
|
+
marginBottom = 0
|
|
61
|
+
} = initConfig;
|
|
62
|
+
const width = containerWidth - marginLeft;
|
|
63
|
+
const height = containerHeight - marginBottom;
|
|
57
64
|
_this.chart = d3.create('svg').attr('id', id).attr('class', "svg-wrapper-".concat(id)).attr('width', width).attr('height', height).attr('viewBox', [0, 0, width, height]);
|
|
58
65
|
_this.container.appendChild(_this.chart.node());
|
|
59
66
|
_this.chartBoundingClientRect = {
|
|
60
67
|
...JSON.parse(JSON.stringify(_this.chart.node().getBoundingClientRect())),
|
|
61
|
-
...initConfig
|
|
68
|
+
...initConfig,
|
|
69
|
+
width,
|
|
70
|
+
height
|
|
62
71
|
};
|
|
63
72
|
};
|
|
64
73
|
this.initDefs = () => {
|
|
@@ -70,7 +79,7 @@ class ChartComponent extends _react.Component {
|
|
|
70
79
|
const {
|
|
71
80
|
width,
|
|
72
81
|
height
|
|
73
|
-
} = this.
|
|
82
|
+
} = this.chartBoundingClientRect;
|
|
74
83
|
this.chart.append('defs').append('mask').attr('id', "mask-wrapper-".concat(previewType, "-").concat(this.chart.node().id)).append('rect').attr('x', 0).attr('y', 0).attr('width', width).attr('height', height - 30).attr('fill', 'white');
|
|
75
84
|
}
|
|
76
85
|
};
|
|
@@ -216,7 +225,6 @@ class ChartComponent extends _react.Component {
|
|
|
216
225
|
}
|
|
217
226
|
};
|
|
218
227
|
this.renderAxisLabel = (chart, tables, chartContainer) => {
|
|
219
|
-
var _this$chart2;
|
|
220
228
|
if (!this.chart || !chart) return;
|
|
221
229
|
let {
|
|
222
230
|
table_id,
|
|
@@ -237,30 +245,31 @@ class ChartComponent extends _react.Component {
|
|
|
237
245
|
y_axis_column_key = y_axis_summary_column_key;
|
|
238
246
|
}
|
|
239
247
|
const table = (0, _dtableUtils.getTableById)(tables, table_id);
|
|
240
|
-
const autoPadding = ((_this$chart2 = this.chart) === null || _this$chart2 === void 0 ? void 0 : _this$chart2.autoPadding) || {
|
|
241
|
-
bottom: 0
|
|
242
|
-
};
|
|
243
248
|
let textColor;
|
|
244
249
|
this.globalTheme === _constants.THEME_NAME_MAP.DARK ? textColor = '#fff' : textColor = '#999';
|
|
245
250
|
const xAxisID = "chart-x-axis-label_".concat(chart.id);
|
|
246
251
|
const xLabel = chartContainer === null || chartContainer === void 0 ? void 0 : chartContainer.querySelector("#".concat(xAxisID));
|
|
252
|
+
const {
|
|
253
|
+
width: containerWidth
|
|
254
|
+
} = this.chartBoundingClientRect;
|
|
247
255
|
if (!xLabel && x_axis_show_label) {
|
|
248
256
|
const div = document.createElement('div');
|
|
249
257
|
div.id = xAxisID;
|
|
250
258
|
div.className = 'chart-axis-label';
|
|
251
259
|
const column = (0, _dtableUtils.getTableColumnByKey)(table, x_axis_column_key);
|
|
252
260
|
div.innerHTML = "".concat(column ? column.name : '');
|
|
253
|
-
div.setAttribute('style', "color:".concat(textColor, "; width:
|
|
261
|
+
div.setAttribute('style', "color:".concat(textColor, "; width: ").concat(containerWidth, "px; text-align: ").concat(x_axis_label_position, "; position: absolute"));
|
|
254
262
|
chartContainer.appendChild(div);
|
|
255
263
|
}
|
|
256
264
|
if (xLabel && x_axis_show_label) {
|
|
257
|
-
xLabel.setAttribute('style', "color:".concat(textColor, "; width:
|
|
265
|
+
xLabel.setAttribute('style', "color:".concat(textColor, "; width: ").concat(containerWidth, "px; text-align: ").concat(x_axis_label_position, "; position: absolute"));
|
|
258
266
|
}
|
|
259
267
|
if (xLabel && !x_axis_show_label) {
|
|
260
268
|
xLabel.parentNode.removeChild(xLabel);
|
|
261
269
|
}
|
|
262
270
|
const yAxisID = "chart-y-axis-label_".concat(chart.id);
|
|
263
271
|
const yLabel = chartContainer.querySelector("#".concat(yAxisID));
|
|
272
|
+
const divHeight = 20;
|
|
264
273
|
if (!yLabel && y_axis_show_label) {
|
|
265
274
|
const div = document.createElement('div');
|
|
266
275
|
div.id = yAxisID;
|
|
@@ -274,24 +283,103 @@ class ChartComponent extends _react.Component {
|
|
|
274
283
|
div.innerHTML = title_name || '';
|
|
275
284
|
}
|
|
276
285
|
}
|
|
277
|
-
const
|
|
286
|
+
const {
|
|
287
|
+
height: containerHeight
|
|
288
|
+
} = this.chartBoundingClientRect;
|
|
278
289
|
let textAlign = 'center';
|
|
279
290
|
if (y_axis_label_position === _constants.LABEL_POSITION_TYPE.BOTTOM) textAlign = 'left';
|
|
280
291
|
if (y_axis_label_position === _constants.LABEL_POSITION_TYPE.TOP) textAlign = 'right';
|
|
281
|
-
div.setAttribute('style', "color:".concat(textColor, "; position: absolute; width: ").concat(containerHeight, "px; text-align: ").concat(textAlign, "; top: 0; left: 0; transform: translate(-").concat(containerHeight / 2
|
|
292
|
+
div.setAttribute('style', "color:".concat(textColor, "; position: absolute; width: ").concat(containerHeight, "px; height: ").concat(divHeight, "px; text-align: ").concat(textAlign, "; top: 0; left: 0; transform: translate(-").concat(containerHeight / 2 - divHeight / 2, "px, ").concat(containerHeight / 2 - divHeight / 2, "px) rotate(-90deg)"));
|
|
282
293
|
chartContainer.appendChild(div);
|
|
283
294
|
}
|
|
284
295
|
if (yLabel && y_axis_show_label) {
|
|
285
|
-
const
|
|
296
|
+
const {
|
|
297
|
+
height: containerHeight
|
|
298
|
+
} = this.chartBoundingClientRect;
|
|
286
299
|
let textAlign = 'center';
|
|
287
300
|
if (y_axis_label_position === _constants.LABEL_POSITION_TYPE.BOTTOM) textAlign = 'left';
|
|
288
301
|
if (y_axis_label_position === _constants.LABEL_POSITION_TYPE.TOP) textAlign = 'right';
|
|
289
|
-
yLabel.setAttribute('style', "color:".concat(textColor, "; position: absolute; width: ").concat(containerHeight, "px; text-align: ").concat(textAlign, "; top: 0; left: 0; transform: translate(-").concat(containerHeight / 2
|
|
302
|
+
yLabel.setAttribute('style', "color:".concat(textColor, "; position: absolute; width: ").concat(containerHeight, "px; height: ").concat(divHeight, "px; text-align: ").concat(textAlign, "; top: 0; left: 0; transform: translate(-").concat(containerHeight / 2 - divHeight / 2, "px, ").concat(containerHeight / 2 - divHeight / 2, "px) rotate(-90deg)"));
|
|
290
303
|
}
|
|
291
304
|
if (yLabel && !y_axis_show_label) {
|
|
292
305
|
yLabel.parentNode.removeChild(yLabel);
|
|
293
306
|
}
|
|
294
307
|
};
|
|
308
|
+
this.renderHorizontalLabel = (chart, tables, chartContainer) => {
|
|
309
|
+
if (!this.chart || !chart) return;
|
|
310
|
+
const {
|
|
311
|
+
table_id,
|
|
312
|
+
vertical_axis_column_key,
|
|
313
|
+
horizontal_axis_column_key,
|
|
314
|
+
horizontal_axis_summary_type,
|
|
315
|
+
horizontal_axis_label_position,
|
|
316
|
+
vertical_axis_label_position,
|
|
317
|
+
show_vertical_axis_label,
|
|
318
|
+
show_horizontal_axis_label
|
|
319
|
+
} = chart.config;
|
|
320
|
+
const table = (0, _dtableUtils.getTableById)(tables, table_id);
|
|
321
|
+
const textColor = '#999999';
|
|
322
|
+
const xAxisID = "chart-x-axis-label_".concat(chart.id);
|
|
323
|
+
const xLabel = chartContainer.querySelector("#".concat(xAxisID));
|
|
324
|
+
const {
|
|
325
|
+
width: containerWidth
|
|
326
|
+
} = this.chartBoundingClientRect;
|
|
327
|
+
if (!xLabel && show_horizontal_axis_label) {
|
|
328
|
+
const div = document.createElement('div');
|
|
329
|
+
div.id = xAxisID;
|
|
330
|
+
div.className = 'chart-axis-label';
|
|
331
|
+
if (horizontal_axis_summary_type === _constants.CHART_SUMMARY_TYPE.COUNT) {
|
|
332
|
+
div.innerHTML = _intl.default.get('Amount');
|
|
333
|
+
} else {
|
|
334
|
+
const column = (0, _dtableUtils.getTableColumnByKey)(table, horizontal_axis_column_key);
|
|
335
|
+
div.innerHTML = "".concat(column ? column.name : '');
|
|
336
|
+
}
|
|
337
|
+
div.setAttribute('style', "color:".concat(textColor, "; width: ").concat(containerWidth, "px; text-align: ").concat(horizontal_axis_label_position, "; position: absolute"));
|
|
338
|
+
chartContainer.appendChild(div);
|
|
339
|
+
}
|
|
340
|
+
if (xLabel && show_horizontal_axis_label) {
|
|
341
|
+
xLabel.setAttribute('style', "color:".concat(textColor, "; width: ").concat(containerWidth, "px; text-align: ").concat(horizontal_axis_label_position, "; position: absolute"));
|
|
342
|
+
}
|
|
343
|
+
if (xLabel && !show_horizontal_axis_label) {
|
|
344
|
+
xLabel.parentNode.removeChild(xLabel);
|
|
345
|
+
}
|
|
346
|
+
const yAxisID = "chart-y-axis-label_".concat(chart.id);
|
|
347
|
+
const yLabel = chartContainer.querySelector("#".concat(yAxisID));
|
|
348
|
+
const divHeight = 20;
|
|
349
|
+
if (!yLabel && show_vertical_axis_label) {
|
|
350
|
+
const div = document.createElement('div');
|
|
351
|
+
div.id = yAxisID;
|
|
352
|
+
div.className = 'chart-axis-label';
|
|
353
|
+
const column = (0, _dtableUtils.getTableColumnByKey)(table, vertical_axis_column_key) || {};
|
|
354
|
+
div.innerHTML = column.name || '';
|
|
355
|
+
const {
|
|
356
|
+
height: containerHeight
|
|
357
|
+
} = this.chartBoundingClientRect;
|
|
358
|
+
let textAlign = 'center';
|
|
359
|
+
if (vertical_axis_label_position === _constants.LABEL_POSITION_TYPE.BOTTOM) textAlign = 'left';
|
|
360
|
+
if (vertical_axis_label_position === _constants.LABEL_POSITION_TYPE.TOP) textAlign = 'right';
|
|
361
|
+
div.setAttribute('style', "color:".concat(textColor, "; position: absolute; width: ").concat(containerHeight, "px; height: ").concat(divHeight, "px; text-align: ").concat(textAlign, "; top: 0; left: 0; transform: translate(-").concat(containerHeight / 2 - divHeight / 2, "px, ").concat(containerHeight / 2 - divHeight / 2, "px) rotate(-90deg)"));
|
|
362
|
+
chartContainer.appendChild(div);
|
|
363
|
+
}
|
|
364
|
+
if (yLabel && show_horizontal_axis_label) {
|
|
365
|
+
const {
|
|
366
|
+
height: containerHeight
|
|
367
|
+
} = this.chartBoundingClientRect;
|
|
368
|
+
let textAlign = 'center';
|
|
369
|
+
if (vertical_axis_label_position === _constants.LABEL_POSITION_TYPE.BOTTOM) textAlign = 'left';
|
|
370
|
+
if (vertical_axis_label_position === _constants.LABEL_POSITION_TYPE.TOP) textAlign = 'right';
|
|
371
|
+
yLabel.setAttribute('style', "color:".concat(textColor, "; position: absolute; width: ").concat(containerHeight, "px; height: ").concat(divHeight, "px; text-align: ").concat(textAlign, "; top: 0; left: 0; transform: translate(-").concat(containerHeight / 2 - divHeight / 2, "px, ").concat(containerHeight / 2 - divHeight / 2, "px) rotate(-90deg)"));
|
|
372
|
+
}
|
|
373
|
+
if (yLabel && !show_horizontal_axis_label) {
|
|
374
|
+
yLabel.parentNode.removeChild(yLabel);
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
this.isShowVerticalAxisLabel = chart => {
|
|
378
|
+
return !!(chart && chart.config && chart.config.show_vertical_axis_label);
|
|
379
|
+
};
|
|
380
|
+
this.isShowHorizontalAxisLabel = chart => {
|
|
381
|
+
return !!(chart && chart.config && chart.config.show_horizontal_axis_label);
|
|
382
|
+
};
|
|
295
383
|
// Automatic adjustment of maximum and minimum values
|
|
296
384
|
this.autoAdjustDataOptions = function (chart) {
|
|
297
385
|
let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
@@ -481,92 +569,290 @@ class ChartComponent extends _react.Component {
|
|
|
481
569
|
return _intl.default.get(name) || name;
|
|
482
570
|
}
|
|
483
571
|
};
|
|
484
|
-
this.
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
} = item.getBoundingClientRect();
|
|
497
|
-
width = width + legendItemWidth;
|
|
572
|
+
this.sortLegend = (result, groupColumn, legendName) => {
|
|
573
|
+
result.forEach(item => {
|
|
574
|
+
const option = groupColumn.data.options.find(option => option.name === item[legendName]);
|
|
575
|
+
if (option !== null && option !== void 0 && option.id) {
|
|
576
|
+
item['group_name_id'] = option.id;
|
|
577
|
+
item['oldName'] = item.name;
|
|
578
|
+
item.name = item['group_name_id'];
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
_utils.BaseUtils.sortCharts(result, groupColumn, 'name');
|
|
582
|
+
result.forEach(item => {
|
|
583
|
+
item.name = item['oldName'];
|
|
498
584
|
});
|
|
499
|
-
return width;
|
|
500
585
|
};
|
|
501
586
|
// set legend
|
|
502
|
-
this.setLegend =
|
|
587
|
+
this.setLegend = _ref => {
|
|
503
588
|
var _this$chart$node;
|
|
504
|
-
let
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
589
|
+
let {
|
|
590
|
+
legendName,
|
|
591
|
+
theme = _constants.CHART_THEME_COLOR['light'],
|
|
592
|
+
legendPosition = 'top-left',
|
|
593
|
+
data,
|
|
594
|
+
colorScale,
|
|
595
|
+
groupColumn
|
|
596
|
+
} = _ref;
|
|
597
|
+
if (!this.chart) return;
|
|
598
|
+
const legendData = (0, _lodashEs.cloneDeep)(data);
|
|
599
|
+
this.legendConfig = {
|
|
600
|
+
legendRectWidth: 20,
|
|
601
|
+
legendRectHeight: 6,
|
|
602
|
+
r: 3,
|
|
603
|
+
legendItemPaddingTop: 3,
|
|
604
|
+
legendItemMargin: 20,
|
|
605
|
+
legendRecTextGap: 8,
|
|
606
|
+
legendPageNavWrapperWidth: 100,
|
|
607
|
+
legendPosition,
|
|
608
|
+
legendName,
|
|
609
|
+
theme
|
|
610
|
+
};
|
|
611
|
+
|
|
612
|
+
// sort legend data
|
|
613
|
+
if (groupColumn && [_dtableUtils.CellType.SINGLE_SELECT].includes(groupColumn.type)) {
|
|
614
|
+
this.sortLegend(legendData, groupColumn, legendName);
|
|
615
|
+
}
|
|
508
616
|
const {
|
|
509
617
|
width: chartWidth,
|
|
510
618
|
insertPadding
|
|
511
|
-
} =
|
|
512
|
-
const
|
|
513
|
-
const
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
619
|
+
} = this.chartBoundingClientRect;
|
|
620
|
+
const groupsData = this.getLegendDataGroups(legendData);
|
|
621
|
+
const legendWrapper = this.chart.append('g').attr('class', "legend-wrapper-".concat((_this$chart$node = this.chart.node()) === null || _this$chart$node === void 0 ? void 0 : _this$chart$node.id));
|
|
622
|
+
|
|
623
|
+
// Render first group legend
|
|
624
|
+
this.renderLegend({
|
|
625
|
+
legendWrapper,
|
|
626
|
+
groupData: groupsData[0],
|
|
627
|
+
colorScale,
|
|
628
|
+
theme
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
// Render Page navigator
|
|
632
|
+
if (groupsData.length > 1) {
|
|
633
|
+
const {
|
|
634
|
+
legendPageNavWrapperWidth
|
|
635
|
+
} = this.legendConfig;
|
|
636
|
+
let curCount = 0;
|
|
637
|
+
const pageNavigator = legendWrapper.append('g').attr('class', 'legend-flip-page');
|
|
638
|
+
|
|
639
|
+
// count
|
|
640
|
+
pageNavigator.append('text').attr('class', 'legend-count').attr('dominant-baseline', 'hanging').attr('x', 15).attr('fill', theme.legendTextColor).attr('font-size', theme.legendFontSize).text("".concat(curCount + 1, "/").concat(groupsData.length));
|
|
641
|
+
|
|
642
|
+
// prev page
|
|
643
|
+
pageNavigator.append('polygon').attr('class', 'legend-prev-page').attr('points', this.calcEquilateralTriangle(5, 5, 12)).attr('fill', theme.legendPageNavigatorMarkerColor).attr('opacity', curCount === 0 ? 0.45 : 1).attr('style', 'cursor: pointer;').on('click', event => {
|
|
644
|
+
if (curCount > 0) {
|
|
645
|
+
curCount--;
|
|
646
|
+
this.renderLegend({
|
|
647
|
+
legendWrapper,
|
|
648
|
+
groupData: groupsData[curCount],
|
|
649
|
+
colorScale,
|
|
650
|
+
theme,
|
|
651
|
+
text: "".concat(curCount + 1, "/").concat(groupsData.length)
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
// next page
|
|
657
|
+
pageNavigator.append('polygon').attr('class', 'legend-next-page').attr('points', this.calcEquilateralTriangle(45, 5, 12, 'bottom')).attr('fill', theme.legendPageNavigatorMarkerColor).attr('opacity', curCount === groupsData.length - 1 ? 0.45 : 1).attr('style', 'cursor: pointer;').on('click', event => {
|
|
658
|
+
if (curCount < groupsData.length - 1) {
|
|
659
|
+
curCount++;
|
|
660
|
+
this.renderLegend({
|
|
661
|
+
legendWrapper,
|
|
662
|
+
groupData: groupsData[curCount],
|
|
663
|
+
colorScale,
|
|
664
|
+
theme,
|
|
665
|
+
text: "".concat(curCount + 1, "/").concat(groupsData.length)
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
// update pageNavigator transform
|
|
671
|
+
pageNavigator.call(g => {
|
|
672
|
+
let groupTranslateX = 0;
|
|
673
|
+
if (legendPosition === 'top-right') {
|
|
674
|
+
groupTranslateX = insertPadding;
|
|
675
|
+
} else if (legendPosition === 'top-left') {
|
|
676
|
+
groupTranslateX = chartWidth - insertPadding - legendPageNavWrapperWidth;
|
|
677
|
+
const {
|
|
678
|
+
width
|
|
679
|
+
} = g.node().getBoundingClientRect();
|
|
680
|
+
const offset = legendPageNavWrapperWidth - width;
|
|
681
|
+
groupTranslateX = groupTranslateX + offset;
|
|
682
|
+
}
|
|
683
|
+
g.attr('transform', "translate(".concat(groupTranslateX, ", 0)"));
|
|
684
|
+
});
|
|
524
685
|
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
}
|
|
534
|
-
|
|
686
|
+
};
|
|
687
|
+
this.renderLegend = _ref2 => {
|
|
688
|
+
let {
|
|
689
|
+
legendWrapper,
|
|
690
|
+
groupData,
|
|
691
|
+
colorScale,
|
|
692
|
+
theme,
|
|
693
|
+
text
|
|
694
|
+
} = _ref2;
|
|
695
|
+
const {
|
|
696
|
+
legendItemPaddingTop,
|
|
697
|
+
legendRectWidth,
|
|
698
|
+
legendRectHeight,
|
|
699
|
+
r,
|
|
700
|
+
legendRecTextGap,
|
|
701
|
+
legendItemMargin,
|
|
702
|
+
legendPosition
|
|
703
|
+
} = this.legendConfig;
|
|
704
|
+
|
|
705
|
+
// clear old legends
|
|
706
|
+
const oldChildren = Array.from(legendWrapper.node().children);
|
|
707
|
+
if (oldChildren.length !== 0) {
|
|
708
|
+
oldChildren.forEach(item => {
|
|
709
|
+
// update navigator button opacity and text
|
|
710
|
+
if (item.getAttribute('class') == 'legend-flip-page') {
|
|
711
|
+
this.handleNavigatorOpacity(item, text);
|
|
712
|
+
d3.select(item).selectAll('text').text(text);
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
// remove old legend item
|
|
716
|
+
d3.select(item).remove();
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
legendWrapper.selectAll().data(groupData).join('g').attr('data-groupName', _ref3 => {
|
|
720
|
+
let [groupName] = _ref3;
|
|
721
|
+
return groupName;
|
|
722
|
+
}).append('rect').attr('width', legendRectWidth).attr('height', legendRectHeight).attr('y', legendItemPaddingTop).attr('rx', r).attr('fill', _ref4 => {
|
|
723
|
+
let [groupName] = _ref4;
|
|
724
|
+
if (colorScale) return colorScale(groupName);
|
|
725
|
+
return this.colorMap[groupName] || _constants.CHART_STYLE_COLORS[0];
|
|
726
|
+
}).attr('data-text', _ref5 => {
|
|
727
|
+
let [groupName] = _ref5;
|
|
535
728
|
return groupName;
|
|
536
729
|
}).call(g => {
|
|
537
|
-
var _this$chart$node2;
|
|
538
|
-
const legendWrapper = d3.selectAll(".legend-wrapper-".concat((_this$chart$node2 = _this.chart.node()) === null || _this$chart$node2 === void 0 ? void 0 : _this$chart$node2.id)).node();
|
|
539
|
-
const legendItems = Array.from(legendWrapper.children);
|
|
540
|
-
const legendItemCount = legendItems.length;
|
|
541
|
-
|
|
542
730
|
// Add text
|
|
543
731
|
g.nodes().forEach(rect => {
|
|
544
732
|
const parentNode = rect.parentNode;
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
733
|
+
d3.select(parentNode).append('text').attr('x', legendRectWidth + legendRecTextGap).attr('fill', theme.legendTextColor).attr('font-size', theme.legendFontSize).text(this.formatterLegendName(rect.dataset.text)).attr('data-text', rect.dataset.text).attr('dominant-baseline', 'hanging');
|
|
734
|
+
});
|
|
735
|
+
// update g translateX
|
|
736
|
+
const legendItems = Array.from(legendWrapper.node().children).filter(item => item.getAttribute('class') !== 'legend-flip-page');
|
|
737
|
+
const {
|
|
738
|
+
start,
|
|
739
|
+
end
|
|
740
|
+
} = this.getLegendBoundary(legendPosition);
|
|
741
|
+
legendItems.forEach((item, index) => {
|
|
742
|
+
let translateX = start;
|
|
743
|
+
const lastItem = legendItems[index - 1];
|
|
744
|
+
if (index > 0) {
|
|
549
745
|
const {
|
|
550
|
-
height,
|
|
551
746
|
width
|
|
552
|
-
} =
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
});
|
|
557
|
-
});
|
|
747
|
+
} = lastItem.getBoundingClientRect();
|
|
748
|
+
const prevTranslateX = Number(lastItem.getAttribute('data-translateX'));
|
|
749
|
+
translateX = prevTranslateX + width + legendItemMargin;
|
|
750
|
+
}
|
|
558
751
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
752
|
+
// legend items add offset
|
|
753
|
+
if (legendPosition === 'top-right') {
|
|
754
|
+
d3.select(item).attr('opacity', 0);
|
|
755
|
+
if (index === legendItems.length - 1) {
|
|
756
|
+
queueMicrotask(() => {
|
|
757
|
+
this.setLegendItemOffset(legendItems, end);
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
d3.select(item).attr('transform', "translate(".concat(translateX, ",0)")).attr('data-translateX', translateX);
|
|
567
762
|
});
|
|
568
763
|
});
|
|
569
764
|
};
|
|
765
|
+
this.getLegendDataGroups = legendData => {
|
|
766
|
+
const {
|
|
767
|
+
legendName,
|
|
768
|
+
theme,
|
|
769
|
+
legendPosition
|
|
770
|
+
} = this.legendConfig;
|
|
771
|
+
legendData = d3.groups(legendData, d => d[legendName]);
|
|
772
|
+
const {
|
|
773
|
+
legendItemMargin,
|
|
774
|
+
legendRectWidth,
|
|
775
|
+
legendRectHeight,
|
|
776
|
+
r,
|
|
777
|
+
legendRecTextGap
|
|
778
|
+
} = this.legendConfig;
|
|
779
|
+
const {
|
|
780
|
+
start,
|
|
781
|
+
end
|
|
782
|
+
} = this.getLegendBoundary(legendPosition);
|
|
783
|
+
let allWidth = start;
|
|
784
|
+
const groupsData = [];
|
|
785
|
+
const newLegendData = (0, _lodashEs.cloneDeep)(legendData);
|
|
786
|
+
legendData.forEach((item, index) => {
|
|
787
|
+
const virtualLegend = this.chart.append('g').attr('opacity', 0);
|
|
788
|
+
virtualLegend.append('rect').attr('width', legendRectWidth).attr('height', legendRectHeight).attr('rx', r);
|
|
789
|
+
virtualLegend.append('text').attr('x', legendRectWidth + legendRecTextGap).attr('font-size', theme.legendFontSize).text(this.formatterLegendName(item[0]));
|
|
790
|
+
const {
|
|
791
|
+
width
|
|
792
|
+
} = virtualLegend.node().getBoundingClientRect();
|
|
793
|
+
const itemWidth = index === legendData.length - 1 ? width : width + legendItemMargin; // last item no used margin
|
|
794
|
+
allWidth = allWidth + itemWidth;
|
|
795
|
+
if (allWidth >= end) {
|
|
796
|
+
groupsData.push(newLegendData.slice(0, index));
|
|
797
|
+
newLegendData.splice(0, index);
|
|
798
|
+
allWidth = 0;
|
|
799
|
+
}
|
|
800
|
+
virtualLegend.remove();
|
|
801
|
+
});
|
|
802
|
+
const restLegendItems = newLegendData.slice(0);
|
|
803
|
+
groupsData.push(restLegendItems);
|
|
804
|
+
return groupsData;
|
|
805
|
+
};
|
|
806
|
+
this.getLegendBoundary = legendPosition => {
|
|
807
|
+
const {
|
|
808
|
+
legendPageNavWrapperWidth
|
|
809
|
+
} = this.legendConfig;
|
|
810
|
+
const {
|
|
811
|
+
width: chartWidth,
|
|
812
|
+
insertPadding
|
|
813
|
+
} = this.chartBoundingClientRect;
|
|
814
|
+
let start = 0;
|
|
815
|
+
let end = 0;
|
|
816
|
+
if (legendPosition === 'top-left') {
|
|
817
|
+
start = insertPadding;
|
|
818
|
+
end = chartWidth - insertPadding - legendPageNavWrapperWidth;
|
|
819
|
+
}
|
|
820
|
+
if (legendPosition === 'top-right') {
|
|
821
|
+
start = insertPadding + legendPageNavWrapperWidth;
|
|
822
|
+
end = chartWidth - insertPadding;
|
|
823
|
+
}
|
|
824
|
+
return {
|
|
825
|
+
start,
|
|
826
|
+
end
|
|
827
|
+
};
|
|
828
|
+
};
|
|
829
|
+
this.handleNavigatorOpacity = (navigator, text) => {
|
|
830
|
+
const curCount = text.split('/')[0];
|
|
831
|
+
const allCount = text.split('/')[1];
|
|
832
|
+
if (Number(curCount) === 0) {
|
|
833
|
+
d3.select(navigator).selectAll('.legend-prev-page').attr('opacity', 0.45);
|
|
834
|
+
d3.select(navigator).selectAll('.legend-next-page').attr('opacity', 1);
|
|
835
|
+
} else if (Number(curCount) === Number(allCount)) {
|
|
836
|
+
d3.select(navigator).selectAll('.legend-prev-page').attr('opacity', 1);
|
|
837
|
+
d3.select(navigator).selectAll('.legend-next-page').attr('opacity', 0.45);
|
|
838
|
+
} else {
|
|
839
|
+
d3.select(navigator).selectAll('.legend-prev-page').attr('opacity', 1);
|
|
840
|
+
d3.select(navigator).selectAll('.legend-next-page').attr('opacity', 1);
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
this.setLegendItemOffset = (legendItems, end) => {
|
|
844
|
+
const endItem = legendItems[legendItems.length - 1];
|
|
845
|
+
const endTranslateX = Number(endItem.getAttribute('data-translateX'));
|
|
846
|
+
const {
|
|
847
|
+
width: endWidth
|
|
848
|
+
} = endItem.getBoundingClientRect();
|
|
849
|
+
const offset = end - (endTranslateX + endWidth);
|
|
850
|
+
legendItems.forEach(legendItem => {
|
|
851
|
+
const curTranslateX = Number(legendItem.getAttribute('data-translateX')) + offset;
|
|
852
|
+
d3.select(legendItem).attr('transform', "translate(".concat(curTranslateX, ",0)")).attr('data-translateX', curTranslateX);
|
|
853
|
+
d3.select(legendItem).attr('opacity', 1);
|
|
854
|
+
});
|
|
855
|
+
};
|
|
570
856
|
// theta is pie or ring chart
|
|
571
857
|
this.setLegendForTheta = function (legendName) {
|
|
572
858
|
let theme = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _constants.CHART_THEME_COLOR['light'];
|
|
@@ -580,6 +866,13 @@ class ChartComponent extends _react.Component {
|
|
|
580
866
|
basicLegendConfig.itemName.style.fontSize = theme.fontSize;
|
|
581
867
|
_this.chart.legend(legendName, basicLegendConfig);
|
|
582
868
|
};
|
|
869
|
+
this.calcEquilateralTriangle = (cx, cy, size, direction) => {
|
|
870
|
+
const height = size * Math.sqrt(3) / 2;
|
|
871
|
+
if (direction === 'bottom') {
|
|
872
|
+
return [[cx, cy + height / 2], [cx - size / 2, cy - height / 2], [cx + size / 2, cy - height / 2]];
|
|
873
|
+
}
|
|
874
|
+
return [[cx, cy - height / 2], [cx - size / 2, cy + height / 2], [cx + size / 2, cy + height / 2]];
|
|
875
|
+
};
|
|
583
876
|
this.setColorMap = (data, chartColorTheme) => {
|
|
584
877
|
let currentIdx = 0;
|
|
585
878
|
const defaultColors = _constants.CHART_STYLE_COLORS;
|
|
@@ -689,47 +982,6 @@ class ChartComponent extends _react.Component {
|
|
|
689
982
|
const settings = this.getToolTipSettings(isGroup, summaryColumn, y_axis_summary_method, useSingleSelectColumnColor);
|
|
690
983
|
this.chart.tooltip(settings);
|
|
691
984
|
};
|
|
692
|
-
this.getToolTipContainer = (tooltipData, position) => {
|
|
693
|
-
const {
|
|
694
|
-
offsetX,
|
|
695
|
-
offsetY
|
|
696
|
-
} = position || {
|
|
697
|
-
offsetX: -9999,
|
|
698
|
-
offsetY: -9999
|
|
699
|
-
};
|
|
700
|
-
const {
|
|
701
|
-
title,
|
|
702
|
-
items
|
|
703
|
-
} = tooltipData || {
|
|
704
|
-
title: '',
|
|
705
|
-
items: []
|
|
706
|
-
};
|
|
707
|
-
const dom = /*#__PURE__*/_react.default.createElement("div", {
|
|
708
|
-
className: "sea-chart-d3-tooltip-container",
|
|
709
|
-
style: {
|
|
710
|
-
transform: "translate(".concat(offsetX + 50, "px, ").concat(offsetY, "px)")
|
|
711
|
-
}
|
|
712
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
713
|
-
className: "sea-chart-d3-tooltip-title"
|
|
714
|
-
}, title), /*#__PURE__*/_react.default.createElement("ul", {
|
|
715
|
-
className: "sea-chart-d3-tooltip-list"
|
|
716
|
-
}, items.map((item, index) => {
|
|
717
|
-
return /*#__PURE__*/_react.default.createElement("li", {
|
|
718
|
-
className: "sea-chart-d3-tooltip-list-item",
|
|
719
|
-
key: index
|
|
720
|
-
}, /*#__PURE__*/_react.default.createElement("span", {
|
|
721
|
-
className: "sea-chart-d3-tooltip-marker",
|
|
722
|
-
style: {
|
|
723
|
-
backgroundColor: item.color
|
|
724
|
-
}
|
|
725
|
-
}), /*#__PURE__*/_react.default.createElement("span", {
|
|
726
|
-
className: "sea-chart-d3-tooltip-name"
|
|
727
|
-
}, item.name), /*#__PURE__*/_react.default.createElement("span", {
|
|
728
|
-
className: "sea-chart-d3-tooltip-value"
|
|
729
|
-
}, item.value));
|
|
730
|
-
})));
|
|
731
|
-
return dom;
|
|
732
|
-
};
|
|
733
985
|
this.setToolTipForLine = () => {
|
|
734
986
|
const settings = this.getToolTipSettings();
|
|
735
987
|
const lineToolTipSettings = {
|
|
@@ -797,17 +1049,16 @@ class ChartComponent extends _react.Component {
|
|
|
797
1049
|
return themeColors || _constants.CHART_THEME_COLOR[_constants.THEME_NAME_MAP.LIGHT];
|
|
798
1050
|
};
|
|
799
1051
|
this.setDispalyGoalLine = (goal_label, goal_value, insertPadding, yScale) => {
|
|
800
|
-
var _this$chart$
|
|
1052
|
+
var _this$chart$node2;
|
|
801
1053
|
const {
|
|
802
1054
|
width: chartWidth
|
|
803
1055
|
} = this.chartBoundingClientRect;
|
|
804
|
-
this.chart.append('g').attr('class', "annotation-wrapper-".concat((_this$chart$
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
parentNode.append('text').attr('x', chartWidth - insertPadding - 30).attr('y', yScale(goal_value) - 10).attr('fill', '#666').text(goal_label);
|
|
1056
|
+
const annotationWrapper = this.chart.append('g').attr('class', "annotation-wrapper-".concat((_this$chart$node2 = this.chart.node()) === null || _this$chart$node2 === void 0 ? void 0 : _this$chart$node2.id));
|
|
1057
|
+
annotationWrapper.append('line').attr('stroke', '#aaa').attr('x1', insertPadding).attr('y1', yScale(goal_value)).attr('x2', chartWidth - insertPadding).attr('y2', yScale(goal_value)).attr('stroke-dasharray', '8,3').call(g => {
|
|
1058
|
+
annotationWrapper.append('text').attr('x', chartWidth - insertPadding - 30).attr('y', yScale(goal_value) - 10).attr('fill', '#666').text(goal_label);
|
|
808
1059
|
});
|
|
809
1060
|
};
|
|
810
|
-
this.addLabelToRectTop =
|
|
1061
|
+
this.addLabelToRectTop = _ref6 => {
|
|
811
1062
|
let {
|
|
812
1063
|
container,
|
|
813
1064
|
x,
|
|
@@ -816,7 +1067,7 @@ class ChartComponent extends _react.Component {
|
|
|
816
1067
|
theme,
|
|
817
1068
|
label_font_size,
|
|
818
1069
|
text
|
|
819
|
-
} =
|
|
1070
|
+
} = _ref6;
|
|
820
1071
|
d3.select(container).append('text').attr('y', Number(y) - 10).attr('fill', theme.labelColor).attr('font-size', _utils.BaseUtils.getLabelFontSize(label_font_size)).text(text).call(g => {
|
|
821
1072
|
const {
|
|
822
1073
|
width
|
|
@@ -824,7 +1075,24 @@ class ChartComponent extends _react.Component {
|
|
|
824
1075
|
g.attr('x', Number(x) + Number(xWidth) / 2 - width / 2);
|
|
825
1076
|
});
|
|
826
1077
|
};
|
|
827
|
-
this.
|
|
1078
|
+
this.addLabelToRectRight = _ref7 => {
|
|
1079
|
+
let {
|
|
1080
|
+
container,
|
|
1081
|
+
y,
|
|
1082
|
+
xWidth,
|
|
1083
|
+
yHeight,
|
|
1084
|
+
theme,
|
|
1085
|
+
label_font_size,
|
|
1086
|
+
text
|
|
1087
|
+
} = _ref7;
|
|
1088
|
+
d3.select(container).append('text').attr('x', Number(xWidth) + 10).attr('y', Number(y)).attr('fill', theme.labelColor).attr('dominant-baseline', 'hanging').attr('font-size', _utils.BaseUtils.getLabelFontSize(label_font_size)).text(text).call(g => {
|
|
1089
|
+
const {
|
|
1090
|
+
height
|
|
1091
|
+
} = g.node().getBoundingClientRect();
|
|
1092
|
+
g.attr('y', Number(y) + Number(yHeight) / 2 - height / 2);
|
|
1093
|
+
});
|
|
1094
|
+
};
|
|
1095
|
+
this.addLabelToRectCenter = _ref8 => {
|
|
828
1096
|
let {
|
|
829
1097
|
chartType,
|
|
830
1098
|
container,
|
|
@@ -832,11 +1100,10 @@ class ChartComponent extends _react.Component {
|
|
|
832
1100
|
y,
|
|
833
1101
|
xWidth,
|
|
834
1102
|
yheight,
|
|
835
|
-
overflowHeight,
|
|
836
1103
|
theme,
|
|
837
1104
|
label_font_size,
|
|
838
1105
|
text
|
|
839
|
-
} =
|
|
1106
|
+
} = _ref8;
|
|
840
1107
|
d3.select(container).append('text').attr('fill', theme.labelColor).attr('font-size', _utils.BaseUtils.getLabelFontSize(label_font_size)).text(text).call(g => {
|
|
841
1108
|
const {
|
|
842
1109
|
width,
|
|
@@ -845,7 +1112,7 @@ class ChartComponent extends _react.Component {
|
|
|
845
1112
|
const translateX = Number(x) + xWidth / 2 - width / 2;
|
|
846
1113
|
let translateY = Number(y) + Number(yheight / 2) + height / 2;
|
|
847
1114
|
if (chartType === _constants.CHART_TYPE.BAR_STACK) {
|
|
848
|
-
translateY = translateY
|
|
1115
|
+
translateY = translateY;
|
|
849
1116
|
}
|
|
850
1117
|
g.attr('transform', "translate(".concat(translateX, ", ").concat(translateY, ")"));
|
|
851
1118
|
});
|
|
@@ -870,6 +1137,31 @@ class ChartComponent extends _react.Component {
|
|
|
870
1137
|
});
|
|
871
1138
|
}
|
|
872
1139
|
};
|
|
1140
|
+
// Use clipPath to make rectangle rounded corners
|
|
1141
|
+
this.addClipPath = _ref9 => {
|
|
1142
|
+
let {
|
|
1143
|
+
rect,
|
|
1144
|
+
parentNode,
|
|
1145
|
+
attr,
|
|
1146
|
+
rectId
|
|
1147
|
+
} = _ref9;
|
|
1148
|
+
const {
|
|
1149
|
+
borderRadius
|
|
1150
|
+
} = this.chartBoundingClientRect;
|
|
1151
|
+
const clipRect = d3.select(rect.cloneNode());
|
|
1152
|
+
if (attr === 'x') {
|
|
1153
|
+
const borderRadiusVal = Number(rect.getAttribute('height')) * borderRadius;
|
|
1154
|
+
clipRect.attr('rx', borderRadiusVal);
|
|
1155
|
+
clipRect.attr('x', Number(rect.getAttribute('x')) - borderRadiusVal).attr('width', Number(rect.getAttribute('width')) + borderRadiusVal);
|
|
1156
|
+
} else {
|
|
1157
|
+
const borderRadiusVal = Number(rect.getAttribute('width')) * borderRadius;
|
|
1158
|
+
clipRect.attr('rx', borderRadiusVal);
|
|
1159
|
+
clipRect.attr('height', Number(rect.getAttribute('height')) + borderRadiusVal);
|
|
1160
|
+
}
|
|
1161
|
+
const clipPath = d3.select(parentNode).append('clipPath').attr('id', rectId);
|
|
1162
|
+
clipPath.node().appendChild(clipRect.node());
|
|
1163
|
+
d3.select(rect).attr('clip-path', "url(#".concat(rectId, ")"));
|
|
1164
|
+
};
|
|
873
1165
|
this.initLabelStroke(props === null || props === void 0 ? void 0 : props.globalTheme);
|
|
874
1166
|
this.chartBoundingClientRect = {};
|
|
875
1167
|
}
|