sea-chart 0.0.97 → 0.0.98

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.
@@ -2,7 +2,7 @@ import _DTableSelect from "dtable-ui-component/lib/DTableSelect";
2
2
  import React, { Component } from 'react';
3
3
  import { FormGroup, Label } from 'reactstrap';
4
4
  import shallowEqual from 'shallowequal';
5
- import { CHART_TYPE, CHART_SUMMARY_CALCULATION_METHOD, CHART_SUMMARY_SHOW, CHART_DATE_SUMMARY_CALCULATION_METHOD } from '../../constants';
5
+ import { CHART_SUMMARY_CALCULATION_METHOD, CHART_SUMMARY_SHOW, CHART_DATE_SUMMARY_CALCULATION_METHOD } from '../../constants';
6
6
  import { BaseUtils } from '../../utils';
7
7
  import intl from '../../intl';
8
8
  class SummaryMethodSettings extends Component {
@@ -13,9 +13,11 @@ class Area extends ChartComponent {
13
13
  chart
14
14
  } = this.props;
15
15
  const {
16
- column_groupby_column_key
16
+ column_groupby_column_key,
17
+ column_groupby_multiple_numeric_column
17
18
  } = chart.config;
18
- this.isGroupChart = chart.config.type.includes('group') && column_groupby_column_key;
19
+ const isGroup = column_groupby_multiple_numeric_column || column_groupby_column_key;
20
+ this.isGroupChart = chart.config.type.includes('group') && isGroup;
19
21
  };
