sea-chart 2.0.14 → 2.0.16

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.
@@ -0,0 +1,400 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+ var _propTypes = _interopRequireDefault(require("prop-types"));
10
+ var _react = _interopRequireDefault(require("react"));
11
+ var _classnames = _interopRequireDefault(require("classnames"));
12
+ var _lodashEs = require("lodash-es");
13
+ var d3 = _interopRequireWildcard(require("d3"));
14
+ var _constants = require("../../constants");
15
+ var _intl = _interopRequireDefault(require("../../intl"));
16
+ var _utils = require("../../utils");
17
+ var _tooltip = _interopRequireDefault(require("../../components/tooltip"));
18
+ var _chartComponent = _interopRequireDefault(require("./chart-component"));
19
+ class Area extends _chartComponent.default {
20
+ constructor(props) {
21
+ super(props);
22
+ this.handleResize = () => {
23
+ this.chart.node() && this.chart.node().remove();
24
+ this.createChart();
25
+ this.drawChart();
26
+ };
27
+ this.createChart = () => {
28
+ const {
29
+ chart
30
+ } = this.props;
31
+ const {
32
+ y_axis_show_label,
33
+ x_axis_show_label,
34
+ y_axis_show_value
35
+ } = chart.config;
36
+ const initConfig = {
37
+ insertPadding: 30,
38
+ marginLeft: y_axis_show_label ? 20 : 0,
39
+ marginBottom: x_axis_show_label ? 20 : 0,
40
+ marginTop: y_axis_show_value ? 15 : 0
41
+ };
42
+ this.initChart(this.container, chart === null || chart === void 0 ? void 0 : chart.id, initConfig);
43
+ };
44
+ this.drawChart = () => {
45
+ let {
46
+ result: data,
47
+ customRender
48
+ } = this.props;
49
+ data = _utils.BaseUtils.formatEmptyName(data, '', _intl.default.get('Empty'));
50
+ if (!Array.isArray(data)) return;
51
+ this.draw(data);
52
+ (0, _utils.isFunction)(customRender) && customRender(this.chart);
53
+ this.renderAxisLabel(this.props.chart, this.props.tables, this.container);
54
+ };
55
+ this.draw = data => {
56
+ const {
57
+ chart,
58
+ globalTheme,
59
+ tables
60
+ } = this.props;
61
+ const theme = _constants.CHART_THEME_COLOR[globalTheme];
62
+ const {
63
+ display_goal_line,
64
+ goal_label,
65
+ goal_value
66
+ } = chart.style_config || {};
67
+ const {
68
+ y_axis_summary_type,
69
+ y_axis_column_key,
70
+ y_axis_summary_column_key,
71
+ line_type,
72
+ y_axis_show_value,
73
+ label_font_size,
74
+ table_id,
75
+ y_axis_auto_range,
76
+ y_axis_min,
77
+ y_axis_max
78
+ } = chart.config;
79
+ const {
80
+ width: chartWidth,
81
+ height: chartHeight,
82
+ insertPadding,
83
+ marginTop
84
+ } = this.chartBoundingClientRect;
85
+ const tooltipTitle = this.getTitle(tables, table_id, y_axis_summary_type, y_axis_column_key || y_axis_summary_column_key);
86
+
87
+ // Y axis
88
+ const niceEnd = d3.nice(0, d3.max(data, d => d.value), 5)[1];
89
+ const y = d3.scaleLinear().domain(y_axis_auto_range ? [0, niceEnd] : [y_axis_min || 0, y_axis_max || niceEnd]).range([chartHeight - insertPadding, insertPadding + marginTop]);
90
+ this.chart.append('g').attr('transform', "translate(".concat(insertPadding, ", 0)")).call(d3.axisLeft(y).tickSizeInner(0).ticks(5).tickFormat(d => d)).call(g => this.drawYaxis(g, theme));
91
+
92
+ // X axis
93
+ const xDomain = data.map(item => item.name);
94
+ const x = d3.scaleBand().domain(xDomain).range([insertPadding + this.horizontalOverflowOffset, chartWidth - insertPadding]).paddingInner(0.4).paddingOuter(0.1);
95
+ this.ticksWrapper = this.chart.append('g').attr('transform', "translate(0, ".concat(chartHeight - insertPadding, ")")).call(d3.axisBottom(x).tickSizeOuter(0).tickSizeInner(5)).call(g => {
96
+ this.ticksAddName(g);
97
+ g.selectAll('.domain').attr('stroke', theme.XAxisColor);
98
+ g.selectAll('.tick line').attr('stroke', theme.XAxisColor);
99
+ g.selectAll('text').attr('font-size', theme.fontSize);
100
+ g.selectAll('text').attr('fill', theme.textColor);
101
+ this.checkTickOverlap(g);
102
+ });
103
+ const rectsWrapper = this.chart.append('g').attr('class', "rects-wrapper-".concat(chart === null || chart === void 0 ? void 0 : chart.id));
104
+
105
+ // Line
106
+ const circleData = xDomain.map(() => ({}));
107
+ const line = d3.line().x((d, index) => {
108
+ const xVal = x(d.name) + x.bandwidth() / 2;
109
+ circleData[index]['x'] = xVal;
110
+ circleData[index]['name'] = d.name;
111
+ return xVal;
112
+ }).y((d, index) => {
113
+ const yVal = y(d.value);
114
+ circleData[index]['y'] = yVal;
115
+ circleData[index]['value'] = d.value;
116
+ return yVal;
117
+ }).curve(line_type === _constants.CHART_LINE_TYPES[1] ? d3.curveBumpX : d3.curveLinear);
118
+ this.Line = rectsWrapper.append('path').attr('fill', 'none').attr('stroke', this.getAreaColor()).attr('stroke-width', 2).attr('d', () => line(data));
119
+
120
+ // Area
121
+ const area = d3.area().x(d => {
122
+ const xVal = x(d.name) + x.bandwidth() / 2;
123
+ return xVal;
124
+ }).y0(y(0)).y1(d => y(d.value)).curve(line_type === _constants.CHART_LINE_TYPES[1] ? d3.curveBumpX : d3.curveLinear);
125
+ this.Area = rectsWrapper.append('path').attr('fill', this.getAreaColor()).attr('d', () => area(data)).attr('opacity', '0.3');
126
+
127
+ // circle
128
+ circleData.forEach(item => {
129
+ rectsWrapper.append('circle').attr('cx', item.x).attr('cy', item.y).attr('r', 3).attr('fill', this.getAreaColor()).attr('opacity', y_axis_show_value ? 1 : 0).attr('data-text', item.value).attr('data-name', item.name).call(g => {
130
+ // circle label
131
+ if (y_axis_show_value) {
132
+ const curCircleEl = g.node();
133
+ rectsWrapper.append('text').attr('fill', theme.labelColor).attr('font-size', _utils.BaseUtils.getLabelFontSize(label_font_size)).text(curCircleEl.getAttribute('data-text')).call(g => {
134
+ const {
135
+ width
136
+ } = g.node().getBoundingClientRect();
137
+ const translateX = Number(curCircleEl.getAttribute('cx')) - width / 2;
138
+ const translateY = Number(curCircleEl.getAttribute('cy')) - 10;
139
+ g.attr('transform', "translate(".concat(translateX, ", ").concat(translateY, ")"));
140
+ });
141
+ }
142
+ }).on('click', (event, data) => {
143
+ this.props.toggleRecords(data);
144
+ });
145
+ });
146
+ this.chart.on('mouseover', event => {
147
+ this.updateCircleAndTickStyle({
148
+ event,
149
+ state: 'zoomIn',
150
+ circleData,
151
+ rectsWrapper,
152
+ eventState: 'over',
153
+ tooltipTitle
154
+ });
155
+ }).on('mousemove', event => {
156
+ this.updateCircleAndTickStyle({
157
+ event,
158
+ state: 'zoomIn',
159
+ circleData,
160
+ rectsWrapper,
161
+ eventState: 'move',
162
+ tooltipTitle
163
+ });
164
+ }).on('mouseleave', event => {
165
+ this.updateCircleAndTickStyle({
166
+ event,
167
+ state: 'zoomOut',
168
+ circleData,
169
+ rectsWrapper,
170
+ eventState: 'leave',
171
+ tooltipTitle
172
+ });
173
+ });
174
+ if (display_goal_line && goal_label && goal_value) {
175
+ this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y);
176
+ }
177
+ };
178
+ this.updateCircleAndTickStyle = _ref => {
179
+ var _rectsWrapper$selectA, _this$ticksWrapper$se;
180
+ let {
181
+ event,
182
+ state,
183
+ circleData,
184
+ rectsWrapper,
185
+ eventState,
186
+ tooltipTitle
187
+ } = _ref;
188
+ const {
189
+ y_axis_show_value
190
+ } = this.props.chart.config;
191
+ const {
192
+ height: chartHeight,
193
+ insertPadding,
194
+ marginTop
195
+ } = this.chartBoundingClientRect;
196
+ const {
197
+ offsetX
198
+ } = event;
199
+ const minDistanceItem = this.getMinDistanceItem(offsetX, circleData);
200
+ const circleList = (_rectsWrapper$selectA = rectsWrapper.selectAll('circle')) === null || _rectsWrapper$selectA === void 0 ? void 0 : _rectsWrapper$selectA.nodes();
201
+ if (circleList.length !== 0) {
202
+ if (state === 'zoomIn') {
203
+ circleList.forEach(circle => {
204
+ const name = circle.getAttribute('data-name');
205
+ if (name === minDistanceItem.name) {
206
+ d3.select(circle).attr('opacity', 1);
207
+ d3.select(circle).attr('r', 5);
208
+ } else {
209
+ d3.select(circle).attr('opacity', 0.3);
210
+ d3.select(circle).attr('r', 3);
211
+ }
212
+ });
213
+ this.Area.attr('opacity', 0.1);
214
+ this.Line.attr('opacity', 0.3);
215
+ } else {
216
+ circleList.forEach(circle => {
217
+ if (!y_axis_show_value) {
218
+ d3.select(circle).attr('opacity', 0);
219
+ } else {
220
+ d3.select(circle).attr('opacity', 1);
221
+ }
222
+ d3.select(circle).attr('r', 3);
223
+ });
224
+ this.Area.attr('opacity', 0.3);
225
+ this.Line.attr('opacity', 1);
226
+ }
227
+ }
228
+ const ticks = (_this$ticksWrapper$se = this.ticksWrapper.selectAll('.tick line')) === null || _this$ticksWrapper$se === void 0 ? void 0 : _this$ticksWrapper$se.nodes();
229
+ if (ticks.length !== 0) {
230
+ if (state === 'zoomIn') {
231
+ ticks.forEach(tick => {
232
+ const name = tick.getAttribute('data-name');
233
+ if (name === minDistanceItem.name) {
234
+ d3.select(tick).attr('y2', -(chartHeight - insertPadding * 2 - marginTop));
235
+ } else {
236
+ d3.select(tick).attr('y2', 0);
237
+ }
238
+ });
239
+ } else {
240
+ ticks.forEach(tick => {
241
+ d3.select(tick).attr('y2', 0);
242
+ });
243
+ }
244
+ }
245
+
246
+ // tooltip
247
+ if (eventState === 'over') {
248
+ this.showTooltip(event, minDistanceItem, tooltipTitle);
249
+ }
250
+ if (eventState === 'move') {
251
+ this.moveTooltip(event, minDistanceItem, tooltipTitle);
252
+ }
253
+ if (eventState === 'leave') {
254
+ this.hiddenTooltip();
255
+ }
256
+ };
257
+ this.showTooltip = (event, data, title) => {
258
+ const {
259
+ offsetX,
260
+ offsetY
261
+ } = event;
262
+ const {
263
+ chart,
264
+ summaryColumn
265
+ } = this.props;
266
+ const {
267
+ y_axis_summary_method
268
+ } = chart.config;
269
+ const newTooltipData = {
270
+ title: title,
271
+ items: [{
272
+ color: this.getAreaColor(),
273
+ name: data.name,
274
+ value: _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, data.value, y_axis_summary_method)
275
+ }]
276
+ };
277
+ this.setState({
278
+ tooltipData: newTooltipData
279
+ });
280
+ this.setState({
281
+ toolTipPosition: {
282
+ offsetX,
283
+ offsetY
284
+ }
285
+ });
286
+ };
287
+ this.moveTooltip = (event, data, title) => {
288
+ const {
289
+ offsetX,
290
+ offsetY
291
+ } = event;
292
+ const {
293
+ chart,
294
+ summaryColumn
295
+ } = this.props;
296
+ const {
297
+ y_axis_summary_method
298
+ } = chart.config;
299
+ const newTooltipData = {
300
+ title: title,
301
+ items: [{
302
+ color: this.getAreaColor(),
303
+ name: data.name,
304
+ value: _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, data.value, y_axis_summary_method)
305
+ }]
306
+ };
307
+ this.setState({
308
+ tooltipData: newTooltipData
309
+ });
310
+ this.setState({
311
+ toolTipPosition: {
312
+ offsetX,
313
+ offsetY
314
+ }
315
+ });
316
+ };
317
+ this.hiddenTooltip = event => {
318
+ this.setState({
319
+ toolTipPosition: null
320
+ });
321
+ };
322
+ this.getAreaColor = () => {
323
+ const {
324
+ chart,
325
+ chartColorTheme
326
+ } = this.props;
327
+ const {
328
+ y_axis_label_color,
329
+ color_option
330
+ } = chart.config;
331
+ let chartBarColor = _constants.CHART_STYLE_COLORS[0];
332
+ if (chartColorTheme) {
333
+ chartBarColor = _utils.BaseUtils.getCurrentTheme(chartColorTheme).colors[0];
334
+ }
335
+ if (color_option === _constants.TYPE_COLOR_USING.USE_SPECIFIC_COLORS && y_axis_label_color) {
336
+ chartBarColor = y_axis_label_color;
337
+ }
338
+ return chartBarColor;
339
+ };
340
+ this.chart = null;
341
+ this.state = {
342
+ tooltipData: null,
343
+ toolTipPosition: null
344
+ };
345
+ }
346
+ componentDidMount() {
347
+ this.createChart();
348
+ this.drawChart();
349
+ this.debouncedHandleResize = (0, _lodashEs.debounce)(this.handleResize, 300);
350
+ window.addEventListener('resize', this.debouncedHandleResize);
351
+ super.componentDidMount();
352
+ }
353
+ componentDidUpdate(prevProps) {
354
+ super.componentDidUpdate(prevProps);
355
+ if (_utils.BaseUtils.shouldChartComponentUpdate(prevProps, this.props)) {
356
+ this.chart.node() && this.chart.node().remove();
357
+ this.createChart();
358
+ this.drawChart();
359
+ }
360
+ }
361
+ componentWillUnmount() {
362
+ this.chart.node() && this.chart.node().remove();
363
+ window.removeEventListener('resize', this.debouncedHandleResize);
364
+ super.componentWillUnmount();
365
+ }
366
+ render() {
367
+ const {
368
+ chart
369
+ } = this.props;
370
+ const {
371
+ tooltipData,
372
+ toolTipPosition
373
+ } = this.state;
374
+ return /*#__PURE__*/_react.default.createElement("div", {
375
+ ref: ref => this.container = ref,
376
+ className: (0, _classnames.default)('sea-chart-container', {
377
+ 'show-x-axis-label': this.isShowXAxisLabel(chart),
378
+ 'show-y-axis-label': this.isShowYAxisLabel(chart)
379
+ })
380
+ }, /*#__PURE__*/_react.default.createElement(_tooltip.default, {
381
+ tooltipData: tooltipData,
382
+ toolTipPosition: toolTipPosition,
383
+ chart: this.chart
384
+ }));
385
+ }
386
+ }
387
+ Area.propTypes = {
388
+ canvasStyle: _propTypes.default.object,
389
+ chart: _propTypes.default.object,
390
+ groupbyColumn: _propTypes.default.object,
391
+ columnGroupbyColumn: _propTypes.default.object,
392
+ summaryColumn: _propTypes.default.object,
393
+ result: _propTypes.default.array,
394
+ tables: _propTypes.default.array,
395
+ globalTheme: _propTypes.default.string,
396
+ chartColorTheme: _propTypes.default.string,
397
+ toggleRecords: _propTypes.default.func,
398
+ customRender: _propTypes.default.func
399
+ };
400
+ var _default = exports.default = Area;
@@ -595,6 +595,7 @@ class ChartComponent extends _react.Component {
595
595
  groupColumn
596
596
  } = _ref;
