sea-chart 2.0.44 → 2.0.46

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.
@@ -21,7 +21,7 @@
21
21
  max-width: 160px;
22
22
  white-space: nowrap;
23
23
  overflow: hidden;
24
- line-height: 14px;
24
+ line-height: 1.4;
25
25
  text-overflow: ellipsis;
26
26
  }
27
27
 
@@ -53,7 +53,7 @@
53
53
  min-width: 80px;
54
54
  white-space: nowrap;
55
55
  overflow: hidden;
56
- line-height: 12px;
56
+ line-height: 1.4;
57
57
  text-overflow: ellipsis;
58
58
  }
59
59
 
@@ -40,6 +40,8 @@ class AreaGroup extends ChartComponent {
40
40
  this.renderAxisLabel(this.props.chart, this.props.tables, this.container);
41
41
  };
42
42
  this.draw = data => {
43
+ const fullData = data;
44
+ data = this.getVisibleLegendData(data, 'group_name');
43
45
  const {
44
46
  chart,
45
47
  globalTheme,
@@ -75,7 +77,7 @@ class AreaGroup extends ChartComponent {
75
77
  marginTop
76
78
  } = this.chartBoundingClientRect;
77
79
  const useSingleSelectColumnColor = (columnGroupbyColumn === null || columnGroupbyColumn === void 0 ? void 0 : columnGroupbyColumn.type) === CellType.SINGLE_SELECT && color_theme === SUPPORT_SINGLE_SELECT_THEMES_OPTIONS.SINGLE_SELECT_COLUMN_COLORS;
78
- useSingleSelectColumnColor ? this.setSingleSelectColorMap(data) : this.setColorMap(data, chartColorTheme, 'group_name', columnGroupbyColumn, chart);
80
+ useSingleSelectColumnColor ? this.setSingleSelectColorMap(fullData) : this.setColorMap(fullData, chartColorTheme, 'group_name', columnGroupbyColumn, chart);
79
81
  const tooltipTitle = this.getTitle(tables, table_id, y_axis_summary_type, y_axis_column_key || y_axis_summary_column_key);
80
82
 
81
83
  // Y axis
@@ -198,7 +200,7 @@ class AreaGroup extends ChartComponent {
198
200
  legendName: 'group_name',
199
201
  theme,
200
202
  legendPosition: 'top-right',
201
- data,
203
+ data: fullData,
202
204
  groupColumn: this.props.columnGroupbyColumn,
203
205
  chart
204
206
  });
@@ -36,6 +36,8 @@ class BarCompare extends ChartComponent {
36
36
  this.renderAxisLabel(this.props.chart, this.props.tables, this.container);
37
37
  };
38
38
  this.draw = data => {
39
+ const fullData = data;
40
+ data = this.getVisibleLegendData(data, 'group_name');
39
41
  const {
40
42
  chart,
41
43
  globalTheme,
@@ -109,12 +111,12 @@ class BarCompare extends ChartComponent {
109
111
  const increaseData = this.getIncreaseData(data);
110
112
  this.drawIncreaseLine(increaseData);
111
113
  }
112
- this.setColorMap(data, chartColorTheme);
114
+ this.setColorMap(fullData, chartColorTheme);
113
115
  this.setLegend({
114
116
  legendName: 'group_name',
115
117
  theme,
116
118
  legendPosition: 'top-right',
117
- data
119
+ data: fullData
118
120
  });
119
121
  };
120
122
  this.showTooltip = (event, colorScale, isCircle) => {
@@ -113,6 +113,8 @@ class BarCustom extends ChartComponent {
113
113
  return allSeries;
114
114
  };
115
115
  this.draw = data => {
116
+ const fullData = data;
117
+ data = this.getVisibleLegendData(data, 'group_name');
116
118
  const {
117
119
  chart,
118
120
  globalTheme,
@@ -133,7 +135,7 @@ class BarCustom extends ChartComponent {
133
135
  insertPadding
134
136
  } = this.chartBoundingClientRect;
135
137
  const organizedData = this.organizeData(data);
136
- const color = d3.scaleOrdinal().domain(d3.group(data, d => d.group_name).keys()).range(BaseUtils.getCurrentTheme(chartColorTheme).colors).unknown('#ccc');
138
+ const color = d3.scaleOrdinal().domain(d3.group(fullData, d => d.group_name).keys()).range(BaseUtils.getCurrentTheme(chartColorTheme).colors).unknown('#ccc');
137
139
  const allSeries = this.getAllSeries(organizedData);
138
140
  const niceEnd = d3.nice(0, d3.max(allSeries, d => d[1]), 5)[1];
139
141
  const y = d3.scaleLinear().domain([0, niceEnd]).range([chartHeight - insertPadding, insertPadding]);
@@ -207,7 +209,7 @@ class BarCustom extends ChartComponent {
207
209
  legendName: 'group_name',
208
210
  theme,
209
211
  legendPosition: 'top-right',
210
- data,
212
+ data: fullData,
211
213
  colorScale: color
212
214
  });
213
215
  };
@@ -49,6 +49,8 @@ class BarGroup extends ChartComponent {
49
49
  isFunction(customRender) && customRender(this.chart);
50
50
  };
51
51
  this.draw = data => {
52
+ const fullData = data;
53
+ data = this.getVisibleLegendData(data, 'group_name');
52
54
  const {
53
55
  chart,
54
56
  globalTheme,
@@ -82,7 +84,7 @@ class BarGroup extends ChartComponent {
82
84
  const theme = CHART_THEME_COLOR[globalTheme];
83
85
  const column_groupby_column = this.getColumn(tables, table_id, column_groupby_column_key);
84
86
  const useSingleSelectColumnColor = (column_groupby_column === null || column_groupby_column === void 0 ? void 0 : column_groupby_column.type) === CellType.SINGLE_SELECT && color_theme === SUPPORT_SINGLE_SELECT_THEMES_OPTIONS.SINGLE_SELECT_COLUMN_COLORS;
85
- useSingleSelectColumnColor ? this.setSingleSelectColorMap(data) : this.setColorMap(data, chartColorTheme, 'group_name', columnGroupbyColumn, chart); // use single select column color
87
+ useSingleSelectColumnColor ? this.setSingleSelectColorMap(fullData) : this.setColorMap(fullData, chartColorTheme, 'group_name', columnGroupbyColumn, chart); // use single select column color
86
88
 
87
89
  const y = d3.scaleLinear().domain(y_axis_auto_range ? [0, d3.max(data, d => d.value)] : [y_axis_min, y_axis_max]).range([chartHeight - insertPadding, insertPadding + marginTop]);
88
90
 
@@ -155,7 +157,7 @@ class BarGroup extends ChartComponent {
155
157
  legendName: 'group_name',
156
158
  theme,
157
159
  legendPosition: 'top-right',
158
- data,
160
+ data: fullData,
159
161
  groupColumn: this.props.columnGroupbyColumn,
160
162
  chart
161
163
  });
@@ -50,6 +50,8 @@ class BarStack extends ChartComponent {
50
50
  isFunction(customRender) && customRender(this.chart);
51
51
  };
52
52
  this.draw = data => {
53
+ const fullData = data;
54
+ data = this.getVisibleLegendData(data, 'group_name');
53
55
  const {
54
56
  chart,
55
57
  globalTheme,
@@ -78,7 +80,7 @@ class BarStack extends ChartComponent {
78
80
  const column_groupby_column = this.getColumn(tables, table_id, column_groupby_column_key);
79
81
  const useSingleSelectColumnColor = (column_groupby_column === null || column_groupby_column === void 0 ? void 0 : column_groupby_column.type) === CellType.SINGLE_SELECT && color_theme === SUPPORT_SINGLE_SELECT_THEMES_OPTIONS.SINGLE_SELECT_COLUMN_COLORS;
80
82
  // use single select column color
81
- useSingleSelectColumnColor ? this.setSingleSelectColorMap(data) : this.setColorMap(data, chartColorTheme, 'group_name', columnGroupbyColumn, chart);
83
+ useSingleSelectColumnColor ? this.setSingleSelectColorMap(fullData) : this.setColorMap(fullData, chartColorTheme, 'group_name', columnGroupbyColumn, chart);
82
84
  const {
83
85
  width: chartWidth,
84
86
  height: chartHeight,
@@ -173,7 +175,7 @@ class BarStack extends ChartComponent {
173
175
  legendName: 'group_name',
174
176
  theme,
175
177
  legendPosition: 'top-right',
176
- data,
178
+ data: fullData,
177
179
  groupColumn: this.props.columnGroupbyColumn,
178
180
  chart
179
181
  });
@@ -13,6 +13,38 @@ export default class ChartComponent extends Component {
13
13
  var _this;
14
14
  super(props);
15
15
  _this = this;
16
+ // Filter out the data whose legend group has been toggled off, so the chart
17
+ // body can be re-laid out without the hidden categories. The full data set is
18
+ // still passed to setLegend so every legend item (including hidden ones) shows.
19
+ this.getVisibleLegendData = (data, legendName) => {
20
+ if (!Array.isArray(data) || !this.hiddenLegendGroups || this.hiddenLegendGroups.size === 0) {
21
+ return data;
22
+ }
23
+ const filtered = data.filter(d => !this.hiddenLegendGroups.has(String(d === null || d === void 0 ? void 0 : d[legendName])));
24
+ // Never hide everything, keep the original data as a fallback.
25
+ return filtered.length ? filtered : data;
26
+ };
27
+ this.handleLegendClick = groupName => {
28
+ if (!this.hiddenLegendGroups) this.hiddenLegendGroups = new Set();
29
+ const key = String(groupName);
30
+ const isHidden = this.hiddenLegendGroups.has(key);
31
+ if (isHidden) {
32
+ this.hiddenLegendGroups.delete(key);
33
+ } else {
34
+ // Keep at least one visible group so the chart is never fully empty.
35
+ const total = this.legendGroupNames ? this.legendGroupNames.size : 0;
36
+ const visibleCount = total - this.hiddenLegendGroups.size;
37
+ if (visibleCount <= 1) return;
38
+ this.hiddenLegendGroups.add(key);
39
+ }
40
+ this.redrawChart();
41
+ };
42
+ this.redrawChart = () => {
43
+ if (!this.createChart || !this.drawChart) return;
44
+ this.destroyChart();
45
+ this.createChart();
46
+ this.drawChart();
47
+ };
16
48
  this.initLabelStroke = theme => {
17
49
  this.globalTheme = theme || THEME_NAME_MAP.LIGHT;
18
50
  this.labelStroke = theme === THEME_NAME_MAP.DARK ? {} : {
@@ -546,8 +578,13 @@ export default class ChartComponent extends Component {
546
578
  legendItemTextPaddingTop: 13,
547
579
  legendItemMargin: 20,
548
580
  legendRecTextGap: 8,
549
- legendPageNavWrapperWidth: 100,
550
- legendPageNavWrapperHeight: 18,
581
+ // Space reserved for the page navigator. Start at 0 and only reserve it when
582
+ // pagination is actually needed, so a legend that fits is not pushed onto a
583
+ // hidden page (which made the legend look incomplete/clipped).
584
+ legendPageNavWrapperWidth: 0,
585
+ legendPageNavWrapperHeight: 0,
586
+ legendPageNavMaxWidth: 100,
587
+ legendPageNavMaxHeight: 18,
551
588
  legendPosition,
552
589
  legendName,
553
590
  theme
@@ -557,6 +594,9 @@ export default class ChartComponent extends Component {
557
594
  const clonedData = cloneDeep(data);
558
595
  clonedData.forEach(item => item[legendName] = String(item[legendName]));
559
596
  const legendData = BaseUtils.sortDataByGroupName(clonedData, legendName, groupColumn, chart);
597
+
598
+ // Record every legend group name so legend click can keep at least one visible.
599
+ this.legendGroupNames = new Set(legendData.map(item => String(item[legendName])));
560
600
  const {
561
601
  width: chartWidth,
562
602
  height: chartHeight,
@@ -564,7 +604,14 @@ export default class ChartComponent extends Component {
564
604
  rightLegendSpace,
565
605
  bottomLegendSpace
566
606
  } = this.chartBoundingClientRect;
567
- const groupsData = this.getLegendDataGroups(legendData);
607
+ let groupsData = this.getLegendDataGroups(legendData);
608
+ // If more than one page is required, reserve room for the page navigator and
609
+ // re-paginate against the reduced space.
610
+ if (groupsData.length > 1) {
611
+ this.legendConfig.legendPageNavWrapperWidth = this.legendConfig.legendPageNavMaxWidth;
612
+ this.legendConfig.legendPageNavWrapperHeight = this.legendConfig.legendPageNavMaxHeight;
613
+ groupsData = this.getLegendDataGroups(legendData);
614
+ }
568
615
  if (groupsData.length === 0) return;
569
616
  const legendWrapper = this.chart.append('g').attr('class', 'legend-wrapper');
570
617
 
@@ -727,6 +774,7 @@ export default class ChartComponent extends Component {
727
774
  translateY = prevTranslateY + height + legendItemMargin;
728
775
  }
729
776
  d3.select(item).attr('transform', `translate(${start},${translateY})`).attr('data-translateY', translateY);
777
+ this.bindLegendItemInteraction(item);
730
778
  });
731
779
  } else {
732
780
  // update g translateX
@@ -741,6 +789,7 @@ export default class ChartComponent extends Component {
741
789
  translateX = prevTranslateX + width + legendItemMargin;
742
790
  }
743
791
  d3.select(item).attr('transform', `translate(${translateX},0)`).attr('data-translateX', translateX);
792
+ this.bindLegendItemInteraction(item);
744
793
 
745
794
  // legend items add offset
746
795
  if (legendPosition === 'top-right') {
@@ -888,9 +937,16 @@ export default class ChartComponent extends Component {
888
937
  legendItems.forEach(legendItem => {
889
938
  const curTranslateX = Number(legendItem.getAttribute('data-translateX')) + offset;
890
939
  d3.select(legendItem).attr('transform', `translate(${curTranslateX}, 0)`).attr('data-translateX', curTranslateX);
891
- d3.select(legendItem).attr('opacity', 1);
940
+ const isHidden = this.hiddenLegendGroups && this.hiddenLegendGroups.has(String(legendItem.getAttribute('data-groupName')));
941
+ d3.select(legendItem).attr('opacity', isHidden ? 0.35 : 1);
892
942
  });
893
943
  };
944
+ this.bindLegendItemInteraction = item => {
945
+ if (!item) return;
946
+ const groupName = item.getAttribute('data-groupName');
947
+ const isHidden = this.hiddenLegendGroups && this.hiddenLegendGroups.has(String(groupName));
948
+ d3.select(item).style('cursor', 'pointer').attr('opacity', isHidden ? 0.35 : 1).on('click', () => this.handleLegendClick(groupName));
949
+ };
894
950
  this.sortLegend = (result, groupColumn, legendName) => {
895
951
  result.forEach(item => {
896
952
  const option = groupColumn.data.options.find(option => option.name === item[legendName]);
@@ -1698,6 +1754,7 @@ export default class ChartComponent extends Component {
1698
1754
  this.enterTransitionName = 'enter';
1699
1755
  this._defs = null;
1700
1756
  this._clipMaskByRect = new Map();
1757
+ this.hiddenLegendGroups = new Set();
1701
1758
  }
1702
1759
  componentDidMount() {
1703
1760
  window.addEventListener('resize', this.handleResize);
@@ -93,6 +93,16 @@ class Combination extends ChartComponent {
93
93
  showRightValue = true;
94
94
  }
95
95
  this.setCombinationColorMap(data, leftSummaryColumn, rightSummaryColumn);
96
+
97
+ // Legend toggle: keep the shared x scale on the full data, but re-lay out the
98
+ // left bars (and hide the right line) for the categories toggled off in the legend.
99
+ const rightHidden = this.hiddenLegendGroups && this.hiddenLegendGroups.has(String(rightSummaryColumn === null || rightSummaryColumn === void 0 ? void 0 : rightSummaryColumn.name) + ' ');
100
+ let dataLeft = data;
101
+ if (y_axis_left_group_by_multiple_numeric_column) {
102
+ dataLeft = this.getVisibleLegendData(data, 'group_name');
103
+ } else if (this.hiddenLegendGroups && this.hiddenLegendGroups.has(String(leftSummaryColumn === null || leftSummaryColumn === void 0 ? void 0 : leftSummaryColumn.name))) {
104
+ dataLeft = [];
105
+ }
96
106
  const rightNiceEnd = d3.nice(0, d3.max(data, d => d.value_right) || 0, 5)[1];
97
107
  const rightY = d3.scaleLinear().domain(y_axis_auto_range_right ? [d3.min(data, d => d.value_right), rightNiceEnd] : [y_axis_min_right, y_axis_max_right]).range([chartHeight - insertPadding, insertPadding + marginTop]);
98
108
 
@@ -103,13 +113,13 @@ class Combination extends ChartComponent {
103
113
  g.selectAll('text').attr('fill', theme.textColor);
104
114
  });
105
115
  const rightAxisOffset = this.getRightAxisOffset(rightAxisWrapper);
106
- const leftNiceEnd = d3.nice(0, d3.max(data, d => d.value_left), 5)[1];
116
+ const leftNiceEnd = d3.nice(0, d3.max(dataLeft, d => d.value_left) || 0, 5)[1];
107
117
  const leftY = d3.scaleLinear().domain(y_axis_auto_range_left ? [0, leftNiceEnd] : [y_axis_min_left, y_axis_max_left]).range([chartHeight - insertPadding, insertPadding + marginTop]);
108
118
 
109
119
  // Y axis (left)
110
120
  this.chart.append('g').attr('class', 'y-axis-wrapper-left').attr('transform', `translate(${insertPadding},0)`).call(d3.axisLeft(leftY).tickSizeInner(0).ticks(5).tickFormat(d => BaseUtils.getSummaryValueDisplayString(leftSummaryColumn, d, y_axis_left_summary_method))).call(g => this.drawYaxis(g, theme, rightAxisOffset));
111
121
  const fx = d3.scaleBand().domain(new Set(data.map(d => d.name))).range([insertPadding + this.horizontalOverflowOffset, chartWidth - insertPadding - rightAxisOffset]).paddingInner(0.5).paddingOuter(0.1);
112
- const x = d3.scaleBand().domain(y_axis_left_group_by_multiple_numeric_column ? new Set(data.map(d => d.group_name)) : new Set([data[0]])).range([0, fx.bandwidth()]).paddingInner(y_axis_left_group_by_multiple_numeric_column ? 0.2 : 0).paddingOuter(0);
122
+ const x = d3.scaleBand().domain(y_axis_left_group_by_multiple_numeric_column ? new Set(dataLeft.map(d => d.group_name)) : new Set([data[0]])).range([0, fx.bandwidth()]).paddingInner(y_axis_left_group_by_multiple_numeric_column ? 0.2 : 0).paddingOuter(0);
113
123
 
114
124
  // X axis
115
125
  this.chart.append('g').attr('class', 'x-axis-wrapper').attr('transform', `translate(0,${chartHeight - insertPadding})`).call(d3.axisBottom(fx).tickSizeOuter(0).tickSizeInner(5)).call(g => {
@@ -121,7 +131,7 @@ class Combination extends ChartComponent {
121
131
  });
122
132
 
123
133
  // Rect group
124
- this.chart.append('g').attr('class', 'content-wrapper').selectAll().data(d3.group(data, d => d.name)).join('g').attr('transform', _ref => {
134
+ this.chart.append('g').attr('class', 'content-wrapper').selectAll().data(d3.group(dataLeft, d => d.name)).join('g').attr('transform', _ref => {
125
135
  let [name, dum] = _ref;
126
136
  return `translate(${fx(name)},0)`;
127
137
  })
@@ -182,7 +192,9 @@ class Combination extends ChartComponent {
182
192
  });
183
193
 
184
194
  // Line group
185
- this.drawRightContent(data, fx, rightY, showRightValue, rightSummaryColumn, rightTitle);
195
+ if (!rightHidden) {
196
+ this.drawRightContent(data, fx, rightY, showRightValue, rightSummaryColumn, rightTitle);
197
+ }
186
198
  if (display_goal_line && goal_label && goal_value) {
187
199
  this.setDispalyGoalLine(goal_label, goal_value, insertPadding, rightY);
188
200
  }
@@ -63,7 +63,9 @@ class Completeness extends ChartComponent {
63
63
  item.groupby = item.groupby.join(', ');
64
64
  }
65
65
  });
66
- this.setColorMap(data, chartColorTheme, 'groupby', columnGroupbyColumn, chart);
66
+ const fullData = data;
67
+ data = this.getVisibleLegendData(data, 'groupby');
68
+ this.setColorMap(fullData, chartColorTheme, 'groupby', columnGroupbyColumn, chart);
67
69
  const newSeries = this.getGroupSeries(data, columnGroupbyColumn, chart);
68
70
 
69
71
  // Y axis
@@ -191,7 +193,7 @@ class Completeness extends ChartComponent {
191
193
  legendName: 'groupby',
192
194
  theme,
193
195
  legendPosition: 'top-right',
194
- data,
196
+ data: fullData,
195
197
  groupColumn: columnGroupbyColumn,
196
198
  chart
197
199
  });
@@ -32,6 +32,8 @@ class Completeness extends ChartComponent {
32
32
  this.draw(data);
33
33
  };
34
34
  this.draw = data => {
35
+ const fullData = data;
36
+ data = this.getVisibleLegendData(data, 'group_name');
35
37
  const {
36
38
  chart,
37
39
  globalTheme,
@@ -144,7 +146,7 @@ class Completeness extends ChartComponent {
144
146
  legendName: 'group_name',
145
147
  theme,
146
148
  legendPosition: 'top-right',
147
- data,
149
+ data: fullData,
148
150
  colorScale: group_name => group_name === 'rest' ? '#bdbdbd' : colors[0]
149
151
  });
150
152
  };
@@ -104,25 +104,46 @@ class Funnel extends ChartComponent {
104
104
  const theme = CHART_THEME_COLOR[globalTheme];
105
105
  const isInside = funnel_label_position === FUNNEL_LABEL_POSITIONS.INSIDE;
106
106
  const title = this.getTitle(tables, table_id, y_axis_summary_type, y_axis_column_key || y_axis_summary_column_key);
107
+
108
+ // Only the visible stages are laid out; the legend still shows every stage.
109
+ const fullData = data;
110
+ data = this.getVisibleLegendData(data, 'name');
107
111
  const nameDomain = new Set(data.map(item => item.name));
108
112
 
109
- // Color scale
110
- const colorScale = d3.scaleOrdinal().domain(nameDomain).range(['#0050B3', '#1890FF', '#40A9FF', '#69C0FF', '#BAE7FF']);
113
+ // Color scale keeps the full domain so stage colors stay stable when toggling.
114
+ const colorScale = d3.scaleOrdinal().domain(new Set(fullData.map(item => item.name))).range(['#0050B3', '#1890FF', '#40A9FF', '#69C0FF', '#BAE7FF']);
111
115
 
112
116
  // Y scale
113
117
  const y = d3.scaleBand().domain(nameDomain).range([insertPadding, chartHeight - insertPadding]).paddingInner(0).paddingOuter(0);
114
118
 
119
+ // Reserve horizontal space on both sides for outside labels, otherwise the
120
+ // widest (top) layer spans nearly the full width and its label is clipped off
121
+ // the left edge.
122
+ let labelSpace = 0;
123
+ if (funnel_show_labels && !isInside) {
124
+ const measureWrapper = this.chart.append('g').attr('opacity', 0);
125
+ data.forEach(_ref => {
126
+ let {
127
+ name
128
+ } = _ref;
129
+ measureWrapper.append('text').attr('font-size', funnel_label_font_size).text(name);
130
+ });
131
+ const maxNameWidth = d3.max(measureWrapper.selectAll('text').nodes(), node => node.getBoundingClientRect().width) || 0;
132
+ measureWrapper.remove();
133
+ labelSpace = Math.min(maxNameWidth + 10, (chartWidth - insertPadding * 2) * 0.35);
134
+ }
135
+
115
136
  // X scale
116
- const x = d3.scaleLinear().domain([0, d3.max(data, d => d.value)]).range([insertPadding, chartWidth - insertPadding]);
137
+ const x = d3.scaleLinear().domain([0, d3.max(data, d => d.value)]).range([insertPadding + labelSpace, chartWidth - insertPadding - labelSpace]);
117
138
 
118
139
  // Content
119
140
  const contentWrapper = this.chart.append('g').attr('class', 'content-wrapper');
120
- const allWidth = chartWidth - insertPadding * 2;
121
- data.forEach((_ref, index) => {
141
+ const allWidth = chartWidth - insertPadding * 2 - labelSpace * 2;
142
+ data.forEach((_ref2, index) => {
122
143
  let {
123
144
  name: curName,
124
145
  value: curValue
125
- } = _ref;
146
+ } = _ref2;
126
147
  const curOffsetX = (allWidth - (x(curValue) - x(0))) / 2;
127
148
  let points3X = x(curValue) + curOffsetX;
128
149
  let points3Y = y(curName) + y.bandwidth();
@@ -163,7 +184,7 @@ class Funnel extends ChartComponent {
163
184
  width,
164
185
  height
165
186
  } = g.node().getBoundingClientRect();
166
- const x = isInside ? left + gWidth / 2 - width / 2 : left - width - 5; // add offsetX is 5
187
+ const x = isInside ? left + gWidth / 2 - width / 2 : Math.max(left - width - 5, 2); // add offsetX is 5
167
188
  const y = isInside ? top + height + 10 : top + gHeight / 2 + height / 2; // add offsetY is 10
168
189
  g.attr('x', x);
169
190
  g.attr('y', y);
@@ -210,7 +231,7 @@ class Funnel extends ChartComponent {
210
231
  legendName: 'name',
211
232
  theme,
212
233
  legendPosition: 'top-right',
213
- data,
234
+ data: fullData,
214
235
  chart,
215
236
  colorScale
216
237
  });
@@ -97,8 +97,10 @@ class HorizontalBarGroup extends ChartComponent {
97
97
  };
98
98
  });
99
99
  }
100
+ const fullData = data;
101
+ data = this.getVisibleLegendData(data, 'group_name');
100
102
  const useSingleSelectColumnColor = (groupByColumn === null || groupByColumn === void 0 ? void 0 : groupByColumn.type) === CellType.SINGLE_SELECT && color_theme === SUPPORT_SINGLE_SELECT_THEMES_OPTIONS.SINGLE_SELECT_COLUMN_COLORS;
101
- useSingleSelectColumnColor ? this.setSingleSelectColorMap(data) : this.setColorMap(data, chartColorTheme);
103
+ useSingleSelectColumnColor ? this.setSingleSelectColorMap(fullData) : this.setColorMap(fullData, chartColorTheme);
102
104
  const fy = d3.scaleBand().domain(new Set(data.map(d => d.name))).range([chartHeight - insertPadding, insertPadding]).paddingInner(0.3).paddingOuter(0.1);
103
105
  const sortedData = BaseUtils.sortDataByGroupName(cloneDeep(data), 'group_name', columnGroupbyColumn, chart);
104
106
  const y = d3.scaleBand().domain(new Set(sortedData.map(d => d.group_name))).range([0, fy.bandwidth()]).paddingInner(0).paddingOuter(0);
@@ -185,7 +187,7 @@ class HorizontalBarGroup extends ChartComponent {
185
187
  legendName: 'group_name',
186
188
  theme,
187
189
  legendPosition: 'top-right',
188
- data,
190
+ data: fullData,
189
191
  groupColumn: this.props.columnGroupbyColumn,
190
192
  chart
191
193
  });
@@ -49,6 +49,8 @@ class HorizontalBarStack extends ChartComponent {
49
49
  this.renderHorizontalLabel(this.props.chart, this.props.tables, this.container);
50
50
  };
51
51
  this.draw = data => {
52
+ const fullData = data;
53
+ data = this.getVisibleLegendData(data, 'group_name');
52
54
  const {
53
55
  chart,
54
56
  globalTheme,
@@ -76,7 +78,7 @@ class HorizontalBarStack extends ChartComponent {
76
78
  } = this.chartBoundingClientRect;
77
79
  const groupByColumn = this.getColumn(tables, table_id, column_groupby_column_key);
78
80
  const useSingleSelectColumnColor = (groupByColumn === null || groupByColumn === void 0 ? void 0 : groupByColumn.type) === CellType.SINGLE_SELECT && color_theme === SUPPORT_SINGLE_SELECT_THEMES_OPTIONS.SINGLE_SELECT_COLUMN_COLORS;
79
- useSingleSelectColumnColor ? this.setSingleSelectColorMap(data) : this.setColorMap(data, chartColorTheme, 'group_name', columnGroupbyColumn, chart);
81
+ useSingleSelectColumnColor ? this.setSingleSelectColorMap(fullData) : this.setColorMap(fullData, chartColorTheme, 'group_name', columnGroupbyColumn, chart);
80
82
  const sortedData = BaseUtils.sortDataByGroupName(cloneDeep(data), 'group_name', columnGroupbyColumn, chart);
81
83
  const series = d3.stack().keys(d3.union(sortedData.map(d => d.group_name))).value((_ref, key) => {
82
84
  var _group$get;
@@ -165,7 +167,7 @@ class HorizontalBarStack extends ChartComponent {
165
167
  legendName: 'group_name',
166
168
  theme,
167
169
  legendPosition: 'top-right',
168
- data,
170
+ data: fullData,
169
171
  groupColumn: this.props.columnGroupbyColumn,
170
172
  chart
171
173
  });
@@ -121,6 +121,8 @@ class LineGroup extends ChartComponent {
121
121
  };
122
122
  };
123
123
  this.draw = data => {
124
+ const fullData = data;
125
+ data = this.getVisibleLegendData(data, 'group_name');
124
126
  const {
125
127
  chart,
126
128
  globalTheme,
@@ -151,7 +153,7 @@ class LineGroup extends ChartComponent {
151
153
  marginTop
152
154
  } = this.chartBoundingClientRect;
153
155
  const useSingleSelectColumnColor = (columnGroupbyColumn === null || columnGroupbyColumn === void 0 ? void 0 : columnGroupbyColumn.type) === CellType.SINGLE_SELECT && color_theme === SUPPORT_SINGLE_SELECT_THEMES_OPTIONS.SINGLE_SELECT_COLUMN_COLORS;
154
- useSingleSelectColumnColor ? this.setSingleSelectColorMap(data) : this.setColorMap(data, chartColorTheme, 'group_name', columnGroupbyColumn, chart);
156
+ useSingleSelectColumnColor ? this.setSingleSelectColorMap(fullData) : this.setColorMap(fullData, chartColorTheme, 'group_name', columnGroupbyColumn, chart);
155
157
 
156
158
  // Y axis
157
159
  const niceEnd = d3.nice(0, d3.max(data, d => d.value), 5)[1];
@@ -265,7 +267,7 @@ class LineGroup extends ChartComponent {
265
267
  legendName: 'group_name',
266
268
  theme,
267
269
  legendPosition: 'top-right',
268
- data,
270
+ data: fullData,
269
271
  groupColumn: this.props.columnGroupbyColumn,
270
272
  chart
271
273
  });
@@ -84,6 +84,8 @@ class Mirror extends ChartComponent {
84
84
  data,
85
85
  colorSet
86
86
  } = _ref;
87
+ const fullData = data;
88
+ data = this.getVisibleLegendData(data, 'group_name');
87
89
  const {
88
90
  chart,
89
91
  tables
@@ -236,12 +238,12 @@ class Mirror extends ChartComponent {
236
238
  legendName: 'group_name',
237
239
  theme: themeColors,
238
240
  legendPosition: 'top-left',
239
- data,
241
+ data: fullData,
240
242
  groupColumn: this.props.columnGroupbyColumn,
241
243
  chart,
242
244
  colorScale: key => {
243
- const curD = data.find(item => item.group_name === key);
244
- return curD.color || '';
245
+ const curD = fullData.find(item => item.group_name === key);
246
+ return (curD === null || curD === void 0 ? void 0 : curD.color) || '';
245
247
  }
246
248
  });
247
249
  };
@@ -61,6 +61,9 @@ class Pie extends ChartComponent {
61
61
  } = BaseUtils.formatPieChartData(data, chart, tables, currentTheme, useSingleSelectColumnColor);
62
62
  if (!Array.isArray(newData) || newData.length === 0) return;
63
63
 
64
+ // Only the visible categories are laid out; the legend still shows every category.
65
+ const visibleData = this.getVisibleLegendData(newData, 'name');
66
+
64
67
  // Color
65
68
  const colorDomain = new Set(newData.map(d => d.name));
66
69
  const colorRange = Array.from(colorDomain).map(name => colorMap[name === null || name === void 0 ? void 0 : name.trim()]);
@@ -68,7 +71,7 @@ class Pie extends ChartComponent {
68
71
 
69
72
  // Pie and Arc
70
73
  const pie = d3.pie().sort(null).value(d => d.value);
71
- const arcs = pie(newData);
74
+ const arcs = pie(visibleData);
72
75
  const arc = d3.arc().innerRadius(0).outerRadius(Math.min(chartWidth, chartHeight) / 2 * 0.7);
73
76
 
74
77
  // Draw Pie
@@ -58,10 +58,14 @@ class Ring extends ChartComponent {
58
58
  const {
59
59
  data: newData,
60
60
  colorMap,
61
- total
61
+ total: fullTotal
62
62
  } = BaseUtils.formatPieChartData(data, chart, tables, currentTheme, useSingleSelectColumnColor);
63
63
  if (!Array.isArray(newData) || newData.length === 0) return;
64
64
 
65
+ // Only the visible categories are laid out; the legend still shows every category.
66
+ const visibleData = this.getVisibleLegendData(newData, 'name');
67
+ const total = visibleData === newData ? fullTotal : d3.sum(visibleData, d => Number(d.value) || 0);
68
+
65
69
  // Color
66
70
  const colorDomain = new Set(newData.map(d => d.name));
67
71
  const colorRange = Array.from(colorDomain).map(name => colorMap[name === null || name === void 0 ? void 0 : name.trim()]);
@@ -69,7 +73,7 @@ class Ring extends ChartComponent {
69
73
 
70
74
  // Ring and Arc
71
75
  const pie = d3.pie().sort(null).value(d => d.value);
72
- const arcs = pie(newData);
76
+ const arcs = pie(visibleData);
73
77
  const arc = d3.arc().innerRadius(Math.min(chartWidth, chartHeight) / 2 * 0.5).outerRadius(Math.min(chartWidth, chartHeight) / 2 * 0.7);
74
78
 
75
79
  // Draw Ring
@@ -167,6 +167,8 @@ class Scatter extends ChartComponent {
167
167
  }
168
168
  };
169
169
  this.draw = data => {
170
+ const fullData = data;
171
+ data = this.getVisibleLegendData(data, 'groupby');
170
172
  const {
171
173
  chart,
172
174
  globalTheme,
@@ -191,7 +193,7 @@ class Scatter extends ChartComponent {
191
193
  marginTop,
192
194
  bottomLegendSpace
193
195
  } = this.chartBoundingClientRect;
194
- const colorMap = this.getFillColor(data);
196
+ const colorMap = this.getFillColor(fullData);
195
197
  const selectedTable = getTableById(tables, table_id);
196
198
  const selectedXAxisColumn = getTableColumnByKey(selectedTable, x_axis_column_key);
197
199
  const selectedYAxisColumn = getTableColumnByKey(selectedTable, y_axis_column_key);
@@ -260,7 +262,7 @@ class Scatter extends ChartComponent {
260
262
  legendName: 'groupby',
261
263
  theme,
262
264
  legendPosition: 'top-right',
263
- data,
265
+ data: fullData,
264
266
  groupColumn: this.props.columnGroupbyColumn,
265
267
  chart,
266
268
  colorScale: key => colorMap[key]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sea-chart",
3
- "version": "2.0.44",
3
+ "version": "2.0.46",
4
4
  "main": "./dist/index.js",
5
5
  "dependencies": {
6
6
  "@dnd-kit/core": "^6.1.0",