sea-chart 2.0.13 → 2.0.15

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.
@@ -69,8 +69,7 @@ const TypesDialog = _ref => {
69
69
  }, [onChange, selectedType, onToggle]);
70
70
  const handleFilterTypes = (0, _react.useCallback)(() => {
71
71
  if (hideTypeToggle) {
72
- const newChartTypes = _constants.CHART_TYPES.filter(item => ['Histogram', 'Bar_chart'].includes(item.name));
73
- newChartTypes[1].children = newChartTypes[1].children.slice(0, 4);
72
+ const newChartTypes = _constants.CHART_TYPES.filter(item => ['Histogram', 'Bar_chart', 'Line_chart'].includes(item.name));
74
73
  return newChartTypes;
75
74
  }
76
75
  return _constants.CHART_TYPES;
@@ -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,
@@ -876,7 +877,8 @@ class ChartComponent extends _react.Component {
876
877
  }
877
878
  return [[cx, cy - height / 2], [cx - size / 2, cy + height / 2], [cx + size / 2, cy + height / 2]];
878
879
  };
879
- this.setColorMap = (data, chartColorTheme) => {
880
+ this.setColorMap = function (data, chartColorTheme) {
881
+ let groupName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'group_name';
880
882
  let currentIdx = 0;
881
883
  const defaultColors = _constants.CHART_STYLE_COLORS;
882
884
  let colors = defaultColors;
@@ -884,12 +886,12 @@ class ChartComponent extends _react.Component {
884
886
  colors = _utils.BaseUtils.getCurrentTheme(chartColorTheme).colors;
885
887
  }
886
888
  const colorMap = data.reduce((acc, cur) => {
887
- if (cur.group_name && !acc[cur.group_name]) {
888
- acc[cur.group_name] = colors[currentIdx++ % colors.length];
889
+ if (cur[groupName] && !acc[cur[groupName]]) {
890
+ acc[cur[groupName]] = colors[currentIdx++ % colors.length];
889
891
  }
890
892
  return acc;
891
893
  }, {});
892
- this.colorMap = colorMap;
894
+ _this.colorMap = colorMap;
893
895
  };
894
896
  this.setSingleSelectColorMap = data => {
895
897
  const colorMap = {};
@@ -1250,6 +1252,7 @@ class ChartComponent extends _react.Component {
1250
1252
  } = this.chartBoundingClientRect;
1251
1253
  const viewBox = this.chart.node().getAttribute('viewBox').split(',');
1252
1254
  if (axis === 'yAxis') {
1255
+ let isRoateText = false;
1253
1256
  let allHeight = 0;
1254
1257
  // Can't fit tilted text, Italic text
1255
1258
  for (let tick of allTicks) {
@@ -1265,6 +1268,7 @@ class ChartComponent extends _react.Component {
1265
1268
  d3.select(tick).select('text').attr('transform', 'rotate(30)').style('text-anchor', 'end').attr('dy', '1em').attr('dx', '-0.5em');
1266
1269
  }
1267
1270
  });
1271
+ isRoateText = true;
1268
1272
  break;
1269
1273
  }
1270
1274
  }
@@ -1273,7 +1277,7 @@ class ChartComponent extends _react.Component {
1273
1277
  const {
1274
1278
  width
1275
1279
  } = g.node().getBoundingClientRect();
1276
- if (width > insertPadding) {
1280
+ if (isRoateText && width > insertPadding) {
1277
1281
  const viewWidth = viewBox[viewBox.length - 2];
1278
1282
  viewBox[0] = "-".concat(width - insertPadding);
1279
1283
  viewBox[viewBox.length - 2] = "".concat(Number(viewWidth) + (width - insertPadding));
@@ -1315,6 +1319,26 @@ class ChartComponent extends _react.Component {
1315
1319
  }
1316
1320
  }
1317
1321
  };
1322
+ this.ticksAddName = g => {
1323
+ if (g.selectAll('.tick')) {
1324
+ const ticks = g.selectAll('.tick').nodes();
1325
+ ticks.forEach(tick => {
1326
+ var _d3$select$select;
1327
+ const text = (_d3$select$select = d3.select(tick).select('text')) === null || _d3$select$select === void 0 ? void 0 : _d3$select$select.node();
1328
+ d3.select(tick).select('line').attr('data-name', text.innerHTML);
1329
+ });
1330
+ }
1331
+ };
1332
+ this.getMinDistanceItem = (offsetX, allData) => {
1333
+ // allData = [{x: number}]
1334
+ const newAllData = allData.filter(item => Object.keys(item).length !== 0);
1335
+ newAllData.forEach(item => {
1336
+ item['distance'] = Math.abs(item.x - offsetX);
1337
+ });
1338
+ const minIndex = d3.minIndex(newAllData, d => d.distance);
1339
+ const minItem = newAllData[minIndex];
1340
+ return minItem;
1341
+ };
1318
1342
  this.initLabelStroke(props === null || props === void 0 ? void 0 : props.globalTheme);
1319
1343
  this.chartBoundingClientRect = {};
1320
1344
  }
@@ -0,0 +1,397 @@
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 _react = _interopRequireDefault(require("react"));
10
+ var _propTypes = _interopRequireDefault(require("prop-types"));
11
+ var _lodashEs = require("lodash-es");
12
+ var d3 = _interopRequireWildcard(require("d3"));
13
+ var _classnames = _interopRequireDefault(require("classnames"));
14
+ var _constants = require("../../constants");
15
+ var _utils = require("../../utils");
16
+ var _intl = _interopRequireDefault(require("../../intl"));
17
+ var _tooltip = _interopRequireDefault(require("../../components/tooltip"));
18
+ var _chartComponent = _interopRequireDefault(require("./chart-component"));
19
+ class Completeness 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
+ show_percentage
33
+ } = chart.config;
34
+ const initConfig = {
35
+ insertPadding: 30,
36
+ borderRadius: 0.2,
37
+ marginRight: show_percentage ? 35 : 0
38
+ };
39
+ this.initChart(this.container, chart === null || chart === void 0 ? void 0 : chart.id, initConfig);
40
+ };
41
+ this.drawChart = () => {
42
+ let {
43
+ result: data
44
+ } = this.props;
45
+ data = _utils.BaseUtils.formatEmptyName(data, '', _intl.default.get('Empty'));
46
+ if (!Array.isArray(data)) return;
47
+ this.draw(data);
48
+ };
49
+ this.draw = data => {
50
+ const {
51
+ chart,
52
+ globalTheme,
53
+ chartColorTheme
54
+ } = this.props;
55
+ const theme = _constants.CHART_THEME_COLOR[globalTheme];
56
+ const {
57
+ y_axis_auto_range,
58
+ y_axis_min,
59
+ y_axis_max,
60
+ show_percentage,
61
+ label_font_size,
62
+ column_groupby_column_key
63
+ } = chart.config;
64
+ const {
65
+ width: chartWidth,
66
+ height: chartHeight,
67
+ insertPadding,
68
+ marginRight
69
+ } = this.chartBoundingClientRect;
70
+ this.markLastForCompleteness(data);
71
+ const colors = _utils.BaseUtils.getCurrentTheme(chartColorTheme).colors;
72
+ this.setColorMap(data, chartColorTheme, 'groupby');
73
+ const newSeries = this.getGroupSeries(data);
74
+
75
+ // Y axis
76
+ const fy = d3.scaleBand().domain(newSeries.map(item => item[0])).range([chartHeight - insertPadding, insertPadding]).paddingInner(0.1).paddingOuter(0.1);
77
+ const y = d3.scaleBand().domain(new Set(data.map(d => d.groupby))).range([0, fy.bandwidth()]);
78
+ const yAxis = this.chart.append('g').call(d3.axisLeft(fy).tickSizeOuter(0).tickPadding(0).tickSizeInner(5)).call(g => {
79
+ g.selectAll('.domain').attr('stroke', theme.XAxisColor);
80
+ g.selectAll('.tick line').attr('stroke', theme.XAxisColor);
81
+ g.selectAll('text').attr('font-size', theme.fontSize);
82
+ g.selectAll('text').attr('fill', theme.textColor);
83
+ // Update axis transform
84
+ const {
85
+ width: axisWidth
86
+ } = g.node().getBoundingClientRect();
87
+ g.attr('transform', "translate(".concat(axisWidth, ", 0)")).attr('data-axisWidth', axisWidth);
88
+ this.checkTickOverlap(g, 'yAxis');
89
+ });
90
+
91
+ // X axis
92
+ const allSeries = this.getAllSeries(newSeries);
93
+ const niceEnd = d3.nice(0, d3.max(allSeries, d => d.sumValue), 5)[1];
94
+ const x = d3.scaleLinear().domain(y_axis_auto_range ? [0, niceEnd] : [y_axis_min || 0, y_axis_max || niceEnd]).range([Number(yAxis.node().getAttribute('data-axisWidth')), chartWidth - insertPadding - marginRight]);
95
+ this.chart.append('g').attr('transform', "translate(0, ".concat(chartHeight - insertPadding, ")")).call(d3.axisBottom(x).tickSizeInner(0).ticks(5)).call(g => {
96
+ g.selectAll('.domain').remove();
97
+ g.selectAll('.tick line').node() && g.selectAll('.tick line').node().remove(); // delete the first line
98
+ g.selectAll('.tick line').attr('y2', -(chartHeight - insertPadding * 2)).attr('stroke', theme.gridColor).attr('stroke-dasharray', '8,3');
99
+ g.selectAll('text').attr('font-size', theme.fontSize);
100
+ g.selectAll('text').attr('fill', theme.textColor);
101
+ });
102
+
103
+ // Rect group
104
+ const rectsWrapper = this.chart.append('g').attr('class', "rects-wrapper-".concat(chart === null || chart === void 0 ? void 0 : chart.id)).attr('transform', "translate(".concat(Number(yAxis.node().getAttribute('data-axisWidth')), ", 0)"));
105
+ rectsWrapper.selectAll().data(newSeries).join('g').attr('transform', _ref => {
106
+ let [name, dum] = _ref;
107
+ const offset = (fy.bandwidth() - dum.length * y.bandwidth()) / 2;
108
+ return "translate(0, ".concat(fy(name) + offset, ")");
109
+ }).attr('data-transform', _ref2 => {
110
+ let [name, dum] = _ref2;
111
+ const offset = (fy.bandwidth() - dum.length * y.bandwidth()) / 2;
112
+ return "".concat(fy(name) + offset);
113
+ }).selectAll().data(_ref3 => {
114
+ let [groupKey] = _ref3;
115
+ const curSeriesData = newSeries.find(item => item[0] === groupKey);
116
+ return curSeriesData[1];
117
+ }).join('g').attr('data-completedRate', _ref4 => {
118
+ let [_, d] = _ref4;
119
+ const restData = d.find(item => item.rawData.group_name === 'rest');
120
+ const completedRate = restData.rawData.completedRate;
121
+ if (completedRate === 'empty') return '';
122
+ return completedRate + '%';
123
+ }).selectAll().data(_ref5 => {
124
+ let [_, d] = _ref5;
125
+ return d;
126
+ }).join('rect').attr('class', 'rect').attr('x', d => x(d[0]) - Number(yAxis.node().getAttribute('data-axisWidth'))).attr('y', d => y.bandwidth() * d.serieIndex).attr('data-y', d => y.bandwidth() * d.serieIndex).attr('width', d => x(d[1]) - x(d[0])).attr('height', y.bandwidth()).attr('fill', d => {
127
+ const key = d.key;
128
+ const groupby = d.rawData.groupby;
129
+ if (key === 'rest') {
130
+ return '#bdbdbd';
131
+ }
132
+ if (column_groupby_column_key) {
133
+ return this.colorMap[groupby];
134
+ }
135
+ return colors[0];
136
+ }).attr('data-value', d => d.rawData.value).attr('data-groupName', d => d.rawData.slugId).attr('data-tooltipTitle', d => d.rawData.name).attr('data-tooltipName', d => d.key).attr('data-groupBy', d => d.rawData.groupby).call(g => {
137
+ // add rect borderRadius
138
+ const allGroup = this.getAllGroup(rectsWrapper);
139
+ allGroup.forEach(group => {
140
+ group.forEach(rects => {
141
+ const firstEl = rects[0];
142
+ firstEl && this.addMaskRect(firstEl === null || firstEl === void 0 ? void 0 : firstEl.parentNode, firstEl, yAxis);
143
+ });
144
+ });
145
+
146
+ // Add label
147
+ if (show_percentage) {
148
+ const newAllGroup = this.getAllGroup(rectsWrapper);
149
+ newAllGroup.forEach(group => {
150
+ group.forEach(rects => {
151
+ const firstEl = rects[0];
152
+ firstEl && this.addLabelToRectRight({
153
+ container: firstEl === null || firstEl === void 0 ? void 0 : firstEl.parentNode,
154
+ xWidth: Number(firstEl.getAttribute('width')),
155
+ yHeight: Number(firstEl.getAttribute('height')),
156
+ x: Number(firstEl.getAttribute('x')),
157
+ y: Number(firstEl.getAttribute('y')),
158
+ theme,
159
+ label_font_size,
160
+ text: firstEl === null || firstEl === void 0 ? void 0 : firstEl.parentNode.getAttribute('data-completedRate')
161
+ });
162
+ });
163
+ });
164
+ }
165
+ }).on('click', (event, data) => {
166
+ this.props.toggleRecords(data);
167
+ }).on('mouseover', event => {
168
+ this.showTooltip(event);
169
+ this.handleAcitveAndInActiveState('inActive', event);
170
+ }).on('mousemove', event => {
171
+ this.moveTooltip(event);
172
+ }).on('mouseleave', (event, data) => {
173
+ this.hiddenTooltip();
174
+ this.handleAcitveAndInActiveState('active', event);
175
+ });
176
+ this.setLegend({
177
+ legendName: 'groupby',
178
+ theme,
179
+ legendPosition: 'top-right',
180
+ data
181
+ });
182
+ };
183
+ this.handleAcitveAndInActiveState = (state, event) => {
184
+ const rectsWrapper = Array.from(event.currentTarget.parentNode.parentNode.parentNode.children);
185
+ const allGroup = [];
186
+ rectsWrapper.forEach(g => {
187
+ const groups = Array.from(g.children);
188
+ groups.forEach(groupRect => {
189
+ const rects = Array.from(groupRect.children);
190
+ rects.forEach(rect => {
191
+ if (rect.getAttribute('class') === 'rect') {
192
+ allGroup.push(rect.parentNode);
193
+ }
194
+ });
195
+ });
196
+ });
197
+ const curGroupName = event.currentTarget.getAttribute('data-groupName');
198
+ this.setActiveAndInActiveState(state, allGroup, curGroupName);
199
+ };
200
+ this.showTooltip = (event, isDiv) => {
201
+ let {
202
+ offsetX,
203
+ offsetY
204
+ } = event;
205
+ if (isDiv) {
206
+ const initX = Number(event.currentTarget.getAttribute('data-x'));
207
+ const initY = Number(event.currentTarget.getAttribute('data-y'));
208
+ offsetX = offsetX + initX;
209
+ offsetY = offsetY + initY;
210
+ }
211
+ const groupby = event.currentTarget.getAttribute('data-groupBy');
212
+ const newTooltipData = {
213
+ title: event.currentTarget.getAttribute('data-tooltipTitle'),
214
+ items: [{
215
+ color: event.currentTarget.getAttribute('data-tooltipName') === 'rest' ? '#bdbdbd' : this.colorMap[groupby],
216
+ name: _intl.default.get(event.currentTarget.getAttribute('data-tooltipName')),
217
+ value: event.currentTarget.getAttribute('data-value')
218
+ }]
219
+ };
220
+ this.setState({
221
+ tooltipData: newTooltipData
222
+ });
223
+ this.setState({
224
+ toolTipPosition: {
225
+ offsetX,
226
+ offsetY
227
+ }
228
+ });
229
+ };
230
+ this.moveTooltip = (event, isDiv) => {
231
+ let {
232
+ offsetX,
233
+ offsetY
234
+ } = event;
235
+ if (isDiv) {
236
+ const initX = Number(event.currentTarget.getAttribute('data-x'));
237
+ const initY = Number(event.currentTarget.getAttribute('data-y'));
238
+ offsetX = offsetX + initX;
239
+ offsetY = offsetY + initY;
240
+ }
241
+ this.setState({
242
+ toolTipPosition: {
243
+ offsetX,
244
+ offsetY
245
+ }
246
+ });
247
+ };
248
+ this.hiddenTooltip = event => {
249
+ this.setState({
250
+ toolTipPosition: null
251
+ });
252
+ };
253
+ this.getGroupSeries = data => {
254
+ const groups = d3.groups(data, d => d.name);
255
+ groups.forEach((item, index) => {
256
+ const itemData = (0, _lodashEs.cloneDeep)(item[1]);
257
+
258
+ // get series
259
+ const series = d3.stack().keys(d3.union(itemData.map(d => d.group_name))).value((_ref6, key) => {
260
+ var _group$get;
261
+ let [_, group] = _ref6;
262
+ return ((_group$get = group.get(String(key))) === null || _group$get === void 0 ? void 0 : _group$get.value) || 0;
263
+ })(d3.index(itemData, d => d.groupby, d => d.group_name));
264
+ item[1] = d3.groups(itemData, d => d.groupby);
265
+ item[1].forEach((group, index) => {
266
+ const groupKey = group[0];
267
+ group[1] = [];
268
+ series.forEach(serie => {
269
+ const serieKey = serie.key;
270
+ serie.forEach(item => {
271
+ if (item.data[0] === groupKey) {
272
+ const newItem = {
273
+ ...item,
274
+ key: serieKey,
275
+ serieIndex: index,
276
+ rawData: item.data[1].get(serieKey)
277
+ };
278
+ group[1].push(newItem);
279
+ }
280
+ });
281
+ });
282
+ let sumValue = 0;
283
+ group[1].forEach(g => {
284
+ sumValue = sumValue + g[1];
285
+ });
286
+ group.sumValue = sumValue;
287
+ });
288
+ });
289
+ return groups;
290
+ };
291
+ this.getAllSeries = newSeries => {
292
+ const allSeries = [];
293
+ newSeries.forEach(series => {
294
+ allSeries.push(...series[1]);
295
+ });
296
+ return allSeries;
297
+ };
298
+ this.getAllGroup = rectsWrapper => {
299
+ const allGroup = [];
300
+ Array.from(rectsWrapper.node().children).forEach(item => {
301
+ const group = [];
302
+ Array.from(item.children).forEach(jtem => {
303
+ const childGroup = [];
304
+ Array.from(jtem.children).forEach(child => {
305
+ if (Number(child.getAttribute('width')) !== 0) {
306
+ childGroup.push(child);
307
+ }
308
+ });
309
+ childGroup.reverse();
310
+ group.push(childGroup);
311
+ });
312
+ allGroup.push(group);
313
+ });
314
+ return allGroup;
315
+ };
316
+ this.addMaskRect = (topG, rect, yAxis) => {
317
+ const xWidth = Number(rect.getAttribute('height'));
318
+ const {
319
+ borderRadius
320
+ } = this.chartBoundingClientRect;
321
+ // Add mask rect
322
+ d3.select(topG).append('foreignObject').attr('class', rect.getAttribute('class')).attr('x', rect.getAttribute('x')).attr('y', rect.getAttribute('y')).attr('data-y', rect.parentNode.parentNode.getAttribute('data-transform')).attr('width', rect.getAttribute('width')).attr('height', rect.getAttribute('height')).attr('data-groupName', rect.getAttribute('data-groupName')).attr('data-value', rect.getAttribute('data-value')).attr('data-tooltipTitle', rect.getAttribute('data-tooltipTitle')).attr('data-tooltipName', rect.getAttribute('data-tooltipName')).attr('data-groupBy', rect.getAttribute('data-groupBy')).attr('data-x', () => {
323
+ const x = Number(rect.getAttribute('x'));
324
+ return x + Number(yAxis.node().getAttribute('data-axisWidth'));
325
+ }).on('click', (event, data) => {
326
+ this.props.toggleRecords(data);
327
+ }).on('mouseover', event => {
328
+ this.showTooltip(event, true);
329
+ this.handleAcitveAndInActiveState('inActive', event);
330
+ }).on('mousemove', event => {
331
+ this.moveTooltip(event, true);
332
+ }).on('mouseleave', event => {
333
+ this.hiddenTooltip();
334
+ this.handleAcitveAndInActiveState('active', event);
335
+ }).append('xhtml:div').attr('style', "width: 100%; height: 100%; background-color: ".concat(rect.getAttribute('fill'), "; border-radius: 0px ").concat(xWidth * borderRadius, "px ").concat(xWidth * borderRadius, "px 0px"));
336
+
337
+ // Remove old rect
338
+ d3.select(rect).remove();
339
+ };
340
+ this.chart = null;
341
+ this.state = {
342
+ tooltipData: null,
343
+ toolTipPosition: null
344
+ };
345
+ }
346
+ componentDidMount() {
347
+ super.componentDidMount();
348
+ this.createChart();
349
+ this.drawChart();
350
+ this.debouncedHandleResize = (0, _lodashEs.debounce)(this.handleResize, 300);
351
+ window.addEventListener('resize', this.debouncedHandleResize);
352
+ }
353
+ componentDidUpdate(prevProps) {
354
+ super.componentDidUpdate(prevProps);
355
+ if (_utils.BaseUtils.shouldChartComponentUpdate(prevProps, this.props)) {
356
+ this.drawChart();
357
+ }
358
+ }
359
+ componentWillUnmount() {
360
+ super.componentWillUnmount();
361
+ this.chart.node() && this.chart.node().remove();
362
+ window.removeEventListener('resize', this.debouncedHandleResize);
363
+ }
364
+ render() {
365
+ const {
366
+ chart
367
+ } = this.props;
368
+ const {
369
+ tooltipData,
370
+ toolTipPosition
371
+ } = this.state;
372
+ return /*#__PURE__*/_react.default.createElement("div", {
373
+ ref: ref => this.container = ref,
374
+ className: (0, _classnames.default)('sea-chart-container', {
375
+ 'show-x-axis-label': this.isShowHorizontalAxisLabel(chart),
376
+ 'show-y-axis-label': this.isShowVerticalAxisLabel(chart)
377
+ })
378
+ }, /*#__PURE__*/_react.default.createElement(_tooltip.default, {
379
+ tooltipData: tooltipData,
380
+ toolTipPosition: toolTipPosition,
381
+ chart: this.chart
382
+ }));
383
+ }
384
+ }
385
+ Completeness.propTypes = {
386
+ canvasStyle: _propTypes.default.object,
387
+ chart: _propTypes.default.object,
388
+ groupbyColumn: _propTypes.default.object,
389
+ columnGroupbyColumn: _propTypes.default.object,
390
+ summaryColumn: _propTypes.default.object,
391
+ result: _propTypes.default.array,
392
+ tables: _propTypes.default.array,
393
+ globalTheme: _propTypes.default.string,
394
+ chartColorTheme: _propTypes.default.string,
395
+ toggleRecords: _propTypes.default.func
396
+ };
397
+ var _default = exports.default = Completeness;
@@ -20,6 +20,9 @@ var _horizontalBar = _interopRequireDefault(require("./horizontal-bar"));
20
20
  var _horizontalBarGroup = _interopRequireDefault(require("./horizontal-bar-group"));