597
597
  if (!this.chart) return;
598
+ data.forEach(item => item[legendName] = String(item[legendName]));
598
599
  const legendData = (0, _lodashEs.cloneDeep)(data);
599
600
  this.legendConfig = {
600
601
  legendRectWidth: 20,
@@ -604,6 +605,7 @@ class ChartComponent extends _react.Component {
604
605
  legendItemMargin: 20,
605
606
  legendRecTextGap: 8,
606
607
  legendPageNavWrapperWidth: 100,
608
+ legendPageNavWrapperHeight: 18,
607
609
  legendPosition,
608
610
  legendName,
609
611
  theme
@@ -615,7 +617,8 @@ class ChartComponent extends _react.Component {
615
617
  }
616
618
  const {
617
619
  width: chartWidth,
618
- insertPadding
620
+ insertPadding,
621
+ rightLegendSpace
619
622
  } = this.chartBoundingClientRect;
620
623
  const groupsData = this.getLegendDataGroups(legendData);
621
624
  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));
@@ -631,7 +634,8 @@ class ChartComponent extends _react.Component {
631
634
  // Render Page navigator
632
635
  if (groupsData.length > 1) {
633
636
  const {
634
- legendPageNavWrapperWidth
637
+ legendPageNavWrapperWidth,
638
+ legendItemMargin
635
639
  } = this.legendConfig;
636
640
  let curCount = 0;
637
641
  const pageNavigator = legendWrapper.append('g').attr('class', 'legend-flip-page');
@@ -670,6 +674,7 @@ class ChartComponent extends _react.Component {
670
674
  // update pageNavigator transform
671
675
  pageNavigator.call(g => {
672
676
  let groupTranslateX = 0;
677
+ let groupTranslateY = 0;
673
678
  if (legendPosition === 'top-right') {
674
679
  groupTranslateX = insertPadding;
675
680
  } else if (legendPosition === 'top-left') {
@@ -679,8 +684,14 @@ class ChartComponent extends _react.Component {
679
684
  } = g.node().getBoundingClientRect();
680
685
  const offset = legendPageNavWrapperWidth - width;
681
686
  groupTranslateX = groupTranslateX + offset;
687
+ } else if (legendPosition === 'center-right') {
688
+ groupTranslateX = chartWidth - insertPadding - rightLegendSpace;
689
+ const {
690
+ height
691
+ } = g.node().parentNode.getBoundingClientRect();
692
+ groupTranslateY = groupTranslateY + height + legendItemMargin;
682
693
  }
683
- g.attr('transform', "translate(".concat(groupTranslateX, ", 0)"));
694
+ g.attr('transform', "translate(".concat(groupTranslateX, ", ").concat(groupTranslateY, ")"));
684
695
  });
685
696
  }
686
697
  };
@@ -732,35 +743,53 @@ class ChartComponent extends _react.Component {
732
743
  const parentNode = rect.parentNode;
733
744
  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
745
  });