20
22
  this.createChart = () => {
21
23
  const {
@@ -1,363 +1,376 @@
1
- import React from 'react';
1
+ import _Loading from "dtable-ui-component/lib/Loading";
2
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
3
  import DataSet from '@antv/data-set/lib/index';
3
- import { getNumberDisplayString } from 'dtable-utils';
4
- import PropTypes from 'prop-types';
5
- import { debounce } from 'lodash-es';
6
- import { Chart } from '@antv/g2';
4
+ import { getNumberDisplayString, getTableById, getTableColumnByKey } from 'dtable-utils';
5
+ import classNames from 'classnames';
6
+ import { Chart } from '../../utils/custom-g2';
7
7
  import intl from '../../intl';
8
8
  import fetchMapJson from '../../services/map-json';
9
- import { BaseUtils, getMapCanvasStyle } from '../../utils';
9
+ import { getMapCanvasStyle } from '../../utils';
10
10
  import { COLOR_OPTIONS } from '../../constants/color-rules';
11
- import { CHART_SUMMARY_TYPE, MAP_LEVEL, CHART_TYPE, TITLE_AMOUNT, DEFAULT_NUMBER_FORMAT_OBJECT } from '../../constants';
11
+ import { CHART_SUMMARY_TYPE, MAP_LEVEL, CHART_TYPE, DEFAULT_NUMBER_FORMAT_OBJECT, THEME_NAME_MAP, CHART_THEME_COLOR } from '../../constants';
12
12
  import context from '../../context';
13
- import ChartComponent from './chart-component';
14
- const WIDTH = 798;
15
- const HEIGHT = 394;
16
- class WorldMap extends ChartComponent {
17
- constructor(props) {
18
- super(props);
19
- this.handleResize = () => {
20
- const container = this.container;
21
- const {
22
- width,
23
- height
24
- } = getMapCanvasStyle(container, 2.1);
25
- this.chart && this.chart.changeSize(width, height);
26
- };
27
- this.queryMapJson = async () => {
28
- const mediaUrl = context.getSetting('mediaUrl');
29
- try {
30
- const mapJson = await fetchMapJson(MAP_LEVEL.WORLD, '', mediaUrl);
31
- this.geoData = mapJson;
32
- this.geoData.features.forEach(item => {
33
- this.countryMap.set(item.properties.name, item.properties.name_cn);
34
- this.countryMap.set(item.properties.name_cn, item.properties.name);
13
+ const reg = /^([A-Za-z])/;
14
+ const fixData = (statisticData, countryMap, chartType) => {
15
+ if (!statisticData) return [];
16
+ let statisticNewData = [];
17
+ let sum = 0;
18
+ statisticData.forEach(item => {
19
+ if (item && item.name) {
20
+ let nameType, name, name_cn;
21
+ if (reg.test(item.name)) {
22
+ nameType = 'en';
23
+ name = item.name;
24
+ name_cn = countryMap.get(name);
25
+ } else {
26
+ nameType = 'zh-cn';
27
+ name = countryMap.get(item.name);
28
+ name_cn = item.name;
29
+ }
30
+ const value = item.value;
31
+ if (name_cn && name) {
32
+ statisticNewData.push({
33
+ name_cn,
34
+ name,
35
+ nameType,
36
+ value: value || 0,
37
+ formatted_value: item.formatted_value
35
38
  });
36
- } catch (error) {
37
- console.error(error);
38
- } finally {
39
- this.mapFormattedData = this.fixData(this.props.result);
40
- this.createChart();
41
- this.drawChart();
39
+ if (chartType === CHART_TYPE.WORLD_MAP_BUBBLE) {
40
+ sum += item.value;
41
+ }
42
42
  }
43
- };
44
- this.fixData = statisticData => {
45
- if (!statisticData) return [];
46
- let statisticNewData = [];
47
- let sum = 0;
48
- const {
49
- config
50
- } = this.props.chart;
51
- const type = config.type;
52
- statisticData.forEach(item => {
53
- if (item && item.name) {
54
- let nameType, name, name_cn;
55
- if (this.reg.test(item.name)) {
56
- nameType = 'en';
57
- name = item.name;
58
- name_cn = this.countryMap.get(name);
59
- } else {
60
- nameType = 'zh-cn';
61
- name = this.countryMap.get(item.name);
62
- name_cn = item.name;
63
- }
64
- const value = item.value;
65
- if (name_cn && name) {
66
- statisticNewData.push({
67
- name_cn,
68
- name,
69
- nameType,
70
- value: value || 0,
71
- formatted_value: item.formatted_value
72
- });
73
- if (type === CHART_TYPE.WORLD_MAP_BUBBLE) {
74
- sum += item.value;
75
- }
76
- }
43
+ }
44
+ });
45
+ if (chartType === CHART_TYPE.WORLD_MAP_BUBBLE) {
46
+ statisticNewData.sum = sum;
47
+ }
48
+ return statisticNewData;
49
+ };
50
+ const CHART_STYLE_CONFIG = {
51
+ 'g2-tooltip': {
52
+ borderRadius: '2px',
53
+ backgroundColor: '#fff',
54
+ padding: '10px'
55
+ },
56
+ 'tooltip-item': {
57
+ marginTop: '5px'
58
+ }
59
+ };
60
+ const getDefaultChartStyleByKey = key => {
61
+ return CHART_STYLE_CONFIG[key] || {};
62
+ };
63
+ function createChart(container) {
64
+ // width / height = 1.5 for chinese map
65
+ const {
66
+ width,
67
+ height
68
+ } = getMapCanvasStyle(container, 2.1);
69
+ let config = {
70
+ container: container,
71
+ width,
72
+ height
73
+ };
74
+ return new Chart(config);
75
+ }
76
+ function initChart(currentChart, props) {
77
+ currentChart.tooltip({
78
+ showTitle: false,
79
+ showMarkers: false,
80
+ shared: true,
81
+ containerTpl: '<div class="g2-tooltip"><div class="g2-tooltip-list"></div></div>',
82
+ itemTpl: '<div class="g2-tooltip-content"><div class="tooltip-name">{name}<div><div class="tooltip-item">数量: {value}<div></div>',
83
+ domStyles: {
84
+ 'g2-tooltip': getDefaultChartStyleByKey('g2-tooltip'),
85
+ 'tooltip-item': getDefaultChartStyleByKey('tooltip-item')
86
+ }
87
+ });
88
+ currentChart.scale({
89
+ longitude: {
90
+ sync: true
91
+ },
92
+ latitude: {
93
+ sync: true
94
+ }
95
+ });
96
+ currentChart.axis(false);
97
+ }
98
+ function mapGetNumberDisplayString(value, columnData, summaryMethod) {
99
+ if (summaryMethod === CHART_SUMMARY_TYPE.Distinct_values) {
100
+ return value;
101
+ }
102
+ return getNumberDisplayString(value, columnData);
103
+ }
104
+ function getThemeColors() {
105
+ let themeColors = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
106
+ let theme = arguments.length > 1 ? arguments[1] : undefined;
107
+ // dark->custom->light
108
+ if (theme === THEME_NAME_MAP.DARK) {
109
+ themeColors = CHART_THEME_COLOR.dark;
110
+ }
111
+ return themeColors || CHART_THEME_COLOR[THEME_NAME_MAP.LIGHT];
112
+ }
113
+ function WorldMap(props) {
114
+ const {
115
+ result: statisticData,
116
+ chart
117
+ } = props;
118
+
119
+ // mapLocation is initially set to null, in this case mapLevel is country, so doesn't here
120
+ const {
121
+ // map_location: mapLocation,
122
+ // map_level: mapLevel = MAP_LEVEL.COUNTRY,
123
+ type,
124
+ data_color,
125
+ bubble_color,
126
+ legend_size,
127
+ legend_direction,
128
+ summary_type,
129
+ summary_column_key,
130
+ summary_method,
131
+ table_id
132
+ } = chart.config;
133
+ const chartRef = useRef(null);
134
+ const chartContainerRef = useRef(null);
135
+ const dataSetRef = useRef(null);
136
+ const [isLoading, setIsLoading] = useState(true);
137
+ const [mapData, setMapData] = useState(null);
138
+ const renderCommonChart = useCallback(function (statisticNewData) {
139
+ const currentDataSet = dataSetRef.current;
140
+ const currentChart = chartRef.current;
141
+ const userDataView = currentDataSet.getView('statisticViewModel').source(statisticNewData).transform({
142
+ geoDataView: currentDataSet.getView('mapDataModel'),
143
+ field: 'name',
144
+ type: 'geo.region',
145
+ as: ['longitude', 'latitude']
146
+ });
147
+ const currentColorOption = COLOR_OPTIONS.filter(item => item.name === data_color)[0] || COLOR_OPTIONS[0];
148
+ const {
149
+ exampleColors,
150
+ highlightedBorderColor
151
+ } = currentColorOption;
152
+ let columnData = DEFAULT_NUMBER_FORMAT_OBJECT;
153
+ if (summary_type === CHART_SUMMARY_TYPE.ADVANCED) {
154
+ const table = getTableById(table_id);
155
+ const summaryColumn = getTableColumnByKey(table, summary_column_key) || {};
156
+ columnData = summaryColumn.data || DEFAULT_NUMBER_FORMAT_OBJECT;
157
+ }
158
+ const statisticView = currentChart.createView();
159
+ statisticView.data(userDataView.rows);
160
+ statisticView.polygon().position('longitude*latitude').color('value', "".concat(exampleColors[0], "-").concat(exampleColors[4], "-").concat(exampleColors[8])).style({
161
+ lineWidth: 1,
162
+ stroke: '#bdbdbd',
163
+ strokeOpacity: 0.5
164
+ }).state({
165
+ active: {
166
+ style: {
167
+ lineWidth: 1,
168
+ stroke: highlightedBorderColor
77
169
  }
78
- });
79
- if (type === CHART_TYPE.WORLD_MAP_BUBBLE) {
80
- statisticNewData.sum = sum;
81
170
  }
82
- return statisticNewData;
83
- };
84
- this.initChart = container => {
85
- const {
86
- width,
87
- height
88
- } = getMapCanvasStyle(container, 2.1);
89
- let config = {
90
- container: container,
91
- width,
92
- height
171
+ }).tooltip('name*formatted_value*color*nameType*name_cn', (name, value, color, nameType, name_cn) => {
172
+ return {
173
+ name: nameType === 'en' ? name : name_cn,
174
+ color,
175
+ value
93
176
  };
94
- this.chart = new Chart(config);
95
- };
96
- this.createChart = () => {
97
- this.initChart(this.container);
98
- this.chart.on('element:click', e => {
99
- const {
100
- result
101
- } = this.props;
102
- const lang = intl.lang;
103
- const data = e.data.data;
104
- const countryName = lang === 'zh-cn' ? data.name_cn : data.name;
105
- const clickData = result.find(i => i.name === countryName);
106
- if (clickData) {
107
- this.props.toggleRecords(clickData);
177
+ });
178
+ const themeColors = getThemeColors();
179
+ const legendDirection = legend_direction || 'vertical';
180
+ const size = legend_size || 1;
181
+ chartRef.current.legend({
182
+ layout: legendDirection,
183
+ position: legendDirection === 'vertical' ? 'left-bottom' : 'bottom-left',
184
+ rail: {
185
+ type: 'color',
186
+ defaultLength: 100 * size
187
+ },
188
+ label: {
189
+ spacing: 2,
190
+ style: {
191
+ fill: themeColors.textColor,
192
+ stroke: '#fff',
193
+ lineWidth: 1
194
+ },
195
+ align: legendDirection === 'vertical' ? 'right' : 'bottom',
196
+ formatter: value => {
197
+ return mapGetNumberDisplayString(value, columnData, summary_method);
108
198
  }
109
- });
110
- this.chart.tooltip({
111
- showTitle: false,
112
- showMarkers: false,
113
- shared: true,
114
- containerTpl: '<div class="g2-tooltip"><div class="g2-tooltip-list"></div></div>',
115
- itemTpl: "<div class=\"g2-tooltip-content\"><div class=\"tooltip-name\">{name}<div><div class=\"tooltip-item\">".concat(intl.get(TITLE_AMOUNT), " : {value}<div></div>"),
116
- domStyles: {
117
- 'g2-tooltip': {
118
- borderRadius: '2px',
119
- backgroundColor: '#fff',
120
- padding: '10px'
121
- },
122
- 'tooltip-item': {
123
- marginTop: '5px'
124
- }
199
+ },
200
+ slidable: false
201
+ });
202
+ statisticView.interaction('element-active');
203
+ statisticView.render();
204
+ return statisticView;
205
+ }, [data_color, legend_direction, legend_size, summary_column_key, summary_method, summary_type, table_id]);
206
+ const renderBubbleChart = useCallback(function (statisticNewData) {
207
+ const currentDataSet = dataSetRef.current;
208
+ const currentChart = chartRef.current;
209
+ const userDv = currentDataSet.createView().source(statisticNewData).transform({
210
+ geoDataView: currentDataSet.getView('mapDataModel'),
211
+ field: 'name',
212
+ type: 'geo.centroid',
213
+ as: ['longitude', 'latitude']
214
+ });
215
+ let columnData = DEFAULT_NUMBER_FORMAT_OBJECT;
216
+ if (summary_type === CHART_SUMMARY_TYPE.ADVANCED) {
217
+ const table = getTableById(table_id);
218
+ const summaryColumn = getTableColumnByKey(table, summary_column_key) || {};
219
+ columnData = summaryColumn.data || DEFAULT_NUMBER_FORMAT_OBJECT;
220
+ }
221
+ const statisticView = currentChart.createView();
222
+ statisticView.data(userDv.rows);
223
+ currentChart.theme({
224
+ defaultColor: bubble_color || '#2a67d1'
225
+ });
226
+ statisticView.point().position('longitude*latitude').size('value', value => {
227
+ const percent = value / statisticNewData.sum;
228
+ let size = percent * 100;
229
+ return size;
230
+ }).shape('circle').color(bubble_color || '#2a67d1').tooltip('name*formatted_value*color*nameType*name_cn', (name, value, color, nameType, name_cn) => {
231
+ return {
232
+ name: nameType === 'en' ? name : name_cn,
233
+ color,
234
+ value
235
+ };
236
+ }).style({
237
+ fillOpacity: 0.6,
238
+ stroke: bubble_color || '#2a67d1'
239
+ }).state({
240
+ active: {
241
+ style: {
242
+ lineWidth: 1,
243
+ stroke: bubble_color || '#2a67d1',
244
+ fillOpacity: 0.9
125
245
  }
126
- });
127
- this.chart.scale({
128
- longitude: {
129
- sync: true
246
+ }
247
+ });
248
+ const themeColors = getThemeColors();
249
+ const legendDirection = legend_direction || 'vertical';
250
+ const size = legend_size || 1;
251
+ currentChart.legend({
252
+ layout: legendDirection,
253
+ position: legendDirection === 'vertical' ? 'left-bottom' : 'bottom-left',
254
+ rail: {
255
+ type: 'size',
256
+ defaultLength: 100 * size
257
+ },
258
+ label: {
259
+ style: {
260
+ fill: themeColors.textColor
261
+ // fill: data_color
130
262
  },
131
- latitude: {
132
- sync: true
263
+ align: legendDirection === 'vertical' ? 'right' : 'bottom',
264
+ formatter: value => {
265
+ return mapGetNumberDisplayString(value, columnData, summary_method);
133
266
  }
134
- });
135
- this.chart.axis(false);
136
- this.dataSet = new DataSet();
137
- if (!this.geoData) return;
138
-
139
- // transform map data
140
- const mapData = this.dataSet.createView('mapDataModel').source(this.geoData, {
141
- type: 'GeoJSON'
142
- });
143
- const mapView = this.chart.createView();
144
-
145
- // draw background map
146
- mapView.data(mapData.rows);
147
- mapView.tooltip(false);
148
- mapView.polygon().position('longitude*latitude').style({
149
- fill: '#e2e2e2',
150
- stroke: '#bdbdbd',
151
- lineWidth: 1
152
- });
153
- this.dataSet.createView('statisticViewModel');
154
- mapView.render();
155
- };
156
- this.drawChart = () => {
267
+ },
268
+ slidable: false
269
+ });
270
+ statisticView.interaction('element-active');
271
+ statisticView.render();
272
+ return statisticView;
273
+ }, [bubble_color, legend_direction, legend_size, summary_column_key, summary_method, summary_type, table_id]);
274
+ useEffect(() => {
275
+ const handleResize = () => {
276
+ const container = chartContainerRef.current;
157
277
  const {
158
- chart
159
- } = this.props;
160
- this.loadData(this.mapFormattedData);
161
- if (this.mapFormattedData.length === 0) {
162
- this.chart.legend(false);
163
- this.chart.render();
164
- return;
165
- }
166
- const type = chart.config.type;
167
- if (!type.includes('bubble')) {
168
- this.renderCommonMap(this.mapFormattedData);
169
- } else {
170
- this.renderBubbleMap(this.mapFormattedData);
171
- }
278
+ width,
279
+ height
280
+ } = getMapCanvasStyle(container, 2.1);
281
+ chartRef.current.changeSize(width, height);
172
282
  };
173
- this.renderCommonMap = data => {
174
- const {
175
- chart,
176
- summaryColumn
177
- } = this.props;
178
- const userDataView = this.dataSet.getView('statisticViewModel').source(data).transform({
179
- geoDataView: this.dataSet.getView('mapDataModel'),
180
- field: 'name',
181
- type: 'geo.region',
182
- as: ['longitude', 'latitude']
183
- });
184
- const {
185
- data_color,
186
- summary_type
187
- } = chart.config;
188
- const currentColorOption = COLOR_OPTIONS.filter(item => item.name === data_color)[0] || COLOR_OPTIONS[0];
189
- const {
190
- exampleColors,
191
- highlightedBorderColor
192
- } = currentColorOption;
193
- let summaryColumnData = DEFAULT_NUMBER_FORMAT_OBJECT;
194
- if (summary_type === CHART_SUMMARY_TYPE.ADVANCED) {
195
- summaryColumnData = summaryColumn.data || DEFAULT_NUMBER_FORMAT_OBJECT;
196
- }
197
- this.statisticView = this.chart.createView();
198
- this.statisticView.data(userDataView.rows);
199
- this.statisticView.polygon().position('longitude*latitude').color('value', "".concat(exampleColors[0], "-").concat(exampleColors[4], "-").concat(exampleColors[8])).style({
200
- lineWidth: 1,
201
- stroke: '#bdbdbd',
202
- strokeOpacity: 0.5
203
- }).state({
204
- active: {
205
- style: {
206
- lineWidth: 1,
207
- stroke: highlightedBorderColor
208
- }
209
- }
210
- }).tooltip('name*formatted_value*color*nameType*name_cn', (name, value, color, nameType, name_cn) => {
211
- return {
212
- name: nameType === 'en' ? name : name_cn,
213
- color,
214
- value
215
- };
216
- });
217
- const themeColors = this.getThemeColors();
218
- const legendDirection = chart.config.legend_direction || 'vertical';
219
- const size = chart.config.legend_size || 1;
220
- this.chart.legend({
221
- layout: legendDirection,
222
- position: legendDirection === 'vertical' ? 'left-bottom' : 'bottom-left',
223
- rail: {
224
- type: 'color',
225
- defaultLength: 100 * size
226
- },
227
- label: {
228
- spacing: 2,
229
- style: {
230
- fill: themeColors.textColor,
231
- stroke: '#fff',
232
- lineWidth: 1
233
- },
234
- align: legendDirection === 'vertical' ? 'right' : 'bottom',
235
- formatter: value => {
236
- return getNumberDisplayString(value, summaryColumnData);
237
- }
238
- },
239
- slidable: false
240
- });
241
- this.statisticView.interaction('element-active');
242
- this.statisticView.render();
283
+ window.addEventListener('resize', handleResize);
284
+ return () => {
285
+ window.removeEventListener('resize', handleResize);
243
286
  };
244
- this.renderBubbleMap = data => {
245
- const {
246
- chart,
247
- summaryColumn
248
- } = this.props;
249
- const userDv = this.dataSet.createView().source(data).transform({
250
- geoDataView: this.dataSet.getView('mapDataModel'),
251
- field: 'name',
252
- type: 'geo.centroid',
253
- as: ['longitude', 'latitude']
254
- });
255
- const {
256
- bubble_color,
257
- summary_type,
258
- legend_direction,
259
- legend_size
260
- } = chart.config;
261
- let summaryColumnData = DEFAULT_NUMBER_FORMAT_OBJECT;
262
- if (summary_type === CHART_SUMMARY_TYPE.ADVANCED) {
263
- summaryColumnData = summaryColumn.data || DEFAULT_NUMBER_FORMAT_OBJECT;
287
+ }, []);
288
+
289
+ // used to fetch mapJson data
290
+ // only triggered once
291
+ useEffect(() => {
292
+ (async () => {
293
+ try {
294
+ const mediaUrl = context.getSetting('mediaUrl');
295
+ const mapJson = await fetchMapJson(MAP_LEVEL.WORLD, '', mediaUrl);
296
+ setMapData(mapJson);
297
+ setIsLoading(false);
298
+ } catch (error) {
299
+ console.error(error);
300
+ setIsLoading(false);
264
301
  }
265
- this.statisticView = this.chart.createView();
266
- this.statisticView.data(userDv.rows);
267
- this.chart.theme({
268
- defaultColor: bubble_color || '#2a67d1'
269
- });
270
- this.statisticView.point().position('longitude*latitude').size('value', value => {
271
- const percent = value / data.sum;
272
- let size = percent * 100;
273
- return size;
274
- }).shape('circle').color(bubble_color || '#2a67d1').tooltip('name*formatted_value*color', (name, value, color) => {
275
- return {
276
- name,
277
- color,
278
- value
279
- };
280
- }).style({
281
- fillOpacity: 0.6,
282
- stroke: bubble_color || '#2a67d1'
283
- }).state({
284
- active: {
285
- style: {
286
- lineWidth: 1,
287
- stroke: bubble_color || '#2a67d1',
288
- fillOpacity: 0.9
289
- }
290
- }
291
- });
292
- const themeColors = this.getThemeColors();
293
- const legendDirection = legend_direction || 'vertical';
294
- const size = legend_size || 1;
295
- this.chart.legend({
296
- layout: legendDirection,
297
- position: legendDirection === 'vertical' ? 'left-bottom' : 'bottom-left',
298
- rail: {
299
- type: 'size',
300
- defaultLength: 100 * size
301
- },
302
- label: {
303
- style: {
304
- fill: themeColors.textColor
305
- },
306
- align: legendDirection === 'vertical' ? 'right' : 'bottom',
307
- formatter: value => {
308
- return getNumberDisplayString(value, summaryColumnData);
309
- }
310
- },
311
- slidable: false
312
- });
313
- this.statisticView.interaction('element-active');
314
- this.statisticView.render();
315
- };
316
- this.statisticView = null;
317
- this.chart = null;
318
- this.geoData = null;
319
- this.countryMap = new Map();
320
- this.dataSet = null;
321
- this.mapFormattedData = null;
322
- this.reg = /^([A-Za-z])/;
323
- this.state = {
324
- isDataLoaded: false
325
- };
326
- }
327
- componentDidMount() {
328
- this.queryMapJson();
329
- this.debouncedHandleResize = debounce(this.handleResize, 300);
330
- window.addEventListener('resize', this.debouncedHandleResize);
331
- }
332
- componentDidUpdate(prevProps) {
333
- if (BaseUtils.shouldChartComponentUpdate(prevProps, this.props)) {
334
- this.chart && this.chart.destroy();
335
- this.createChart();
336
- this.drawChart();
302
+ })();
303
+ }, []);
304
+
305
+ // used to init map background
306
+ // if no statistics data, then render empty map
307
+ useEffect(() => {
308
+ if (!chartRef.current) {
309
+ chartRef.current = createChart(chartContainerRef.current);
337
310
  }
338
- }
339
- componentWillUnmount() {
340
- this.chart && this.chart.destroy();
341
- window.removeEventListener('resize', this.debouncedHandleResize);
342
- }
343
- render() {
344
- return /*#__PURE__*/React.createElement("div", {
345
- className: "sea-chart-container",
346
- style: {
347
- display: 'flex',
348
- justifyContent: 'center',
349
- alignItems: 'center'
350
- },
351
- ref: ref => this.container = ref
311
+ // triggered after mapData is set
312
+ if (!mapData) return;
313
+ const currentChart = chartRef.current;
314
+ initChart(currentChart, props);
315
+ const dataSet = new DataSet();
316
+ dataSetRef.current = dataSet;
317
+ // transform map data
318
+ const data = dataSet.createView('mapDataModel').source(mapData, {
319
+ type: 'GeoJSON'
352
320
  });
353
- }
321
+ const mapView = currentChart.createView();
322
+ // // draw background map
323
+ mapView.data(data.rows);
324
+ mapView.tooltip(false);
325
+ mapView.polygon().position('longitude*latitude').style({
326
+ fill: '#e2e2e2',
327
+ stroke: '#bdbdbd',
328
+ lineWidth: 1
329
+ });
330
+ dataSet.createView('statisticViewModel');
331
+ mapView.render();
332
+ return () => {
333
+ currentChart.destroy();
334
+ };
335
+ },
336
+ // eslint-disable-next-line react-hooks/exhaustive-deps
337
+ [mapData]);
338
+ useEffect(() => {
339
+ const currentChart = chartRef.current;
340
+ // need mapData and statisticData to render
341
+ if (!Array.isArray(statisticData) || !mapData) return;
342
+ const countryMap = new Map();
343
+ mapData.features.forEach(item => {
344
+ countryMap.set(item.properties.name, item.properties.name_cn);
345
+ countryMap.set(item.properties.name_cn, item.properties.name);
346
+ });
347
+ const mapFormattedData = fixData(statisticData, countryMap, type);
348
+ if (mapFormattedData.length === 0) {
349
+ currentChart.legend(false);
350
+ currentChart.render();
351
+ return;
352
+ }
353
+ let currentView;
354
+ if (type.includes('bubble')) {
355
+ currentView = renderBubbleChart(mapFormattedData);
356
+ } else {
357
+ currentView = renderCommonChart(mapFormattedData);
358
+ }
359
+ currentChart.render();
360
+ return () => {
361
+ currentView && currentView.destroy();
362
+ };
363
+ }, [statisticData, mapData, type, renderCommonChart, renderBubbleChart]);
364
+ return /*#__PURE__*/React.createElement(React.Fragment, null, isLoading && /*#__PURE__*/React.createElement("div", {
365
+ className: 'statistic-chart-loading-container'
366
+ }, /*#__PURE__*/React.createElement(_Loading, null)), /*#__PURE__*/React.createElement("div", {
367
+ className: classNames('sea-chart-container '),
368
+ style: {
369
+ display: 'flex',
370
+ justifyContent: 'center',
371
+ alignItems: 'center'
372
+ },
373
+ ref: chartContainerRef
374
+ }));
354
375
  }
355
- WorldMap.propTypes = {
356
- chart: PropTypes.object,
357
- summaryColumn: PropTypes.object,
358
- result: PropTypes.array,
359
- tables: PropTypes.array,
360
- theme: PropTypes.object,
361
- toggleRecords: PropTypes.func
362
- };
363
376
  export default WorldMap;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sea-chart",
3
- "version": "0.0.97",
3
+ "version": "0.0.98",
4
4
  "main": "./dist/index.js",
5
5
  "dependencies": {
6
6
  "@antv/data-set": "0.11.8",