21
21
  var _horizontalBarStack = _interopRequireDefault(require("./horizontal-bar-stack"));
22
22
  var _completeness = _interopRequireDefault(require("./completeness"));
23
+ var _completenessGroup = _interopRequireDefault(require("./completeness-group"));
24
+ var _line = _interopRequireDefault(require("./line"));
25
+ var _lineGroup = _interopRequireDefault(require("./line-group"));
23
26
  var _basicNumberCard = _interopRequireDefault(require("./basic-number-card"));
24
27
  var _trend = _interopRequireDefault(require("./trend"));
25
28
  var _tableElement = _interopRequireDefault(require("./table-element"));
@@ -188,6 +191,24 @@ const Wrapper = _ref => {
188
191
  canvasStyle: canvasStyle
189
192
  }));
190
193
  }
194
+ case _constants.CHART_TYPE.COMPLETENESS_GROUP:
195
+ {
196
+ return /*#__PURE__*/_react.default.createElement(_completenessGroup.default, Object.assign({}, baseProps, {
197
+ canvasStyle: canvasStyle
198
+ }));
199
+ }
200
+ case _constants.CHART_TYPE.LINE:
201
+ {
202
+ return /*#__PURE__*/_react.default.createElement(_line.default, Object.assign({}, baseProps, {
203
+ canvasStyle: canvasStyle
204
+ }));
205
+ }
206
+ case _constants.CHART_TYPE.LINE_GROUP:
207
+ {
208
+ return /*#__PURE__*/_react.default.createElement(_lineGroup.default, Object.assign({}, baseProps, {
209
+ canvasStyle: canvasStyle
210
+ }));
211
+ }
191
212
  case _constants.CHART_TYPE.BASIC_NUMBER_CARD:
192
213
  {
193
214
  return /*#__PURE__*/_react.default.createElement(_basicNumberCard.default, Object.assign({}, baseProps, {
@@ -0,0 +1,403 @@
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 _react = _interopRequireDefault(require("react"));
10
+ var _propTypes = _interopRequireDefault(require("prop-types"));
11
+ var _lodashEs = require("lodash-es");
12
+ var d3 = _interopRequireWildcard(require("d3"));
13
+ var _classnames = _interopRequireDefault(require("classnames"));
14
+ var _dtableUtils = require("dtable-utils");
15
+ var _constants = require("../../constants");
16
+ var _colorRules = require("../../constants/color-rules");
17
+ var _utils = require("../../utils");
18
+ var _intl = _interopRequireDefault(require("../../intl"));
19
+ var _tooltip = _interopRequireDefault(require("../../components/tooltip"));
20
+ var _chartComponent = _interopRequireDefault(require("./chart-component"));
21
+ class LineGroup extends _chartComponent.default {
22
+ constructor(props) {
23
+ super(props);
24
+ this.handleResize = () => {
25
+ this.chart.node() && this.chart.node().remove();
26
+ this.createChart();
27
+ this.drawChart();
28
+ };
29
+ this.createChart = () => {
30
+ const {
31
+ chart
32
+ } = this.props;
33
+ const {
34
+ y_axis_show_label,
35
+ x_axis_show_label,
36
+ y_axis_show_value
37
+ } = chart.config;
38
+ const initConfig = {
39
+ insertPadding: 30,
40
+ marginLeft: y_axis_show_label ? 20 : 0,
41
+ marginBottom: x_axis_show_label ? 20 : 0,
42
+ marginTop: y_axis_show_value ? 15 : 0
43
+ };
44
+ this.initChart(this.container, chart === null || chart === void 0 ? void 0 : chart.id, initConfig);
45
+ };
46
+ this.drawChart = () => {
47
+ const {
48
+ customRender
49
+ } = this.props;
50
+ let {
51
+ result: data
52
+ } = this.props;
53
+ data = _utils.BaseUtils.formatEmptyName(data, '', _intl.default.get('Empty'));
54
+ if (!Array.isArray(data)) return;
55
+ this.draw(data);
56
+ this.renderAxisLabel(this.props.chart, this.props.tables, this.container);
57
+ (0, _utils.isFunction)(customRender) && customRender(this.chart);
58
+ };
59
+ this.showTooltip = (event, data, rectsWrapper) => {
60
+ const {
61
+ offsetX,
62
+ offsetY
63
+ } = event;
64
+ const {
65
+ title,
66
+ items
67
+ } = this.getTooltipItems(data, rectsWrapper);
68
+ const newTooltipData = {
69
+ title,
70
+ items
71
+ };
72
+ this.setState({
73
+ tooltipData: newTooltipData
74
+ });
75
+ this.setState({
76
+ toolTipPosition: {
77
+ offsetX,
78
+ offsetY
79
+ }
80
+ });
81
+ };
82
+ this.moveTooltip = (event, data, rectsWrapper) => {
83
+ const {
84
+ offsetX,
85
+ offsetY
86
+ } = event;
87
+ const {
88
+ title,
89
+ items
90
+ } = this.getTooltipItems(data, rectsWrapper);
91
+ const newTooltipData = {
92
+ title,
93
+ items
94
+ };
95
+ this.setState({
96
+ tooltipData: newTooltipData
97
+ });
98
+ this.setState({
99
+ toolTipPosition: {
100
+ offsetX,
101
+ offsetY
102
+ }
103
+ });
104
+ };
105
+ this.hiddenTooltip = event => {
106
+ this.setState({
107
+ toolTipPosition: null
108
+ });
109
+ };
110
+ this.getTooltipItems = (data, rectsWrapper) => {
111
+ var _rectsWrapper$selectA;
112
+ const title = !data.name && typeof data.name !== 'number' ? _intl.default.get(_constants.EMPTY_NAME) : data.name;
113
+ const circleList = (_rectsWrapper$selectA = rectsWrapper.selectAll('circle')) === null || _rectsWrapper$selectA === void 0 ? void 0 : _rectsWrapper$selectA.nodes();
114
+ const items = circleList.filter(circle => circle.getAttribute('data-name') === title).map(circle => {
115
+ return {
116
+ color: this.colorMap[circle.getAttribute('data-groupName')],
117
+ name: circle.getAttribute('data-groupName'),
118
+ value: circle.getAttribute('data-text')
119
+ };
120
+ });
121
+ return {
122
+ title,
123
+ items
124
+ };
125
+ };
126
+ this.draw = data => {
127
+ const {
128
+ chart,
129
+ globalTheme,
130
+ columnGroupbyColumn,
131
+ chartColorTheme
132
+ } = this.props;
133
+ const theme = _constants.CHART_THEME_COLOR[globalTheme];
134
+ const {
135
+ display_goal_line,
136
+ goal_value,
137
+ goal_label
138
+ } = chart.style_config || {};
139
+ const {
140
+ y_axis_show_value,
141
+ label_font_size,
142
+ line_type,
143
+ y_axis_max,
144
+ y_axis_min,
145
+ y_axis_auto_range,
146
+ color_theme
147
+ } = chart.config;
148
+ const {
149
+ width: chartWidth,
150
+ height: chartHeight,
151
+ insertPadding,
152
+ marginTop
153
+ } = this.chartBoundingClientRect;
154
+ const useSingleSelectColumnColor = (columnGroupbyColumn === null || columnGroupbyColumn === void 0 ? void 0 : columnGroupbyColumn.type) === _dtableUtils.CellType.SINGLE_SELECT && color_theme === _colorRules.SUPPORT_SINGLE_SELECT_THEMES_OPTIONS.SINGLE_SELECT_COLUMN_COLORS;
155
+ useSingleSelectColumnColor ? this.setSingleSelectColorMap(data) : this.setColorMap(data, chartColorTheme);
156
+
157
+ // Y axis
158
+ const niceEnd = d3.nice(0, d3.max(data, d => d.value), 5)[1];
159
+ const y = d3.scaleLinear().domain(y_axis_auto_range ? [0, niceEnd] : [y_axis_min || 0, y_axis_max || niceEnd]).range([chartHeight - insertPadding, insertPadding + marginTop]);
160
+ 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));
161
+
162
+ // X axis
163
+ const xDomain = data.map(item => item.name);
164
+ const x = d3.scaleBand().domain(xDomain).range([insertPadding + this.horizontalOverflowOffset, chartWidth - insertPadding]).paddingInner(0.4).paddingOuter(0.1);
165
+ this.ticksWrapper = this.chart.append('g').attr('transform', "translate(0, ".concat(chartHeight - insertPadding, ")")).call(d3.axisBottom(x).tickSizeOuter(0).tickSizeInner(5)).call(g => {
166
+ this.ticksAddName(g);
167
+ g.selectAll('.domain').attr('stroke', theme.XAxisColor);
168
+ g.selectAll('.tick line').attr('stroke', theme.XAxisColor);
169
+ g.selectAll('text').attr('font-size', theme.fontSize);
170
+ g.selectAll('text').attr('fill', theme.textColor);
171
+ this.checkTickOverlap(g);
172
+ });
173
+
174
+ // Line
175
+ const rectsWrapper = this.chart.append('g').attr('class', "rects-wrapper-".concat(chart === null || chart === void 0 ? void 0 : chart.id));
176
+ const circleDatas = [];
177
+ const groupData = d3.groups(data, d => d.group_name);
178
+ groupData.forEach(item => {
179
+ const circleData = xDomain.map(() => ({}));
180
+ const line = d3.line().x((d, index) => {
181
+ const xVal = x(d.name) + x.bandwidth() / 2;
182
+ circleData[index]['x'] = xVal;
183
+ circleData[index]['name'] = d.name;
184
+ return xVal;
185
+ }).y((d, index) => {
186
+ const yVal = y(d.value);
187
+ circleData[index]['y'] = yVal;
188
+ circleData[index]['value'] = d.value;
189
+ return yVal;
190
+ }).curve(line_type === _constants.CHART_LINE_TYPES[1] ? d3.curveBumpX : d3.curveLinear);
191
+ const group_name = item[0];
192
+ const data = item[1];
193
+ rectsWrapper.append('path').attr('fill', 'none').attr('stroke', this.colorMap[group_name]).attr('stroke-width', 2).attr('d', () => line(data));
194
+ circleDatas.push({
195
+ group_name,
196
+ circleData
197
+ });
198
+ });
199
+
200
+ // circle
201
+ circleDatas.forEach(_ref => {
202
+ let {
203
+ group_name,
204
+ circleData
205
+ } = _ref;
206
+ circleData.forEach(item => {
207
+ if (Object.keys(item).length > 0) {
208
+ rectsWrapper.append('circle').attr('cx', item.x).attr('cy', item.y).attr('r', 3).attr('fill', this.colorMap[group_name]).attr('opacity', y_axis_show_value ? 1 : 0).attr('data-groupName', group_name).attr('data-text', item.value).attr('data-name', item.name).call(g => {
209
+ // circle label
210
+ if (y_axis_show_value) {
211
+ const curCircleEl = g.node();
212
+ rectsWrapper.append('text').attr('fill', theme.labelColor).attr('font-size', _utils.BaseUtils.getLabelFontSize(label_font_size)).text(curCircleEl.getAttribute('data-text')).call(g => {
213
+ const {
214
+ width
215
+ } = g.node().getBoundingClientRect();
216
+ const translateX = Number(curCircleEl.getAttribute('cx')) - width / 2;
217
+ const translateY = Number(curCircleEl.getAttribute('cy')) - 10;
218
+ g.attr('transform', "translate(".concat(translateX, ", ").concat(translateY, ")"));
219
+ });
220
+ }
221
+ }).on('click', (event, data) => {
222
+ this.props.toggleRecords(data);
223
+ });
224
+ }
225
+ });
226
+ });
227
+ this.chart.on('mouseover', event => {
228
+ this.updateCircleAndTickStyle({
229
+ event,
230
+ state: 'zoomIn',
231
+ circleDatas,
232
+ rectsWrapper,
233
+ eventState: 'over'
234
+ });
235
+ }).on('mousemove', event => {
236
+ this.updateCircleAndTickStyle({
237
+ event,
238
+ state: 'zoomIn',
239
+ circleDatas,
240
+ rectsWrapper,
241
+ eventState: 'move'
242
+ });
243
+ }).on('mouseleave', event => {
244
+ this.updateCircleAndTickStyle({
245
+ event,
246
+ state: 'zoomOut',
247
+ circleDatas,
248
+ rectsWrapper,
249
+ eventState: 'leave'
250
+ });
251
+ });
252
+ if (display_goal_line && goal_label && goal_value) {
253
+ this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y);
254
+ }
255
+ this.setLegend({
256
+ legendName: 'group_name',
257
+ theme,
258
+ legendPosition: 'top-right',
259
+ data
260
+ });
261
+ };
262
+ this.updateCircleAndTickStyle = _ref2 => {
263
+ var _rectsWrapper$selectA2, _this$ticksWrapper$se;
264
+ let {
265
+ event,
266
+ state,
267
+ circleDatas,
268
+ rectsWrapper,
269
+ eventState
270
+ } = _ref2;
271
+ const {
272
+ y_axis_show_value
273
+ } = this.props.chart.config;
274
+ const {
275
+ height: chartHeight,
276
+ insertPadding,
277
+ marginTop
278
+ } = this.chartBoundingClientRect;
279
+ const {
280
+ offsetX
281
+ } = event;
282
+ const minDistanceArr = [];
283
+ circleDatas.forEach(_ref3 => {
284
+ let {
285
+ group_name,
286
+ circleData
287
+ } = _ref3;
288
+ const item = this.getMinDistanceItem(offsetX, circleData);
289
+ minDistanceArr.push(item);
290
+ });
291
+ const minIndex = d3.minIndex(minDistanceArr, d => d.distance);
292
+ const minDistanceItem = minDistanceArr[minIndex];
293
+
294
+ // circle
295
+ const circleList = (_rectsWrapper$selectA2 = rectsWrapper.selectAll('circle')) === null || _rectsWrapper$selectA2 === void 0 ? void 0 : _rectsWrapper$selectA2.nodes();
296
+ if (circleList.length !== 0) {
297
+ if (state === 'zoomIn') {
298
+ circleList.forEach(circle => {
299
+ const name = circle.getAttribute('data-name');
300
+ if (name === minDistanceItem.name) {
301
+ d3.select(circle).attr('opacity', 1);
302
+ d3.select(circle).attr('r', 5);
303
+ } else {
304
+ d3.select(circle).attr('opacity', 0);
305
+ d3.select(circle).attr('r', 3);
306
+ }
307
+ });
308
+ } else {
309
+ circleList.forEach(circle => {
310
+ !y_axis_show_value && d3.select(circle).attr('opacity', 0);
311
+ d3.select(circle).attr('r', 3);
312
+ });
313
+ }
314
+ }
315
+
316
+ // tick
317
+ const ticks = (_this$ticksWrapper$se = this.ticksWrapper.selectAll('.tick line')) === null || _this$ticksWrapper$se === void 0 ? void 0 : _this$ticksWrapper$se.nodes();
318
+ if (ticks.length !== 0) {
319
+ if (state === 'zoomIn') {
320
+ ticks.forEach(tick => {
321
+ const name = tick.getAttribute('data-name');
322
+ if (name === minDistanceItem.name) {
323
+ d3.select(tick).attr('y2', -(chartHeight - insertPadding * 2 - marginTop));
324
+ } else {
325
+ d3.select(tick).attr('y2', 0);
326
+ }
327
+ });
328
+ } else {
329
+ ticks.forEach(tick => {
330
+ d3.select(tick).attr('y2', 0);
331
+ });
332
+ }
333
+ }
334
+
335
+ // tooltip
336
+ if (eventState === 'over') {
337
+ this.showTooltip(event, minDistanceItem, rectsWrapper);
338
+ }
339
+ if (eventState === 'move') {
340
+ this.moveTooltip(event, minDistanceItem, rectsWrapper);
341
+ }
342
+ if (eventState === 'leave') {
343
+ this.hiddenTooltip();
344
+ }
345
+ };
346
+ this.chart = null;
347
+ this.state = {
348
+ tooltipData: null,
349
+ toolTipPosition: null
350
+ };
351
+ }
352
+ componentDidMount() {
353
+ this.createChart();
354
+ this.drawChart();
355
+ this.debouncedHandleResize = (0, _lodashEs.debounce)(this.handleResize, 300);
356
+ window.addEventListener('resize', this.debouncedHandleResize);
357
+ }
358
+ componentDidUpdate(prevProps) {
359
+ super.componentDidUpdate(prevProps);
360
+ if (_utils.BaseUtils.shouldChartComponentUpdate(prevProps, this.props)) {
361
+ this.createChart();
362
+ this.drawChart();
363
+ }
364
+ }
365
+ componentWillUnmount() {
366
+ this.chart.node() && this.chart.node().remove();
367
+ window.removeEventListener('resize', this.debouncedHandleResize);
368
+ }
369
+ render() {
370
+ const {
371
+ chart
372
+ } = this.props;
373
+ const {
374
+ tooltipData,
375
+ toolTipPosition
376
+ } = this.state;
377
+ return /*#__PURE__*/_react.default.createElement("div", {
378
+ ref: ref => this.container = ref,
379
+ className: (0, _classnames.default)('sea-chart-container', {
380
+ 'show-x-axis-label': this.isShowXAxisLabel(chart),
381
+ 'show-y-axis-label': this.isShowYAxisLabel(chart)
382
+ })
383
+ }, /*#__PURE__*/_react.default.createElement(_tooltip.default, {
384
+ tooltipData: tooltipData,
385
+ toolTipPosition: toolTipPosition,
386
+ chart: this.chart
387
+ }));
388
+ }
389
+ }
390
+ LineGroup.propTypes = {
391
+ canvasStyle: _propTypes.default.object,
392
+ chart: _propTypes.default.object,
393
+ groupbyColumn: _propTypes.default.object,
394
+ columnGroupbyColumn: _propTypes.default.object,
395
+ summaryColumn: _propTypes.default.object,
396
+ result: _propTypes.default.array,
397
+ tables: _propTypes.default.array,
398
+ globalTheme: _propTypes.default.string,
399
+ chartColorTheme: _propTypes.default.string,
400
+ toggleRecords: _propTypes.default.func,
401
+ customRender: _propTypes.default.func
402
+ };
403
+ var _default = exports.default = LineGroup;
@@ -0,0 +1,371 @@
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 _react = _interopRequireDefault(require("react"));
10
+ var _propTypes = _interopRequireDefault(require("prop-types"));
11
+ var _lodashEs = require("lodash-es");
12
+ var d3 = _interopRequireWildcard(require("d3"));
13
+ var _classnames = _interopRequireDefault(require("classnames"));
14
+ var _constants = require("../../constants");
15
+ var _utils = require("../../utils");
16
+ var _intl = _interopRequireDefault(require("../../intl"));
17
+ var _tooltip = _interopRequireDefault(require("../../components/tooltip"));
18
+ var _chartComponent = _interopRequireDefault(require("./chart-component"));
19
+ class Line 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
+ const {
46
+ customRender
47
+ } = this.props;
48
+ let {
49
+ result: data
50
+ } = this.props;
51
+ data = _utils.BaseUtils.formatEmptyName(data, '', _intl.default.get('Empty'));
52
+ if (!Array.isArray(data)) return;
53
+ this.draw(data);
54
+ this.renderAxisLabel(this.props.chart, this.props.tables, this.container);
55
+ (0, _utils.isFunction)(customRender) && customRender(this.chart);
56
+ };
57
+ this.showTooltip = (event, data, title) => {
58
+ const {
59
+ offsetX,
60
+ offsetY
61
+ } = event;
62
+ const newTooltipData = {
63
+ title: title,
64
+ items: [{
65
+ color: this.getChartBarColor(),
66
+ name: data.name,
67
+ value: data.value
68
+ }]
69
+ };
70
+ this.setState({
71
+ tooltipData: newTooltipData
72
+ });
73
+ this.setState({
74
+ toolTipPosition: {
75
+ offsetX,
76
+ offsetY
77
+ }
78
+ });
79
+ };
80
+ this.moveTooltip = (event, data, title) => {
81
+ const {
82
+ offsetX,
83
+ offsetY
84
+ } = event;
85
+ const newTooltipData = {
86
+ title: title,
87
+ items: [{
88
+ color: this.getChartBarColor(),
89
+ name: data.name,
90
+ value: data.value
91
+ }]
92
+ };
93
+ this.setState({
94
+ tooltipData: newTooltipData
95
+ });
96
+ this.setState({
97
+ toolTipPosition: {
98
+ offsetX,
99
+ offsetY
100
+ }
101
+ });
102
+ };
103
+ this.hiddenTooltip = event => {
104
+ this.setState({
105
+ toolTipPosition: null
106
+ });
107
+ };
108
+ this.draw = data => {
109
+ const {
110
+ chart,
111
+ globalTheme,
112
+ tables
113
+ } = this.props;
114
+ const theme = _constants.CHART_THEME_COLOR[globalTheme];
115
+ const {
116
+ display_goal_line,
117
+ goal_value,
118
+ goal_label
119
+ } = chart.style_config || {};
120
+ const {
121
+ table_id,
122
+ y_axis_column_key,
123
+ y_axis_summary_column_key,
124
+ y_axis_show_value,
125
+ label_font_size,
126
+ line_type,
127
+ y_axis_summary_type,
128
+ y_axis_max,
129
+ y_axis_min,
130
+ y_axis_auto_range
131
+ } = chart.config;
132
+ const {
133
+ width: chartWidth,
134
+ height: chartHeight,
135
+ insertPadding,
136
+ marginTop
137
+ } = this.chartBoundingClientRect;
138
+ const chartBarColor = this.getChartBarColor();
139
+ const tooltipTitle = this.getTitle(tables, table_id, y_axis_summary_type, y_axis_column_key || y_axis_summary_column_key);
140
+
141
+ // Y axis
142
+ const niceEnd = d3.nice(0, d3.max(data, d => d.value), 5)[1];
143
+ const y = d3.scaleLinear().domain(y_axis_auto_range ? [0, niceEnd] : [y_axis_min || 0, y_axis_max || niceEnd]).range([chartHeight - insertPadding, insertPadding + marginTop]);
144
+ 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));
145
+
146
+ // X axis
147
+ const xDomain = data.map(item => item.name);
148
+ const x = d3.scaleBand().domain(xDomain).range([insertPadding + this.horizontalOverflowOffset, chartWidth - insertPadding]).paddingInner(0.4).paddingOuter(0.1);
149
+ this.ticksWrapper = this.chart.append('g').attr('transform', "translate(0, ".concat(chartHeight - insertPadding, ")")).call(d3.axisBottom(x).tickSizeOuter(0).tickSizeInner(5)).call(g => {
150
+ this.ticksAddName(g);
151
+ g.selectAll('.domain').attr('stroke', theme.XAxisColor);
152
+ g.selectAll('.tick line').attr('stroke', theme.XAxisColor);
153
+ g.selectAll('text').attr('font-size', theme.fontSize);
154
+ g.selectAll('text').attr('fill', theme.textColor);
155
+ this.checkTickOverlap(g);
156
+ });
157
+
158
+ // Line
159
+ const circleData = xDomain.map(() => ({}));
160
+ const line = d3.line().x((d, index) => {
161
+ const xVal = x(d.name) + x.bandwidth() / 2;
162
+ circleData[index]['x'] = xVal;
163
+ circleData[index]['name'] = d.name;
164
+ return xVal;
165
+ }).y((d, index) => {
166
+ const yVal = y(d.value);
167
+ circleData[index]['y'] = yVal;
168
+ circleData[index]['value'] = d.value;
169
+ return yVal;
170
+ }).curve(line_type === _constants.CHART_LINE_TYPES[1] ? d3.curveBumpX : d3.curveLinear);
171
+ const rectsWrapper = this.chart.append('g').attr('class', "rects-wrapper-".concat(chart === null || chart === void 0 ? void 0 : chart.id));
172
+ rectsWrapper.append('path').attr('fill', 'none').attr('stroke', chartBarColor).attr('stroke-width', 2).attr('d', () => line(data));
173
+
174
+ // circle
175
+ circleData.forEach(item => {
176
+ rectsWrapper.append('circle').attr('cx', item.x).attr('cy', item.y).attr('r', 3).attr('fill', chartBarColor).attr('opacity', y_axis_show_value ? 1 : 0).attr('data-text', item.value).attr('data-name', item.name).call(g => {
177
+ // circle label
178
+ if (y_axis_show_value) {
179
+ const curCircleEl = g.node();
180
+ rectsWrapper.append('text').attr('fill', theme.labelColor).attr('font-size', _utils.BaseUtils.getLabelFontSize(label_font_size)).text(curCircleEl.getAttribute('data-text')).call(g => {
181
+ const {
182
+ width
183
+ } = g.node().getBoundingClientRect();
184
+ const translateX = Number(curCircleEl.getAttribute('cx')) - width / 2;
185
+ const translateY = Number(curCircleEl.getAttribute('cy')) - 10;
186
+ g.attr('transform', "translate(".concat(translateX, ", ").concat(translateY, ")"));
187
+ });
188
+ }
189
+ }).on('click', (event, data) => {
190
+ this.props.toggleRecords(data);
191
+ });
192
+ });
193
+ this.chart.on('mouseover', event => {
194
+ this.updateCircleAndTickStyle({
195
+ event,
196
+ state: 'zoomIn',
197
+ circleData,
198
+ rectsWrapper,
199
+ eventState: 'over',
200
+ tooltipTitle
201
+ });
202
+ }).on('mousemove', event => {
203
+ this.updateCircleAndTickStyle({
204
+ event,
205
+ state: 'zoomIn',
206
+ circleData,
207
+ rectsWrapper,
208
+ eventState: 'move',
209
+ tooltipTitle
210
+ });
211
+ }).on('mouseleave', event => {
212
+ this.updateCircleAndTickStyle({
213
+ event,
214
+ state: 'zoomOut',
215
+ circleData,
216
+ rectsWrapper,
217
+ eventState: 'leave',
218
+ tooltipTitle
219
+ });
220
+ });
221
+ if (display_goal_line && goal_label && goal_value) {
222
+ this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y);
223
+ }
224
+ };
225
+ this.updateCircleAndTickStyle = _ref => {
226
+ var _rectsWrapper$selectA, _this$ticksWrapper$se;
227
+ let {
228
+ event,
229
+ state,
230
+ circleData,
231
+ rectsWrapper,
232
+ eventState,
233
+ tooltipTitle
234
+ } = _ref;
235
+ const {
236
+ y_axis_show_value
237
+ } = this.props.chart.config;
238
+ const {
239
+ height: chartHeight,
240
+ insertPadding,
241
+ marginTop
242
+ } = this.chartBoundingClientRect;
243
+ const {
244
+ offsetX
245
+ } = event;
246
+ const minDistanceItem = this.getMinDistanceItem(offsetX, circleData);
247
+ const circleList = (_rectsWrapper$selectA = rectsWrapper.selectAll('circle')) === null || _rectsWrapper$selectA === void 0 ? void 0 : _rectsWrapper$selectA.nodes();
248
+ if (circleList.length !== 0) {
249
+ if (state === 'zoomIn') {
250
+ circleList.forEach(circle => {
251
+ const name = circle.getAttribute('data-name');
252
+ if (name === minDistanceItem.name) {
253
+ d3.select(circle).attr('opacity', 1);
254
+ d3.select(circle).attr('r', 5);
255
+ } else {
256
+ d3.select(circle).attr('opacity', 0);
257
+ d3.select(circle).attr('r', 3);
258
+ }
259
+ });
260
+ } else {
261
+ circleList.forEach(circle => {
262
+ !y_axis_show_value && d3.select(circle).attr('opacity', 0);
263
+ d3.select(circle).attr('r', 3);
264
+ });
265
+ }
266
+ }
267
+ const ticks = (_this$ticksWrapper$se = this.ticksWrapper.selectAll('.tick line')) === null || _this$ticksWrapper$se === void 0 ? void 0 : _this$ticksWrapper$se.nodes();
268
+ if (ticks.length !== 0) {
269
+ if (state === 'zoomIn') {
270
+ ticks.forEach(tick => {
271
+ const name = tick.getAttribute('data-name');
272
+ if (name === minDistanceItem.name) {
273
+ d3.select(tick).attr('y2', -(chartHeight - insertPadding * 2 - marginTop));
274
+ } else {
275
+ d3.select(tick).attr('y2', 0);
276
+ }
277
+ });
278
+ } else {
279
+ ticks.forEach(tick => {
280
+ d3.select(tick).attr('y2', 0);
281
+ });
282
+ }
283
+ }
284
+
285
+ // tooltip
286
+ if (eventState === 'over') {
287
+ this.showTooltip(event, minDistanceItem, tooltipTitle);
288
+ }
289
+ if (eventState === 'move') {
290
+ this.moveTooltip(event, minDistanceItem, tooltipTitle);
291
+ }
292
+ if (eventState === 'leave') {
293
+ this.hiddenTooltip();
294
+ }
295
+ };
296
+ this.getChartBarColor = () => {
297
+ const {
298
+ chart,
299
+ chartColorTheme
300
+ } = this.props;
301
+ const {
302
+ y_axis_label_color,
303
+ color_option
304
+ } = chart.config;
305
+ let chartBarColor = _constants.CHART_STYLE_COLORS[0];
306
+ if (chartColorTheme) {
307
+ chartBarColor = _utils.BaseUtils.getCurrentTheme(chartColorTheme).colors[0];
308
+ }
309
+ if (color_option === _constants.TYPE_COLOR_USING.USE_SPECIFIC_COLORS && y_axis_label_color) {
310
+ chartBarColor = y_axis_label_color;
311
+ }
312
+ return chartBarColor;
313
+ };
314
+ this.chart = null;
315
+ this.state = {
316
+ tooltipData: null,
317
+ toolTipPosition: null
318
+ };
319
+ }
320
+ componentDidMount() {
321
+ this.createChart();
322
+ this.drawChart();
323
+ this.debouncedHandleResize = (0, _lodashEs.debounce)(this.handleResize, 300);
324
+ window.addEventListener('resize', this.debouncedHandleResize);
325
+ }
326
+ componentDidUpdate(prevProps) {
327
+ super.componentDidUpdate(prevProps);
328
+ if (_utils.BaseUtils.shouldChartComponentUpdate(prevProps, this.props)) {
329
+ this.createChart();
330
+ this.drawChart();
331
+ }
332
+ }
333
+ componentWillUnmount() {
334
+ this.chart.node() && this.chart.node().remove();
335
+ window.removeEventListener('resize', this.debouncedHandleResize);
336
+ }
337
+ render() {
338
+ const {
339
+ chart
340
+ } = this.props;
341
+ const {
342
+ tooltipData,
343
+ toolTipPosition
344
+ } = this.state;
345
+ return /*#__PURE__*/_react.default.createElement("div", {
346
+ ref: ref => this.container = ref,
347
+ className: (0, _classnames.default)('sea-chart-container', {
348
+ 'show-x-axis-label': this.isShowXAxisLabel(chart),
349
+ 'show-y-axis-label': this.isShowYAxisLabel(chart)
350
+ })
351
+ }, /*#__PURE__*/_react.default.createElement(_tooltip.default, {
352
+ tooltipData: tooltipData,
353
+ toolTipPosition: toolTipPosition,
354
+ chart: this.chart
355
+ }));
356
+ }
357
+ }
358
+ Line.propTypes = {
359
+ canvasStyle: _propTypes.default.object,
360
+ chart: _propTypes.default.object,
361
+ groupbyColumn: _propTypes.default.object,
362
+ columnGroupbyColumn: _propTypes.default.object,
363
+ summaryColumn: _propTypes.default.object,
364
+ result: _propTypes.default.array,
365
+ tables: _propTypes.default.array,
366
+ globalTheme: _propTypes.default.string,
367
+ chartColorTheme: _propTypes.default.string,
368
+ toggleRecords: _propTypes.default.func,
369
+ customRender: _propTypes.default.func
370
+ };
371
+ var _default = exports.default = Line;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sea-chart",
3
- "version": "2.0.13",
3
+ "version": "2.0.15",
4
4
  "main": "./dist/index.js",
5
5
  "dependencies": {
6
6
  "@dnd-kit/core": "^6.1.0",