735
- // update g translateX
736
746
  const legendItems = Array.from(legendWrapper.node().children).filter(item => item.getAttribute('class') !== 'legend-flip-page');
737
747
  const {
738
748
  start,
739
- end
749
+ end,
750
+ top,
751
+ bottom
740
752
  } = this.getLegendBoundary(legendPosition);
741
- legendItems.forEach((item, index) => {
742
- let translateX = start;
743
- const prevItem = legendItems[index - 1];
744
- if (index > 0) {
745
- const {
746
- width
747
- } = prevItem.getBoundingClientRect();
748
- const prevTranslateX = Number(prevItem.getAttribute('data-translateX'));
749
- translateX = prevTranslateX + width + legendItemMargin;
750
- }
751
- d3.select(item).attr('transform', "translate(".concat(translateX, ",0)")).attr('data-translateX', translateX);
753
+ if (top && bottom) {
754
+ // update g translateY
755
+ legendItems.forEach((item, index) => {
756
+ let translateY = top;
757
+ const prevItem = legendItems[index - 1];
758
+ if (index > 0) {
759
+ const {
760
+ height
761
+ } = prevItem.getBoundingClientRect();
762
+ const prevTranslateY = Number(prevItem.getAttribute('data-translateY'));
763
+ translateY = prevTranslateY + height + legendItemMargin;
764
+ }
765
+ d3.select(item).attr('transform', "translate(".concat(start, ",").concat(translateY, ")")).attr('data-translateY', translateY);
766
+ });
767
+ } else {
768
+ // update g translateX
769
+ legendItems.forEach((item, index) => {
770
+ let translateX = start;
771
+ const prevItem = legendItems[index - 1];
772
+ if (index > 0) {
773
+ const {
774
+ width
775
+ } = prevItem.getBoundingClientRect();
776
+ const prevTranslateX = Number(prevItem.getAttribute('data-translateX'));
777
+ translateX = prevTranslateX + width + legendItemMargin;
778
+ }
779
+ d3.select(item).attr('transform', "translate(".concat(translateX, ",0)")).attr('data-translateX', translateX);
752
780
 
753
- // legend items add offset
754
- if (legendPosition === 'top-right') {
755
- d3.select(item).attr('opacity', 0);
756
- // Execute only once
757
- if (index === legendItems.length - 1) {
758
- queueMicrotask(() => {
759
- this.setLegendItemOffset(legendItems, end);
760
- });
781
+ // legend items add offset
782
+ if (legendPosition === 'top-right') {
783
+ d3.select(item).attr('opacity', 0);
784
+ // Execute only once
785
+ if (index === legendItems.length - 1) {
786
+ queueMicrotask(() => {
787
+ this.setLegendItemOffset(legendItems, end);
788
+ });
789
+ }
761
790
  }
762
- }
763
- });
791
+ });
792
+ }
764
793
  });
