sea-chart 2.0.58 → 2.0.60

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.
@@ -565,27 +565,63 @@ class ChartComponent extends _react.Component {
565
565
  return _intl.default.get(name) || name;
566
566
  }
567
567
  };
568
+ this.getSvgTextWidth = textNode => {
569
+ if (!textNode) return 0;
570
+ if (typeof textNode.getComputedTextLength === 'function') {
571
+ return textNode.getComputedTextLength();
572
+ }
573
+ return textNode.getBoundingClientRect().width;
574
+ };
575
+ this.getRightLegendLayout = _ref => {
576
+ let {
577
+ data,
578
+ legendName,
579
+ theme
580
+ } = _ref;
581
+ const {
582
+ width: chartWidth,
583
+ insertPadding
584
+ } = this.chartBoundingClientRect;
585
+ const legendRectWidth = 20;
586
+ const legendRecTextGap = 8;
587
+ const minChartWidth = 160;
588
+ const chartLegendGap = 30;
589
+ const measureText = text => {
590
+ const textNode = this.chart.append('text').attr('font-size', theme.legendFontSize).text(text).node();
591
+ const textWidth = this.getSvgTextWidth(textNode);
592
+ textNode.remove();
593
+ return textWidth;
594
+ };
595
+ const maxTextWidth = Array.from(new Set(data.map(item => item[legendName]))).reduce((maxWidth, name) => Math.max(maxWidth, measureText(this.formatterLegendName(name))), 0);
596
+ const desiredLegendSpace = legendRectWidth + legendRecTextGap + maxTextWidth;
597
+ const minLegendSpace = legendRectWidth + legendRecTextGap + measureText('...');
598
+ const maxLegendSpace = chartWidth - insertPadding * 2 - minChartWidth - chartLegendGap;
599
+ const rightLegendSpace = Math.min(desiredLegendSpace, Math.max(minLegendSpace, maxLegendSpace));
600
+ return {
601
+ rightLegendSpace,
602
+ chartLegendGap
603
+ };
604
+ };
568
605
  this.truncateLegendText = (textNode, maxWidth) => {
569
- if (!textNode || !Number.isFinite(maxWidth) || maxWidth <= 0) return false;
606
+ if (!textNode || !Number.isFinite(maxWidth)) return false;
570
607
  const fullText = textNode.textContent || '';
571
- const getTextWidth = () => {
572
- if (typeof textNode.getComputedTextLength === 'function') {
573
- return textNode.getComputedTextLength();
574
- }
575
- return textNode.getBoundingClientRect().width;
576
- };
577
- if (!fullText || getTextWidth() <= maxWidth) return false;
608
+ if (!fullText) return false;
609
+ if (maxWidth <= 0) {
610
+ textNode.textContent = '...';
611
+ return true;
612
+ }
613
+ if (this.getSvgTextWidth(textNode) <= maxWidth) return false;
578
614
  const ellipsis = '...';
579
615
  let textLength = fullText.length;
580
616
  while (textLength > 0) {
581
617
  textNode.textContent = `${fullText.slice(0, textLength)}${ellipsis}`;
582
- if (getTextWidth() <= maxWidth) return true;
618
+ if (this.getSvgTextWidth(textNode) <= maxWidth) return true;
583
619
  textLength--;
584
620
  }
585
621
  textNode.textContent = ellipsis;
586
622
  return true;
587
623
  };
588
- this.setLegend = _ref => {
624
+ this.setLegend = _ref2 => {
589
625
  var _chart$config, _chart$config2;
590
626
  let {
591
627
  legendName,
@@ -595,7 +631,7 @@ class ChartComponent extends _react.Component {
595
631
  colorScale,
596
632
  groupColumn,
597
633
  chart
598
- } = _ref;
634
+ } = _ref2;
599
635
  if (!this.chart) return;
600
636
  this.legendConfig = {
601
637
  legendRectWidth: [_constants.CHART_TYPE.SCATTER, _constants.CHART_TYPE.MIRROR].includes(chart === null || chart === void 0 ? void 0 : (_chart$config = chart.config) === null || _chart$config === void 0 ? void 0 : _chart$config.type) ? 8 : 20,
@@ -732,14 +768,14 @@ class ChartComponent extends _react.Component {
732
768
  });
733
769
  }
734
770
  };
