sea-chart 2.0.13 → 2.0.14

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.
@@ -70,7 +70,6 @@ const TypesDialog = _ref => {
70
70
  const handleFilterTypes = (0, _react.useCallback)(() => {
71
71
  if (hideTypeToggle) {
72
72
  const newChartTypes = _constants.CHART_TYPES.filter(item => ['Histogram', 'Bar_chart'].includes(item.name));
73
- newChartTypes[1].children = newChartTypes[1].children.slice(0, 4);
74
73
  return newChartTypes;
75
74
  }
76
75
  return _constants.CHART_TYPES;
@@ -876,7 +876,8 @@ class ChartComponent extends _react.Component {
876
876
  }
877
877
  return [[cx, cy - height / 2], [cx - size / 2, cy + height / 2], [cx + size / 2, cy + height / 2]];
878
878
  };
879
- this.setColorMap = (data, chartColorTheme) => {
879
+ this.setColorMap = function (data, chartColorTheme) {
880
+ let groupName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'group_name';
880
881
  let currentIdx = 0;
881
882
  const defaultColors = _constants.CHART_STYLE_COLORS;
882
883
  let colors = defaultColors;
@@ -884,12 +885,12 @@ class ChartComponent extends _react.Component {
884
885
  colors = _utils.BaseUtils.getCurrentTheme(chartColorTheme).colors;
885
886
  }
886
887
  const colorMap = data.reduce((acc, cur) => {
887
- if (cur.group_name && !acc[cur.group_name]) {
888
- acc[cur.group_name] = colors[currentIdx++ % colors.length];
888
+ if (cur[groupName] && !acc[cur[groupName]]) {
889
+ acc[cur[groupName]] = colors[currentIdx++ % colors.length];
889
890
  }
890
891
  return acc;
891
892
  }, {});
892
- this.colorMap = colorMap;
893
+ _this.colorMap = colorMap;
893
894
  };
894
895
  this.setSingleSelectColorMap = data => {
895
896
  const colorMap = {};
@@ -1250,6 +1251,7 @@ class ChartComponent extends _react.Component {
1250
1251
  } = this.chartBoundingClientRect;
1251
1252
  const viewBox = this.chart.node().getAttribute('viewBox').split(',');
1252
1253
  if (axis === 'yAxis') {
1254
+ let isRoateText = false;
1253
1255
  let allHeight = 0;
1254
1256
  // Can't fit tilted text, Italic text
1255
1257
  for (let tick of allTicks) {
@@ -1265,6 +1267,7 @@ class ChartComponent extends _react.Component {
1265
1267
  d3.select(tick).select('text').attr('transform', 'rotate(30)').style('text-anchor', 'end').attr('dy', '1em').attr('dx', '-0.5em');
1266
1268
  }
1267
1269
  });
1270
+ isRoateText = true;
1268
1271
  break;
1269
1272
  }
1270
1273
  }
@@ -1273,7 +1276,7 @@ class ChartComponent extends _react.Component {
1273
1276
  const {
1274
1277
  width
1275
1278
  } = g.node().getBoundingClientRect();
1276
- if (width > insertPadding) {
1279
+ if (isRoateText && width > insertPadding) {
1277
1280
  const viewWidth = viewBox[viewBox.length - 2];
1278
1281
  viewBox[0] = "-".concat(width - insertPadding);
1279
1282
  viewBox[viewBox.length - 2] = "".concat(Number(viewWidth) + (width - insertPadding));
@@ -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,7 @@ 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"));
23
24
  var _basicNumberCard = _interopRequireDefault(require("./basic-number-card"));
24
25
  var _trend = _interopRequireDefault(require("./trend"));
25
26
  var _tableElement = _interopRequireDefault(require("./table-element"));
@@ -188,6 +189,12 @@ const Wrapper = _ref => {
188
189
  canvasStyle: canvasStyle
189
190
  }));
190
191
  }
192
+ case _constants.CHART_TYPE.COMPLETENESS_GROUP:
193
+ {
194
+ return /*#__PURE__*/_react.default.createElement(_completenessGroup.default, Object.assign({}, baseProps, {
195
+ canvasStyle: canvasStyle
196
+ }));
197
+ }
191
198
  case _constants.CHART_TYPE.BASIC_NUMBER_CARD:
192
199
  {
193
200
  return /*#__PURE__*/_react.default.createElement(_basicNumberCard.default, Object.assign({}, baseProps, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sea-chart",
3
- "version": "2.0.13",
3
+ "version": "2.0.14",
4
4
  "main": "./dist/index.js",
5
5
  "dependencies": {
6
6
  "@dnd-kit/core": "^6.1.0",