765
794
  };
766
795
  this.getLegendDataGroups = legendData => {
@@ -779,43 +808,77 @@ class ChartComponent extends _react.Component {
779
808
  } = this.legendConfig;
780
809
  const {
781
810
  start,
782
- end
811
+ end,
812
+ top,
813
+ bottom
783
814
  } = this.getLegendBoundary(legendPosition);
784
- let allWidth = start;
785
- const groupsData = [];
786
- const newLegendData = (0, _lodashEs.cloneDeep)(legendData);
787
- let lastIndex = 0;
788
- legendData.forEach((item, index) => {
789
- const virtualLegend = this.chart.append('g').attr('opacity', 0);
790
- virtualLegend.append('rect').attr('width', legendRectWidth).attr('height', legendRectHeight).attr('rx', r);
791
- virtualLegend.append('text').attr('x', legendRectWidth + legendRecTextGap).attr('font-size', theme.legendFontSize).text(this.formatterLegendName(item[0]));
792
- const {
793
- width
794
- } = virtualLegend.node().getBoundingClientRect();
795
- const itemWidth = index === legendData.length - 1 ? width : width + legendItemMargin; // last item no used margin
796
- allWidth = allWidth + itemWidth;
797
- if (allWidth > end) {
798
- groupsData.push(newLegendData.slice(0, index - lastIndex));
799
- newLegendData.splice(0, index - lastIndex);
800
- lastIndex = index;
801
- allWidth = start + itemWidth;
802
- }
803
- virtualLegend.remove();
804
- });
805
- const restLegendItems = newLegendData.slice(0);
806
- restLegendItems.length !== 0 && groupsData.push(restLegendItems);
807
- return groupsData;
815
+ if (top && bottom) {
816
+ let allHeight = top;
817
+ const groupsData = [];
818
+ const newLegendData = (0, _lodashEs.cloneDeep)(legendData);
819
+ let lastIndex = 0;
820
+ legendData.forEach((item, index) => {
821
+ const virtualLegend = this.chart.append('g').attr('opacity', 0);
822
+ virtualLegend.append('rect').attr('width', legendRectWidth).attr('height', legendRectHeight).attr('rx', r);
823
+ virtualLegend.append('text').attr('x', legendRectWidth + legendRecTextGap).attr('font-size', theme.legendFontSize).text(this.formatterLegendName(item[0]));
824
+ const {
825
+ height
826
+ } = virtualLegend.node().getBoundingClientRect();
827
+ const itemHeight = index === legendData.length - 1 ? height : height + legendItemMargin; // last item no used margin
828
+ allHeight = allHeight + itemHeight;
829
+ if (allHeight > bottom) {
830
+ groupsData.push(newLegendData.slice(0, index - lastIndex));
831
+ newLegendData.splice(0, index - lastIndex);
832
+ lastIndex = index;
833
+ allHeight = top + itemHeight;
834
+ }
835
+ virtualLegend.remove();
836
+ });
837
+ const restLegendItems = newLegendData.slice(0);
838
+ restLegendItems.length !== 0 && groupsData.push(restLegendItems);
839
+ return groupsData;
840
+ } else {
841
+ let allWidth = start;
842
+ const groupsData = [];
843
+ const newLegendData = (0, _lodashEs.cloneDeep)(legendData);
844
+ let lastIndex = 0;
845
+ legendData.forEach((item, index) => {
846
+ const virtualLegend = this.chart.append('g').attr('opacity', 0);
847
+ virtualLegend.append('rect').attr('width', legendRectWidth).attr('height', legendRectHeight).attr('rx', r);
848
+ virtualLegend.append('text').attr('x', legendRectWidth + legendRecTextGap).attr('font-size', theme.legendFontSize).text(this.formatterLegendName(item[0]));
849
+ const {
850
+ width
851
+ } = virtualLegend.node().getBoundingClientRect();
852
+ const itemWidth = index === legendData.length - 1 ? width : width + legendItemMargin; // last item no used margin
853
+ allWidth = allWidth + itemWidth;
854
+ if (allWidth > end) {
855
+ groupsData.push(newLegendData.slice(0, index - lastIndex));
856
+ newLegendData.splice(0, index - lastIndex);
857
+ lastIndex = index;
858
+ allWidth = start + itemWidth;
859
+ }
860
+ virtualLegend.remove();
861
+ });
862
+ const restLegendItems = newLegendData.slice(0);
863
+ restLegendItems.length !== 0 && groupsData.push(restLegendItems);
864
+ return groupsData;
865
+ }
808
866
  };
