sea-chart 2.0.14 → 2.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,328 @@
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 _constants = require("../../constants");
14
+ var _utils = require("../../utils");
15
+ var _intl = _interopRequireDefault(require("../../intl"));
16
+ var _colorRules = require("../../constants/color-rules");
17
+ var _tooltip = _interopRequireDefault(require("../../components/tooltip"));
18
+ var _chartComponent = _interopRequireDefault(require("./chart-component"));
19
+ class Ring extends _chartComponent.default {
20
+ constructor(props) {
21
+ super(props);
22
+ this.createChart = () => {
23
+ const {
24
+ chart
25
+ } = this.props;
26
+ const {
27
+ show_legend
28
+ } = chart.config;
29
+ const initConfig = {
30
+ insertPadding: 30,
31
+ rightLegendSpace: show_legend ? 150 : 0
32
+ };
33
+ this.initChart(this.container, chart === null || chart === void 0 ? void 0 : chart.id, initConfig);
34
+ };
35
+ this.handleResize = () => {
36
+ this.chart.node() && this.chart.node().remove();
37
+ this.createChart();
38
+ this.drawChart();
39
+ };
40
+ this.drawChart = () => {
41
+ const {
42
+ result: data,
43
+ customRender
44
+ } = this.props;
45
+ this.draw(data);
46
+ (0, _utils.isFunction)(customRender) && customRender(this.chart);
47
+ };
48
+ this.draw = data => {
49
+ const {
50
+ chart,
51
+ tables,
52
+ globalTheme,
53
+ chartColorTheme
54
+ } = this.props;
55
+ const theme = _constants.CHART_THEME_COLOR[globalTheme];
56
+ const {
57
+ show_legend,
58
+ display_label,
59
+ label_position,
60
+ label_font_size,
61
+ color_theme
62
+ } = chart.config;
63
+ const {
64
+ width: chartWidth,
65
+ height: chartHeight,
66
+ insertPadding,
67
+ rightLegendSpace
68
+ } = this.chartBoundingClientRect;
69
+ this.isInnerLabel = !label_position || label_position === _constants.CHART_LABEL_POSITIONS[0];
70
+ const currentTheme = _utils.BaseUtils.getCurrentTheme(chartColorTheme);
71
+ const useSingleSelectColumnColor = color_theme === _colorRules.SUPPORT_SINGLE_SELECT_THEMES_OPTIONS.SINGLE_SELECT_COLUMN_COLORS;
72
+ const {
73
+ data: newData,
74
+ colorMap,
75
+ total
76
+ } = _utils.BaseUtils.formatPieChartData(data, chart, tables, currentTheme, useSingleSelectColumnColor);
77
+ if (!Array.isArray(newData) || newData.length === 0) return;
78
+
79
+ // Color
80
+ const colorDomain = new Set(data.map(d => d.name));
81
+ const colorRange = Array.from(colorDomain).map(name => colorMap[name === null || name === void 0 ? void 0 : name.trim()]);
82
+ const color = d3.scaleOrdinal().domain(colorDomain).range(colorRange);
83
+
84
+ // Ring and Arc
85
+ const pie = d3.pie().sort(null).value(d => d.value);
86
+ const arcs = pie(data);
87
+ const arc = d3.arc().innerRadius(Math.min(chartWidth, chartHeight) / 2 * 0.7).outerRadius(Math.min(chartWidth, chartHeight) / 2 * 0.5);
88
+
89
+ // Draw Ring
90
+ this.chart.append('g').selectAll().data(arcs).join('path').attr('stroke', 'white').attr('stroke-width', 2).attr('fill', d => color(d.data.name)).attr('d', arc).attr('data-groupName', d => d.data.name).call(g => {
91
+ var _g$node$parentNode;
92
+ const {
93
+ width,
94
+ height
95
+ } = (_g$node$parentNode = g.node().parentNode) === null || _g$node$parentNode === void 0 ? void 0 : _g$node$parentNode.getBoundingClientRect();
96
+ const left = width / 2 + insertPadding;
97
+ const top = height / 2 + insertPadding;
98
+ const offsetX = (chartWidth - (insertPadding + rightLegendSpace) - insertPadding - width) / 2;
99
+ const offsetY = (chartHeight - insertPadding - insertPadding - height) / 2;
100
+ d3.select(g.node().parentNode).attr('transform', "translate(".concat(left + offsetX, ", ").concat(top + offsetY, ")"));
101
+
102
+ // Draw total
103
+ this.setAnnotationTotal(g.node().parentNode, {
104
+ value: total
105
+ });
106
+
107
+ // Draw label
108
+ if (display_label) {
109
+ const labelRadius = this.isInnerLabel ? arc.outerRadius()() * 1.2 : arc.outerRadius()() * 1.65;
110
+ const arcLabel = d3.arc().innerRadius(labelRadius).outerRadius(labelRadius);
111
+ this.chart.append('g').attr('transform', "translate(".concat(left + offsetX, ", ").concat(top + offsetY, ")")).attr('text-anchor', 'middle').selectAll().data(arcs).join('text').attr('class', 'label').attr('transform', d => "translate(".concat(arcLabel.centroid(d), ")")).text(d => {
112
+ const {
113
+ value,
114
+ percent
115
+ } = d.data;
116
+ return this.getLabel(value, percent);
117
+ }).attr('fill', theme.labelColor).attr('font-size', _utils.BaseUtils.getLabelFontSize(label_font_size));
118
+
119
+ // Line
120
+ if (!this.isInnerLabel) {
121
+ const lineRadius = arc.outerRadius()() * 0.7;
122
+ const arcLine = d3.arc().innerRadius(lineRadius).outerRadius(lineRadius);
123
+ this.chart.append('g').attr('transform', "translate(".concat(left + offsetX, ", ").concat(top + offsetY, ")")).selectAll().data(arcs).join('line').attr('transform', d => "translate(".concat(arcLine.centroid(d), ")")).attr('x1', d => arcLine.centroid(d)[0]).attr('y1', d => arcLine.centroid(d)[1]).attr('x2', d => arcLine.centroid(d)[0] * 1.2).attr('y2', d => arcLine.centroid(d)[1] * 1.2).attr('stroke', d => color(d.data.name)).attr('font-size', _utils.BaseUtils.getLabelFontSize(label_font_size));
124
+ }
125
+ }
126
+ }).on('click', (event, rowData) => {
127
+ this.props.toggleRecords(rowData.data);
128
+ }).on('mouseenter', (event, rowData) => {
129
+ this.showTooltip(event, rowData.data, color);
130
+ this.handleAcitveAndInActiveState('inActive', event);
131
+ this.setAnnotationTotal(event.currentTarget.parentNode, {
132
+ name: this.getTooltipName(rowData.data.name),
133
+ value: this.getLabel(rowData.data.value, rowData.data.percent)
134
+ });
135
+ }).on('mousemove', event => {
136
+ this.moveTooltip(event);
137
+ }).on('mouseleave', (event, data) => {
138
+ if (event.relatedTarget.getAttribute('class') === 'label') return;
139
+ this.hiddenTooltip();
140
+ this.handleAcitveAndInActiveState('active', event);
141
+ this.setAnnotationTotal(event.currentTarget.parentNode, {
142
+ value: total
143
+ });
144
+ });
145
+ if (show_legend) {
146
+ this.setLegend({
147
+ legendName: 'name',
148
+ theme,
149
+ legendPosition: 'center-right',
150
+ data,
151
+ colorScale: color
152
+ });
153
+ }
154
+ };
155
+ this.showTooltip = (event, data, colorScale) => {
156
+ const {
157
+ offsetX,
158
+ offsetY
159
+ } = event;
160
+ const {
161
+ value,
162
+ percent
163
+ } = data;
164
+ const newTooltipData = {
165
+ title: false,
166
+ items: [{
167
+ color: colorScale(data.name),
168
+ name: this.getTooltipName(data.name),
169
+ value: this.getLabel(value, percent)
170
+ }]
171
+ };
172
+ this.setState({
173
+ tooltipData: newTooltipData
174
+ });
175
+ this.setState({
176
+ toolTipPosition: {
177
+ offsetX,
178
+ offsetY
179
+ }
180
+ });
181
+ };
182
+ this.moveTooltip = event => {
183
+ const {
184
+ offsetX,
185
+ offsetY
186
+ } = event;
187
+ this.setState({
188
+ toolTipPosition: {
189
+ offsetX,
190
+ offsetY
191
+ }
192
+ });
193
+ };
194
+ this.hiddenTooltip = event => {
195
+ this.setState({
196
+ toolTipPosition: null
197
+ });
198
+ };
199
+ this.handleAcitveAndInActiveState = (state, event) => {
200
+ const allGroup = [event.currentTarget.parentNode];
201
+ const curGroupName = event.currentTarget.getAttribute('data-groupName');
202
+ this.setActiveAndInActiveState(state, allGroup, curGroupName);
203
+ };
204
+ this.getLabel = (val, percent) => {
205
+ const {
206
+ chart,
207
+ summaryColumn
208
+ } = this.props;
209
+ const {
210
+ summary_method,
211
+ display_label,
212
+ label_format
213
+ } = chart.config;
214
+ const value = _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, val, summary_method);
215
+ if (!display_label || !value || !percent) {
216
+ return '';
217
+ }
218
+ switch (label_format) {
219
+ case _constants.CHART_LABEL_FORMATS[0]:
220
+ return percent;
221
+ case _constants.CHART_LABEL_FORMATS[1]:
222
+ return value;
223
+ case _constants.CHART_LABEL_FORMATS[2]:
224
+ return "".concat(value, " (").concat(percent, ")");
225
+ default:
226
+ return percent;
227
+ }
228
+ };
229
+ this.getTooltipName = name => {
230
+ let title = name;
231
+ if (!name || name.trim() === 'undefined' || name.trim() === 'null') {
232
+ title = _intl.default.get('Empty');
233
+ } else if (name === '_Others') {
234
+ title = _intl.default.get('Others');
235
+ }
236
+ return title;
237
+ };
238
+ this.setAnnotationTotal = (wrapper, _ref) => {
239
+ var _d3$select$select, _d3$select$select2;
240
+ let {
241
+ name,
242
+ value
243
+ } = _ref;
244
+ const {
245
+ chart,
246
+ globalTheme,
247
+ summaryColumn
248
+ } = this.props;
249
+ const {
250
+ summary_method
251
+ } = chart.config;
252
+ const theme = _constants.CHART_THEME_COLOR[globalTheme];
253
+ // Clear old annotation
254
+ const oldTitle = (_d3$select$select = d3.select(wrapper).select('.title')) === null || _d3$select$select === void 0 ? void 0 : _d3$select$select.node();
255
+ const oldText = (_d3$select$select2 = d3.select(wrapper).select('.text')) === null || _d3$select$select2 === void 0 ? void 0 : _d3$select$select2.node();
256
+ oldTitle && oldTitle.remove();
257
+ oldText && oldText.remove();
258
+
259
+ // Title
260
+ d3.select(wrapper).append('text').attr('class', 'title').text(name ? name : _intl.default.get('Total')).attr('fill', theme.annotationTitleFontColor).attr('font-size', theme.annotationFontSize).attr('font-weight', 300).attr('pointer-events', 'none').call(g => {
261
+ var _g$node;
262
+ const {
263
+ width
264
+ } = (_g$node = g.node()) === null || _g$node === void 0 ? void 0 : _g$node.getBoundingClientRect();
265
+ g.attr('transform', "translate(".concat(-(width / 2), ", ").concat(-20, ")"));
266
+ });
267
+
268
+ // Text this.getLabel(value, percent)
269
+ d3.select(wrapper).append('text').attr('class', 'text').text(summaryColumn ? _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, value, summary_method) : value).attr('fill', theme.annotationValueFontColor).attr('font-size', theme.annotationFontSize).call(g => {
270
+ var _g$node2;
271
+ const {
272
+ width
273
+ } = (_g$node2 = g.node()) === null || _g$node2 === void 0 ? void 0 : _g$node2.getBoundingClientRect();
274
+ g.attr('transform', "translate(".concat(-(width / 2), ", ", 10, ")"));
275
+ });
276
+ };
277
+ this.chart = null;
278
+ this.state = {
279
+ tooltipData: null,
280
+ toolTipPosition: null
281
+ };
282
+ }
283
+ componentDidMount() {
284
+ this.createChart();
285
+ this.drawChart();
286
+ this.debouncedHandleResize = (0, _lodashEs.debounce)(this.handleResize, 300);
287
+ window.addEventListener('resize', this.debouncedHandleResize);
288
+ }
289
+ componentDidUpdate(prevProps) {
290
+ super.componentDidUpdate(prevProps);
291
+ if (_utils.BaseUtils.shouldChartComponentUpdate(prevProps, this.props)) {
292
+ this.chart.node() && this.chart.node().remove();
293
+ this.createChart();
294
+ this.drawChart();
295
+ }
296
+ }
297
+ componentWillUnmount() {
298
+ this.chart.node() && this.chart.node().remove();
299
+ window.removeEventListener('resize', this.debouncedHandleResize);
300
+ }
301
+ render() {
302
+ const {
303
+ tooltipData,
304
+ toolTipPosition
305
+ } = this.state;
306
+ return /*#__PURE__*/_react.default.createElement("div", {
307
+ ref: ref => this.container = ref,
308
+ className: "sea-chart-container"
309
+ }, /*#__PURE__*/_react.default.createElement(_tooltip.default, {
310
+ tooltipData: tooltipData,
311
+ toolTipPosition: toolTipPosition,
312
+ chart: this.chart
313
+ }));
314
+ }
315
+ }
316
+ Ring.propTypes = {
317
+ canvasStyle: _propTypes.default.object,
318
+ chart: _propTypes.default.object,
319
+ groupbyColumn: _propTypes.default.object,
320
+ summaryColumn: _propTypes.default.object,
321
+ result: _propTypes.default.array,
322
+ tables: _propTypes.default.array,
323
+ globalTheme: _propTypes.default.string,
324
+ chartColorTheme: _propTypes.default.string,
325
+ toggleRecords: _propTypes.default.func,
326
+ customRender: _propTypes.default.func
327
+ };
328
+ var _default = exports.default = Ring;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sea-chart",
3
- "version": "2.0.14",
3
+ "version": "2.0.16",
4
4
  "main": "./dist/index.js",
5
5
  "dependencies": {
6
6
  "@dnd-kit/core": "^6.1.0",