735
- this.renderLegend = _ref2 => {
771
+ this.renderLegend = _ref3 => {
736
772
  let {
737
773
  legendWrapper,
738
774
  groupData,
739
775
  colorScale,
740
776
  theme,
741
777
  text
742
- } = _ref2;
778
+ } = _ref3;
743
779
  const {
744
780
  legendItemPaddingTop,
745
781
  legendItemTextPaddingTop,
@@ -765,15 +801,15 @@ class ChartComponent extends _react.Component {
765
801
  d3.select(item).remove();
766
802
  });
767
803
  }
768
- legendWrapper.selectAll().data(groupData).join('g').attr('data-groupName', _ref3 => {
769
- let [groupName] = _ref3;
770
- return groupName;
771
- }).append('rect').attr('width', legendRectWidth).attr('height', legendRectHeight).attr('y', legendItemPaddingTop).attr('rx', r).attr('fill', _ref4 => {
804
+ legendWrapper.selectAll().data(groupData).join('g').attr('data-groupName', _ref4 => {
772
805
  let [groupName] = _ref4;
806
+ return groupName;
807
+ }).append('rect').attr('width', legendRectWidth).attr('height', legendRectHeight).attr('y', legendItemPaddingTop).attr('rx', r).attr('fill', _ref5 => {
808
+ let [groupName] = _ref5;
773
809
  if (colorScale) return colorScale(groupName);
774
810
  return this.colorMap[groupName] || _constants.CHART_STYLE_COLORS[0];
775
- }).attr('data-text', _ref5 => {
776
- let [groupName] = _ref5;
811
+ }).attr('data-text', _ref6 => {
812
+ let [groupName] = _ref6;
777
813
  return groupName;
778
814
  }).call(g => {
779
815
  const legendItems = Array.from(legendWrapper.node().children).filter(item => item.getAttribute('class') !== 'legend-flip-page');
@@ -783,8 +819,7 @@ class ChartComponent extends _react.Component {
783
819
  top,
784
820
  bottom
785
821
  } = this.getLegendBoundary(legendPosition);
786
- const legendTranslateX = legendPosition === 'center-right' ? start - 50 : start;
787
- const maxLegendTextWidth = legendPosition === 'center-right' ? end - legendTranslateX - legendRectWidth - legendRecTextGap : null;
822
+ const maxLegendTextWidth = legendPosition === 'center-right' ? end - start - legendRectWidth - legendRecTextGap : null;
788
823
 
789
824
  // Add text
790
825
  g.nodes().forEach(rect => {
@@ -807,8 +842,7 @@ class ChartComponent extends _react.Component {
807
842
  const prevTranslateY = Number(prevItem.getAttribute('data-translateY'));
808
843
  translateY = prevTranslateY + height + legendItemMargin;
809
844
  }
810
- const translateX = legendPosition === 'center-right' ? start - 50 : start;
811
- d3.select(item).attr('transform', `translate(${translateX},${translateY})`).attr('data-translateY', translateY);
845
+ d3.select(item).attr('transform', `translate(${start},${translateY})`).attr('data-translateY', translateY);
812
846
  this.bindLegendItemInteraction(item);
813
847
  });
814
848
  } else {
@@ -1153,7 +1187,7 @@ class ChartComponent extends _react.Component {
1153
1187
  annotationWrapper.append('text').attr('x', chartWidth - insertPadding - 30).attr('y', yScale(goal_value) - 10).attr('fill', '#666').text(goal_label);
1154
1188
  });
1155
1189
  };
1156
- this.addLabelToRectTop = _ref6 => {
1190
+ this.addLabelToRectTop = _ref7 => {
1157
1191
  let {
1158
1192
  container,
1159
1193
  x,
@@ -1162,7 +1196,7 @@ class ChartComponent extends _react.Component {
1162
1196
  theme,
1163
1197
  label_font_size,
1164
1198
  text
1165
- } = _ref6;
1199
+ } = _ref7;
1166
1200
  d3.select(container).append('text').attr('stroke', '#fff').attr('stroke-width', 1).attr('paint-order', 'stroke').attr('y', Number(y) - 10).attr('fill', theme.labelColor).attr('font-size', _utils.BaseUtils.getLabelFontSize(label_font_size)).text(text).call(g => {
1167
1201
  if (!g.node()) return;
1168
1202
  const {
@@ -1171,7 +1205,7 @@ class ChartComponent extends _react.Component {
1171
1205
  g.attr('x', Number(x) + Number(xWidth) / 2 - width / 2);
1172
1206
  });
1173
1207
  };
1174
- this.addLabelToRectRight = _ref7 => {
1208
+ this.addLabelToRectRight = _ref8 => {
1175
1209
  let {
1176
1210
  container,
1177
1211
  x,
@@ -1181,7 +1215,7 @@ class ChartComponent extends _react.Component {
1181
1215
  theme,
1182
1216
  label_font_size,
1183
1217
  text
1184
- } = _ref7;
1218
+ } = _ref8;
1185
1219
  d3.select(container).append('text').attr('stroke', '#fff').attr('stroke-width', 1).attr('paint-order', 'stroke').attr('x', Number(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 => {
1186
1220
  if (g.node()) {
1187
1221
  var _g$node;
@@ -1192,7 +1226,7 @@ class ChartComponent extends _react.Component {
1192
1226
  }
1193
1227
  });
1194
1228
  };
1195
- this.addLabelToRectCenter = _ref8 => {
1229
+ this.addLabelToRectCenter = _ref9 => {
1196
1230
  let {
1197
1231
  chartType,
1198
1232
  container,
@@ -1203,7 +1237,7 @@ class ChartComponent extends _react.Component {
1203
1237
  theme,
1204
1238
  label_font_size,
1205
1239
  text
1206
- } = _ref8;
1240
+ } = _ref9;
1207
1241
  d3.select(container).append('text').attr('stroke', '#fff').attr('stroke-width', 1).attr('paint-order', 'stroke').attr('fill', theme.labelColor).attr('font-size', _utils.BaseUtils.getLabelFontSize(label_font_size)).text(text).call(g => {
1208
1242
  if (!g.node()) return;
1209
1243
  const {
@@ -1245,12 +1279,12 @@ class ChartComponent extends _react.Component {
1245
1279
  });
1246
1280
  }
1247
1281
  };
1248
- this.addClipPath = _ref9 => {
1282
+ this.addClipPath = _ref0 => {
1249
1283
  let {
1250
1284
  rect,
1251
1285
  attr,
1252
1286
  borderRadiusVal
1253
- } = _ref9;
1287
+ } = _ref0;
1254
1288
  return this.addRoundedClip(rect, attr === 'x' ? 'x' : 'y', null, borderRadiusVal);
1255
1289
  };
1256
1290
  this.addRoundedClip = function (rect, orient) {
@@ -1503,13 +1537,13 @@ class ChartComponent extends _react.Component {
1503
1537
  }).filter(Boolean).sort((a, b) => a.top - b.top);
1504
1538
  const keptTicks = [];
1505
1539
  let prevBottom = -Infinity;
1506
- visibleTicks.forEach(_ref0 => {
1540
+ visibleTicks.forEach(_ref1 => {
1507
1541
  let {
1508
1542
  tick,
1509
1543
  index,
1510
1544
  top,
1511
1545
  bottom
1512
- } = _ref0;
1546
+ } = _ref1;
1513
1547
  const shouldKeepFirstTick = index === 0;
1514
1548
  const shouldKeepLastTick = index === ticks.length - 1;
1515
1549
  const hasEnoughSpace = top > prevBottom + this.yAxisTickLabelGap;
@@ -1711,11 +1745,11 @@ class ChartComponent extends _react.Component {
1711
1745
  const annotationWrapper = contentWrapper.insert('g', ':first-child').attr('class', 'vertical-annotation-wrapper');
1712
1746
  annotationWrapper.append('line').attr('x1', x).attr('y1', insertPadding + marginTop).attr('x2', x).attr('y2', chartHeight - insertPadding).attr('stroke', theme.XAxisColor);
1713
1747
  };
1714
- this.setLegendForHeatMap = _ref1 => {
1748
+ this.setLegendForHeatMap = _ref10 => {
1715
1749
  let {
1716
1750
  exampleColors,
1717
1751
  themeColors
1718
- } = _ref1;
1752
+ } = _ref10;
1719
1753
  const legendOffsetY = 3;
1720
1754
  const legendItemTextWidth = 32;
1721
1755
  const legendItemWidth = 12;
@@ -1729,7 +1763,7 @@ class ChartComponent extends _react.Component {
1729
1763
  });
1730
1764
  legendWrapper.append('text').attr('x', 182).attr('y', 10).attr('fill', themeColors.textColor).attr('font-size', 12).attr('font-weight', 'bold').text(_intl.default.get('More'));
1731
1765
  };
1732
- this.setContinuousLegend = _ref10 => {
1766
+ this.setContinuousLegend = _ref11 => {
1733
1767
  var _this$chart$node2;
1734
1768
  let {
1735
1769
  previewType,
@@ -1740,7 +1774,7 @@ class ChartComponent extends _react.Component {
1740
1774
  legendTextRange,
1741
1775
  bubbleColor,
1742
1776
  type
1743
- } = _ref10;
1777
+ } = _ref11;
1744
1778
  const {
1745
1779
  width: chartWidth,
1746
1780
  height: chartHeight,
@@ -22,12 +22,9 @@ class Pie extends _chartComponent.default {
22
22
  const {
23
23
  chart
24
24
  } = this.props;
25
- const {
26
- show_legend
27
- } = chart.config;
28
25
  const initConfig = {
29
26
  insertPadding: 30,
30
- rightLegendSpace: show_legend ? 50 : 0
27
+ rightLegendSpace: 0
31
28
  };
32
29
  this.initChart(this.container, chart === null || chart === void 0 ? void 0 : chart.id, initConfig);
33
30
  };
@@ -57,8 +54,7 @@ class Pie extends _chartComponent.default {
57
54
  const {
58
55
  width: chartWidth,
59
56
  height: chartHeight,
60
- insertPadding,
61
- rightLegendSpace
57
+ insertPadding
62
58
  } = this.chartBoundingClientRect;
63
59
  this.isInnerLabel = !label_position || label_position === _constants.CHART_LABEL_POSITIONS[0];
64
60
  const currentTheme = _utils.BaseUtils.getCurrentTheme(chartColorTheme);
@@ -68,6 +64,17 @@ class Pie extends _chartComponent.default {
68
64
  colorMap
69
65
  } = _utils.BaseUtils.formatPieChartData(data, chart, tables, currentTheme, useSingleSelectColumnColor);
70
66
  if (!Array.isArray(newData) || newData.length === 0) return;
67
+ const {
68
+ rightLegendSpace = 0,
69
+ chartLegendGap = 0
70
+ } = show_legend ? this.getRightLegendLayout({
71
+ data: newData,
72
+ legendName: 'name',
73
+ theme
74
+ }) : {};
75
+ this.chartBoundingClientRect.rightLegendSpace = rightLegendSpace;
76
+ const plotWidth = Math.max(0, chartWidth - insertPadding * 2 - rightLegendSpace - chartLegendGap);
77
+ const radiusWidth = show_legend ? plotWidth : chartWidth;
71
78
 
72
79
  // Only the visible categories are laid out; the legend still shows every category.
73
80
  const visibleData = this.getVisibleLegendData(newData, 'name');
@@ -80,7 +87,7 @@ class Pie extends _chartComponent.default {
80
87
  // Pie and Arc
81
88
  const pie = d3.pie().sort(null).value(d => d.value);
82
89
  const arcs = pie(visibleData);
83
- const arc = d3.arc().innerRadius(0).outerRadius(Math.min(chartWidth, chartHeight) / 2 * 0.7);
90
+ const arc = d3.arc().innerRadius(0).outerRadius(Math.min(radiusWidth, chartHeight) / 2 * 0.7);
84
91
 
85
92
  // Draw Pie
86
93
  this.chart.append('g').attr('class', 'content-wrapper').attr('stroke', 'white').selectAll().data(arcs).join('path').attr('stroke-width', 2).attr('opacity', 1).attr('fill', d => color(d.data.name)).attr('d', arc).attr('data-groupName', d => d.data.name).call(g => {
@@ -91,7 +98,7 @@ class Pie extends _chartComponent.default {
91
98
  } = (_g$node$parentNode = g.node().parentNode) === null || _g$node$parentNode === void 0 ? void 0 : _g$node$parentNode.getBoundingClientRect();
92
99
  const left = width / 2 + insertPadding;
93
100
  const top = height / 2 + insertPadding;
94
- const offsetX = (chartWidth - (insertPadding + rightLegendSpace) - insertPadding - width) / 2;
101
+ const offsetX = (plotWidth - width) / 2;
95
102
  const offsetY = (chartHeight - insertPadding - insertPadding - height) / 2;
96
103
  d3.select(g.node().parentNode).attr('transform', `translate(${left + offsetX}, ${top + offsetY})`);
97
104
 
@@ -22,12 +22,9 @@ class Ring extends _chartComponent.default {
22
22
  const {
23
23
  chart
24
24
  } = this.props;
25
- const {
26
- show_legend
27
- } = chart.config;
28
25
  const initConfig = {
29
26
  insertPadding: 30,
30
- rightLegendSpace: show_legend ? 50 : 0
27
+ rightLegendSpace: 0
31
28
  };
32
29
  this.initChart(this.container, chart === null || chart === void 0 ? void 0 : chart.id, initConfig);
33
30
  };
@@ -57,8 +54,7 @@ class Ring extends _chartComponent.default {
57
54
  const {
58
55
  width: chartWidth,
59
56
  height: chartHeight,
60
- insertPadding,
61
- rightLegendSpace
57
+ insertPadding
62
58
  } = this.chartBoundingClientRect;
63
59
  this.isInnerLabel = !label_position || label_position === _constants.CHART_LABEL_POSITIONS[0];
64
60
  const currentTheme = _utils.BaseUtils.getCurrentTheme(chartColorTheme);
@@ -69,6 +65,17 @@ class Ring extends _chartComponent.default {
69
65
  total: fullTotal
70
66
  } = _utils.BaseUtils.formatPieChartData(data, chart, tables, currentTheme, useSingleSelectColumnColor);
71
67
  if (!Array.isArray(newData) || newData.length === 0) return;
68
+ const {
69
+ rightLegendSpace = 0,
70
+ chartLegendGap = 0
71
+ } = show_legend ? this.getRightLegendLayout({
72
+ data: newData,
73
+ legendName: 'name',
74
+ theme
75
+ }) : {};
76
+ this.chartBoundingClientRect.rightLegendSpace = rightLegendSpace;
77
+ const plotWidth = Math.max(0, chartWidth - insertPadding * 2 - rightLegendSpace - chartLegendGap);
78
+ const radiusWidth = show_legend ? plotWidth : chartWidth;
72
79
 
73
80
  // Only the visible categories are laid out; the legend still shows every category.
74
81
  const visibleData = this.getVisibleLegendData(newData, 'name');
@@ -82,7 +89,8 @@ class Ring extends _chartComponent.default {
82
89
  // Ring and Arc
83
90
  const pie = d3.pie().sort(null).value(d => d.value);
84
91
  const arcs = pie(visibleData);
85
- const arc = d3.arc().innerRadius(Math.min(chartWidth, chartHeight) / 2 * 0.5).outerRadius(Math.min(chartWidth, chartHeight) / 2 * 0.7);
92
+ const radius = Math.min(radiusWidth, chartHeight) / 2;
93
+ const arc = d3.arc().innerRadius(radius * 0.5).outerRadius(radius * 0.7);
86
94
 
87
95
  // Draw Ring
88
96
  this.chart.append('g').attr('class', 'content-wrapper').selectAll().data(arcs).join('path').attr('stroke', 'white').attr('stroke-width', 2).attr('opacity', 1).attr('fill', d => color(d.data.name)).attr('d', arc).attr('data-groupName', d => d.data.name).call(g => {
@@ -93,7 +101,7 @@ class Ring extends _chartComponent.default {
93
101
  } = (_g$node$parentNode = g.node().parentNode) === null || _g$node$parentNode === void 0 ? void 0 : _g$node$parentNode.getBoundingClientRect();
94
102
  const left = width / 2 + insertPadding;
95
103
  const top = height / 2 + insertPadding;
96
- const offsetX = (chartWidth - (insertPadding + rightLegendSpace) - insertPadding - width) / 2;
104
+ const offsetX = (plotWidth - width) / 2;
97
105
  const offsetY = (chartHeight - insertPadding - insertPadding - height) / 2;
98
106
  d3.select(g.node().parentNode).attr('transform', `translate(${left + offsetX}, ${top + offsetY})`);
99
107
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sea-chart",
3
- "version": "2.0.58",
3
+ "version": "2.0.60",
4
4
  "main": "./dist/index.js",
5
5
  "dependencies": {
6
6
  "@dnd-kit/core": "^6.1.0",