809
867
  this.getLegendBoundary = legendPosition => {
810
868
  const {
811
- legendPageNavWrapperWidth
869
+ legendPageNavWrapperWidth,
870
+ legendPageNavWrapperHeight
812
871
  } = this.legendConfig;
813
872
  const {
814
873
  width: chartWidth,
815
- insertPadding
874
+ height: chartHeight,
875
+ insertPadding,
876
+ rightLegendSpace
816
877
  } = this.chartBoundingClientRect;
817
878
  let start = 0;
818
879
  let end = 0;
880
+ let top = 0;
881
+ let bottom = 0;
819
882
  if (legendPosition === 'top-left') {
820
883
  start = insertPadding;
821
884
  end = chartWidth - insertPadding - legendPageNavWrapperWidth;
@@ -824,9 +887,17 @@ class ChartComponent extends _react.Component {
824
887
  start = insertPadding + legendPageNavWrapperWidth;
825
888
  end = chartWidth - insertPadding;
826
889
  }
890
+ if (legendPosition === 'center-right') {
891
+ start = chartWidth - insertPadding - rightLegendSpace;
892
+ end = chartWidth - insertPadding;
893
+ top = insertPadding;
894
+ bottom = chartHeight - insertPadding - legendPageNavWrapperHeight;
895
+ }
827
896
  return {
828
897
  start,
829
- end
898
+ end,
899
+ top,
900
+ bottom
830
901
  };
831
902
  };
832
903
  this.handleNavigatorOpacity = (navigator, text) => {
@@ -1318,6 +1389,26 @@ class ChartComponent extends _react.Component {
1318
1389
  }
1319
1390
  }
1320
1391
  };
1392
+ this.ticksAddName = g => {
1393
+ if (g.selectAll('.tick')) {
1394
+ const ticks = g.selectAll('.tick').nodes();
1395
+ ticks.forEach(tick => {
1396
+ var _d3$select$select;
1397
+ const text = (_d3$select$select = d3.select(tick).select('text')) === null || _d3$select$select === void 0 ? void 0 : _d3$select$select.node();
1398
+ d3.select(tick).select('line').attr('data-name', text.innerHTML);
1399
+ });
1400
+ }
1401
+ };
1402
+ this.getMinDistanceItem = (offsetX, allData) => {
1403
+ // allData = [{x: number}]
1404
+ const newAllData = allData.filter(item => Object.keys(item).length !== 0);
1405
+ newAllData.forEach(item => {
1406
+ item['distance'] = Math.abs(item.x - offsetX);
1407
+ });
1408
+ const minIndex = d3.minIndex(newAllData, d => d.distance);
1409
+ const minItem = newAllData[minIndex];
1410
+ return minItem;
1411
+ };
1321
1412
  this.initLabelStroke(props === null || props === void 0 ? void 0 : props.globalTheme);
1322
1413
  this.chartBoundingClientRect = {};
1323
1414
  }