sea-chart 2.0.18 → 2.0.20

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,333 @@
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 _utils = require("../../utils");
17
+ var _intl = _interopRequireDefault(require("../../intl"));
18
+ var _tooltip = _interopRequireDefault(require("../../components/tooltip"));
19
+ var _chartComponent = _interopRequireDefault(require("./chart-component"));
20
+ class Scatter extends _chartComponent.default {
21
+ constructor(props) {
22
+ super(props);
23
+ this.handleResize = () => {
24
+ this.chart.node() && this.chart.node().remove();
25
+ this.createChart();
26
+ this.drawChart();
27
+ };
28
+ this.createChart = () => {
29
+ const {
30
+ chart,
31
+ columnGroupbyColumn
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
+ bottomLegendSpace: columnGroupbyColumn ? 20 : 0
44
+ };
45
+ this.initChart(this.container, chart === null || chart === void 0 ? void 0 : chart.id, initConfig);
46
+ };
47
+ this.drawChart = () => {
48
+ const {
49
+ customRender
50
+ } = this.props;
51
+ let {
52
+ result: data
53
+ } = this.props;
54
+ data = _utils.BaseUtils.formatEmptyName(data, '', _intl.default.get('Empty'));
55
+ if (!Array.isArray(data)) return;
56
+ this.transformStringToNumber(data);
57
+ this.draw(data);
58
+ this.renderAxisLabel(this.props.chart, this.props.tables, this.container);
59
+ (0, _utils.isFunction)(customRender) && customRender(this.chart);
60
+ };
61
+ this.transformStringToNumber = data => {
62
+ data.forEach(item => {
63
+ item.name = Number(item.name);
64
+ item.value = Number(item.value);
65
+ });
66
+ };
67
+ this.getFillColor = data => {
68
+ const {
69
+ chartColorTheme
70
+ } = this.props;
71
+ let currentIdx = 0;
72
+ let colors = _utils.BaseUtils.getCurrentTheme(chartColorTheme).colors;
73
+ const colorMap = data.reduce((acc, cur) => {
74
+ if (cur.groupby && !acc[cur.groupby]) {
75
+ acc[cur.groupby] = colors[currentIdx++ % colors.length];
76
+ }
77
+ return acc;
78
+ }, {});
79
+ return colorMap;
80
+ };
81
+ this.showTooltip = (event, data, selectedXAxisColumn, selectedYAxisColumn) => {
82
+ const {
83
+ groupby,
84
+ name,
85
+ value
86
+ } = data;
87
+ const {
88
+ offsetX,
89
+ offsetY
90
+ } = event;
91
+ const newTooltipData = {
92
+ titleMarkColor: event.currentTarget.getAttribute('fill'),
93
+ title: groupby || groupby === 0 ? groupby : _intl.default.get('Empty'),
94
+ items: [{
95
+ name: selectedXAxisColumn.name,
96
+ value: name
97
+ }, {
98
+ name: selectedYAxisColumn.name,
99
+ value: value
100
+ }]
101
+ };
102
+ this.setState({
103
+ tooltipData: newTooltipData
104
+ });
105
+ this.setState({
106
+ toolTipPosition: {
107
+ offsetX,
108
+ offsetY
109
+ }
110
+ });
111
+ };
112
+ this.moveTooltip = event => {
113
+ const {
114
+ offsetX,
115
+ offsetY
116
+ } = event;
117
+ this.setState({
118
+ toolTipPosition: {
119
+ offsetX,
120
+ offsetY
121
+ }
122
+ });
123
+ };
124
+ this.hiddenTooltip = event => {
125
+ this.setState({
126
+ toolTipPosition: null
127
+ });
128
+ };
129
+ this.handleAcitveAndInActiveState = (state, event) => {
130
+ const {
131
+ globalTheme
132
+ } = this.props;
133
+ const theme = _constants.CHART_THEME_COLOR[globalTheme];
134
+ const contentWrapper = event.currentTarget.parentNode;
135
+
136
+ // Remove old mark line wrapper
137
+ const markLineWrapper = d3.select(contentWrapper).select('.mark-line-wrapper');
138
+ markLineWrapper.node() && markLineWrapper.node().remove();
139
+ if (state === 'inActive') {
140
+ // Remove stroke
141
+ d3.select(event.currentTarget).attr('stroke', '').attr('storke-width', '');
142
+ return;
143
+ }
144
+ if (state === 'active') {
145
+ const {
146
+ width: chartWidth,
147
+ height: chartHeight,
148
+ insertPadding,
149
+ marginTop,
150
+ bottomLegendSpace
151
+ } = this.chartBoundingClientRect;
152
+ const x = Number(event.currentTarget.getAttribute('data-x'));
153
+ const y = Number(event.currentTarget.getAttribute('data-y'));
154
+ const r = Number(event.currentTarget.getAttribute('r'));
155
+
156
+ // Add stroke and shadow
157
+ d3.select(event.currentTarget).attr('stroke', 'white').attr('stroke-width', 1.5).attr('style', 'filter: drop-shadow(0px 0px 1px rgba(0, 0, 0, 0.1));');
158
+ const markLineWrapper = d3.select(contentWrapper).append('g').attr('class', 'mark-line-wrapper');
159
+ // X axis
160
+ if (x - r >= insertPadding) {
161
+ // The length of the line must be a positive number
162
+ markLineWrapper.append('line').attr('x1', insertPadding).attr('y1', y).attr('x2', x - r).attr('y2', y).attr('stroke', theme.XAxisColor);
163
+ }
164
+ if (chartWidth - insertPadding >= x + r) {
165
+ // The length of the line must be a positive number
166
+ markLineWrapper.append('line').attr('x1', x + r).attr('y1', y).attr('x2', chartWidth - insertPadding).attr('y2', y).attr('stroke', theme.XAxisColor);
167
+ }
168
+ // Y axis
169
+ if (y - r >= insertPadding) {
170
+ // The length of the line must be a positive number
171
+ markLineWrapper.append('line').attr('x1', x).attr('y1', insertPadding + marginTop).attr('x2', x).attr('y2', y - r).attr('stroke', theme.XAxisColor);
172
+ }
173
+ if (chartHeight - insertPadding >= y + r) {
174
+ // The length of the line must be a positive number
175
+ markLineWrapper.append('line').attr('x1', x).attr('y1', y + r).attr('x2', x).attr('y2', chartHeight - insertPadding - bottomLegendSpace).attr('stroke', theme.XAxisColor);
176
+ }
177
+ }
178
+ };
179
+ this.draw = data => {
180
+ const {
181
+ chart,
182
+ globalTheme,
183
+ tables,
184
+ chartColorTheme
185
+ } = this.props;
186
+ const theme = _constants.CHART_THEME_COLOR[globalTheme];
187
+ const {
188
+ label_font_size,
189
+ x_axis_column_key,
190
+ y_axis_column_key,
191
+ table_id,
192
+ y_axis_show_value,
193
+ y_axis_max,
194
+ y_axis_min,
195
+ y_axis_auto_range
196
+ } = chart.config;
197
+ const {
198
+ width: chartWidth,
199
+ height: chartHeight,
200
+ insertPadding,
201
+ marginTop,
202
+ bottomLegendSpace
203
+ } = this.chartBoundingClientRect;
204
+ const colorMap = this.getFillColor(data);
205
+ const selectedTable = (0, _dtableUtils.getTableById)(tables, table_id);
206
+ const selectedXAxisColumn = (0, _dtableUtils.getTableColumnByKey)(selectedTable, x_axis_column_key);
207
+ const selectedYAxisColumn = (0, _dtableUtils.getTableColumnByKey)(selectedTable, y_axis_column_key);
208
+
209
+ // Y axis
210
+ 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 - bottomLegendSpace, insertPadding + marginTop]);
211
+ this.chart.append('g').attr('class', 'y-axis-wrapper').attr('transform', "translate(".concat(insertPadding, ", 0)")).call(d3.axisLeft(y).tickSizeInner(0).ticks(5).tickFormat(d => d)).call(g => this.drawYaxis(g, theme));
212
+
213
+ // X axis
214
+ const niceEnd = d3.nice(0, d3.max(data, d => d.name), 5)[1];
215
+ const x = d3.scaleLinear().domain([0, niceEnd]).range([insertPadding + this.horizontalOverflowOffset, chartWidth - insertPadding]);
216
+ this.chart.append('g').attr('class', 'x-axis-wrapper').attr('transform', "translate(0, ".concat(chartHeight - insertPadding - bottomLegendSpace, ")")).call(d3.axisBottom(x).tickSizeOuter(0).tickSizeInner(5).ticks(5).tickFormat(d => d)).call(g => {
217
+ g.selectAll('.domain').attr('stroke', theme.XAxisColor);
218
+ g.selectAll('.tick line').attr('stroke', theme.XAxisColor);
219
+ g.selectAll('text').attr('font-size', theme.fontSize);
220
+ g.selectAll('text').attr('fill', theme.textColor);
221
+ const allLineNode = g.selectAll('line').nodes();
222
+ if (Array.isArray(allLineNode)) {
223
+ // delete the first line and last line
224
+ allLineNode[0] && allLineNode[0].remove();
225
+ allLineNode[allLineNode.length - 1] && allLineNode[allLineNode.length - 1].remove();
226
+ }
227
+ this.checkTickOverlap(g);
228
+ });
229
+
230
+ // Circle
231
+ const contentWrapper = this.chart.append('g').attr('class', 'content-wrapper');
232
+ contentWrapper.selectAll().data(data).join('circle').attr('fill', d => {
233
+ const {
234
+ groupby
235
+ } = d;
236
+ if (groupby && groupby[0] === 'groupby') {
237
+ return _utils.BaseUtils.getCurrentTheme(chartColorTheme).colors[0];
238
+ }
239
+ return colorMap[d.groupby];
240
+ }).attr('data-x', d => x(d.name)).attr('data-y', d => y(d.value)).attr('data-value', d => d.value).attr('data-width', 3.5).attr('data-groupName', d => d.name).attr('cx', d => x(d.name)).attr('cy', d => y(d.value)).attr('r', 3.5).attr('opacity', 0.85).call(g => {
241
+ g.nodes().forEach(path => {
242
+ // Add label
243
+ if (y_axis_show_value) {
244
+ this.addLabelToRectTop({
245
+ container: contentWrapper.node(),
246
+ xWidth: Number(path.dataset.width),
247
+ x: Number(path.dataset.x),
248
+ y: Number(path.dataset.y),
249
+ theme,
250
+ label_font_size,
251
+ text: path.dataset.value
252
+ });
253
+ }
254
+ });
255
+ }).on('click', (event, data) => {
256
+ this.props.toggleRecords(data);
257
+ }).on('mouseover', (event, data) => {
258
+ this.showTooltip(event, data, selectedXAxisColumn, selectedYAxisColumn);
259
+ this.handleAcitveAndInActiveState('active', event);
260
+ }).on('mousemove', (event, data) => {
261
+ this.moveTooltip(event, data, selectedXAxisColumn, selectedYAxisColumn);
262
+ }).on('mouseleave', (event, data) => {
263
+ this.hiddenTooltip();
264
+ this.handleAcitveAndInActiveState('inActive', event);
265
+ });
266
+ this.setLegend({
267
+ legendName: 'groupby',
268
+ theme,
269
+ legendPosition: 'top-right',
270
+ data,
271
+ groupColumn: this.props.columnGroupbyColumn,
272
+ chart,
273
+ colorScale: key => colorMap[key]
274
+ });
275
+ };
276
+ this.chart = null;
277
+ this.state = {
278
+ tooltipData: null,
279
+ toolTipPosition: null
280
+ };
281
+ }
282
+ componentDidMount() {
283
+ this.createChart();
284
+ this.drawChart();
285
+ this.debouncedHandleResize = (0, _lodashEs.debounce)(this.handleResize, 300);
286
+ window.addEventListener('resize', this.debouncedHandleResize);
287
+ }
288
+ componentDidUpdate(prevProps) {
289
+ super.componentDidUpdate(prevProps);
290
+ if (_utils.BaseUtils.shouldChartComponentUpdate(prevProps, this.props)) {
291
+ this.createChart();
292
+ this.drawChart();
293
+ }
294
+ }
295
+ componentWillUnmount() {
296
+ this.chart.node() && this.chart.node().remove();
297
+ window.removeEventListener('resize', this.debouncedHandleResize);
298
+ }
299
+ render() {
300
+ const {
301
+ chart
302
+ } = this.props;
303
+ const {
304
+ tooltipData,
305
+ toolTipPosition
306
+ } = this.state;
307
+ return /*#__PURE__*/_react.default.createElement("div", {
308
+ ref: ref => this.container = ref,
309
+ className: (0, _classnames.default)('sea-chart-container', {
310
+ 'show-x-axis-label': this.isShowXAxisLabel(chart),
311
+ 'show-y-axis-label': this.isShowYAxisLabel(chart)
312
+ })
313
+ }, /*#__PURE__*/_react.default.createElement(_tooltip.default, {
314
+ tooltipData: tooltipData,
315
+ toolTipPosition: toolTipPosition,
316
+ chart: this.chart
317
+ }));
318
+ }
319
+ }
320
+ Scatter.propTypes = {
321
+ canvasStyle: _propTypes.default.object,
322
+ chart: _propTypes.default.object,
323
+ groupbyColumn: _propTypes.default.object,
324
+ columnGroupbyColumn: _propTypes.default.object,
325
+ summaryColumn: _propTypes.default.object,
326
+ result: _propTypes.default.array,
327
+ tables: _propTypes.default.array,
328
+ globalTheme: _propTypes.default.string,
329
+ chartColorTheme: _propTypes.default.string,
330
+ toggleRecords: _propTypes.default.func,
331
+ customRender: _propTypes.default.func
332
+ };
333
+ var _default = exports.default = Scatter;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sea-chart",
3
- "version": "2.0.18",
3
+ "version": "2.0.20",
4
4
  "main": "./dist/index.js",
5
5
  "dependencies": {
6
6
  "@dnd-kit/core": "^6.1.0",