sea-chart 0.0.97 → 0.0.99

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.
@@ -155,7 +155,7 @@
155
155
  .statistic-color-rule-filters .delete-filter .dtable-icon-fork-number {
156
156
  display: inline-block;
157
157
  font-size: 12px;
158
- color: #949494;
158
+ color: #999999;
159
159
  }
160
160
 
161
161
  .statistic-color-rule-filters .popover-add-tool {
@@ -173,7 +173,7 @@
173
173
  }
174
174
 
175
175
  .statistic-color-rule-filters .filter-item .dtable-icon-fork-number:hover {
176
- color: #5a5a5a;
176
+ color: #555555;
177
177
  }
178
178
 
179
179
  .statistic-color-rule-filters .filter-container-readonly .selected-option-show,
@@ -137,7 +137,7 @@
137
137
  .statistic-delete-color-rule:hover .dtable-font,
138
138
  .statistic-btn-add-color-rule-filter:hover .popover-add-icon,
139
139
  .statistic-btn-add-color-rule-filter:hover .add-new-option {
140
- color: #5a5a5a;
140
+ color: #555555;
141
141
  }
142
142
 
143
143
  .statistic-btn-add-color-rule-filter.disabled:hover .popover-add-icon,
@@ -68,5 +68,5 @@
68
68
  }
69
69
 
70
70
  .sea-chart-settings .sea-chart-y-axis-title .dtable-icon-fork-number:hover {
71
- color: #212529;
71
+ color: #555555;
72
72
  }
@@ -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 {
@@ -77,7 +77,8 @@ const Wrapper = _ref => {
77
77
  summaryColumnsWithMethod,
78
78
  globalTheme,
79
79
  chartColorTheme,
80
- toggleRecords: toggleStatisticRecordsDialog
80
+ toggleRecords: toggleStatisticRecordsDialog,
81
+ isCalculateByView
81
82
  };
82
83
  switch (type) {
83
84
  case CHART_TYPE.TABLE:
@@ -1,363 +1,400 @@
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
+ const {
78
+ result,
79
+ toggleRecords,
80
+ isCalculateByView
81
+ } = props;
82
+ if (isCalculateByView) {
83
+ currentChart.on('element:click', e => {
84
+ const lang = intl.lang;
85
+ const data = e.data.data;
86
+ const countryName = lang === 'zh-cn' ? data.name_cn : data.name;
87
+ const clickData = result.find(i => i.name === countryName);
88
+ if (clickData) {
89
+ toggleRecords(clickData);
90
+ }
91
+ });
92
+ }
93
+ currentChart.tooltip({
94
+ showTitle: false,
95
+ showMarkers: false,
96
+ shared: true,
97
+ containerTpl: '<div class="g2-tooltip"><div class="g2-tooltip-list"></div></div>',
98
+ itemTpl: '<div class="g2-tooltip-content"><div class="tooltip-name">{name}<div><div class="tooltip-item">数量: {value}<div></div>',
99
+ domStyles: {
100
+ 'g2-tooltip': getDefaultChartStyleByKey('g2-tooltip'),
101
+ 'tooltip-item': getDefaultChartStyleByKey('tooltip-item')
102
+ }
103
+ });
104
+ currentChart.scale({
105
+ longitude: {
106
+ sync: true
107
+ },
108
+ latitude: {
109
+ sync: true
110
+ }
111
+ });
112
+ currentChart.axis(false);
113
+ }
114
+ function mapGetNumberDisplayString(value, columnData, summaryMethod) {
115
+ if (summaryMethod === CHART_SUMMARY_TYPE.Distinct_values) {
116
+ return value;
117
+ }
118
+ return getNumberDisplayString(value, columnData);
119
+ }
120
+ function getThemeColors() {
121
+ let themeColors = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
122
+ let theme = arguments.length > 1 ? arguments[1] : undefined;
123
+ // dark->custom->light
124
+ if (theme === THEME_NAME_MAP.DARK) {
125
+ themeColors = CHART_THEME_COLOR.dark;
126
+ }
127
+ return themeColors || CHART_THEME_COLOR[THEME_NAME_MAP.LIGHT];
128
+ }
129
+ function WorldMap(props) {
130
+ let {
131
+ result: statisticData,
132
+ chart,
133
+ isCalculateByView
134
+ } = props;
135
+ if (isCalculateByView) {
136
+ statisticData = statisticData.map(v => {
137
+ var _v$name;
138
+ v.name = ((_v$name = v.name) === null || _v$name === void 0 ? void 0 : _v$name.country_region) || v.name || '';
139
+ return v;
140
+ });
141
+ }
142
+
143
+ // mapLocation is initially set to null, in this case mapLevel is country, so doesn't here
144
+ const {
145
+ // map_location: mapLocation,
146
+ // map_level: mapLevel = MAP_LEVEL.COUNTRY,
147
+ type,
148
+ data_color,
149
+ bubble_color,
150
+ legend_size,
151
+ legend_direction,
152
+ summary_type,
153
+ summary_column_key,
154
+ summary_method,
155
+ table_id
156
+ } = chart.config;
157
+ const chartRef = useRef(null);
158
+ const chartContainerRef = useRef(null);
159
+ const dataSetRef = useRef(null);
160
+ const [isLoading, setIsLoading] = useState(true);
161
+ const [mapData, setMapData] = useState(null);
162
+ const renderCommonChart = useCallback(function (statisticNewData) {
163
+ const currentDataSet = dataSetRef.current;
164
+ const currentChart = chartRef.current;
165
+ const userDataView = currentDataSet.getView('statisticViewModel').source(statisticNewData).transform({
166
+ geoDataView: currentDataSet.getView('mapDataModel'),
167
+ field: 'name',
168
+ type: 'geo.region',
169
+ as: ['longitude', 'latitude']
170
+ });
171
+ const currentColorOption = COLOR_OPTIONS.filter(item => item.name === data_color)[0] || COLOR_OPTIONS[0];
172
+ const {
173
+ exampleColors,
174
+ highlightedBorderColor
175
+ } = currentColorOption;
176
+ let columnData = DEFAULT_NUMBER_FORMAT_OBJECT;
177
+ if (summary_type === CHART_SUMMARY_TYPE.ADVANCED) {
178
+ const table = getTableById(table_id);
179
+ const summaryColumn = getTableColumnByKey(table, summary_column_key) || {};
180
+ columnData = summaryColumn.data || DEFAULT_NUMBER_FORMAT_OBJECT;
181
+ }
182
+ const statisticView = currentChart.createView();
183
+ statisticView.data(userDataView.rows);
184
+ statisticView.polygon().position('longitude*latitude').color('value', "".concat(exampleColors[0], "-").concat(exampleColors[4], "-").concat(exampleColors[8])).style({
185
+ lineWidth: 1,
186
+ stroke: '#bdbdbd',
187
+ strokeOpacity: 0.5
188
+ }).state({
189
+ active: {
190
+ style: {
191
+ lineWidth: 1,
192
+ stroke: highlightedBorderColor
77
193
  }
78
- });
79
- if (type === CHART_TYPE.WORLD_MAP_BUBBLE) {
80
- statisticNewData.sum = sum;
81
194
  }
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
195
+ }).tooltip('name*formatted_value*color*nameType*name_cn', (name, value, color, nameType, name_cn) => {
196
+ return {
197
+ name: nameType === 'en' ? name : name_cn,
198
+ color,
199
+ value
93
200
  };
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);
201
+ });
202
+ const themeColors = getThemeColors();
203
+ const legendDirection = legend_direction || 'vertical';
204
+ const size = legend_size || 1;
205
+ chartRef.current.legend({
206
+ layout: legendDirection,
207
+ position: legendDirection === 'vertical' ? 'left-bottom' : 'bottom-left',
208
+ rail: {
209
+ type: 'color',
210
+ defaultLength: 100 * size
211
+ },
212
+ label: {
213
+ spacing: 2,
214
+ style: {
215
+ fill: themeColors.textColor,
216
+ stroke: '#fff',
217
+ lineWidth: 1
218
+ },
219
+ align: legendDirection === 'vertical' ? 'right' : 'bottom',
220
+ formatter: value => {
221
+ return mapGetNumberDisplayString(value, columnData, summary_method);
108
222
  }
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
- }
223
+ },
224
+ slidable: false
225
+ });
226
+ statisticView.interaction('element-active');
227
+ statisticView.render();
228
+ return statisticView;
229
+ }, [data_color, legend_direction, legend_size, summary_column_key, summary_method, summary_type, table_id]);
230
+ const renderBubbleChart = useCallback(function (statisticNewData) {
231
+ const currentDataSet = dataSetRef.current;
232
+ const currentChart = chartRef.current;
233
+ const userDv = currentDataSet.createView().source(statisticNewData).transform({
234
+ geoDataView: currentDataSet.getView('mapDataModel'),
235
+ field: 'name',
236
+ type: 'geo.centroid',
237
+ as: ['longitude', 'latitude']
238
+ });
239
+ let columnData = DEFAULT_NUMBER_FORMAT_OBJECT;
240
+ if (summary_type === CHART_SUMMARY_TYPE.ADVANCED) {
241
+ const table = getTableById(table_id);
242
+ const summaryColumn = getTableColumnByKey(table, summary_column_key) || {};
243
+ columnData = summaryColumn.data || DEFAULT_NUMBER_FORMAT_OBJECT;
244
+ }
245
+ const statisticView = currentChart.createView();
246
+ statisticView.data(userDv.rows);
247
+ currentChart.theme({
248
+ defaultColor: bubble_color || '#2a67d1'
249
+ });
250
+ statisticView.point().position('longitude*latitude').size('value', value => {
251
+ const percent = value / statisticNewData.sum;
252
+ let size = percent * 100;
253
+ return size;
254
+ }).shape('circle').color(bubble_color || '#2a67d1').tooltip('name*formatted_value*color*nameType*name_cn', (name, value, color, nameType, name_cn) => {
255
+ return {
256
+ name: nameType === 'en' ? name : name_cn,
257
+ color,
258
+ value
259
+ };
260
+ }).style({
261
+ fillOpacity: 0.6,
262
+ stroke: bubble_color || '#2a67d1'
263
+ }).state({
264
+ active: {
265
+ style: {
266
+ lineWidth: 1,
267
+ stroke: bubble_color || '#2a67d1',
268
+ fillOpacity: 0.9
125
269
  }
126
- });
127
- this.chart.scale({
128
- longitude: {
129
- sync: true
270
+ }
271
+ });
272
+ const themeColors = getThemeColors();
273
+ const legendDirection = legend_direction || 'vertical';
274
+ const size = legend_size || 1;
275
+ currentChart.legend({
276
+ layout: legendDirection,
277
+ position: legendDirection === 'vertical' ? 'left-bottom' : 'bottom-left',
278
+ rail: {
279
+ type: 'size',
280
+ defaultLength: 100 * size
281
+ },
282
+ label: {
283
+ style: {
284
+ fill: themeColors.textColor
285
+ // fill: data_color
130
286
  },
131
- latitude: {
132
- sync: true
287
+ align: legendDirection === 'vertical' ? 'right' : 'bottom',
288
+ formatter: value => {
289
+ return mapGetNumberDisplayString(value, columnData, summary_method);
133
290
  }
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 = () => {
291
+ },
292
+ slidable: false
293
+ });
294
+ statisticView.interaction('element-active');
295
+ statisticView.render();
296
+ return statisticView;
297
+ }, [bubble_color, legend_direction, legend_size, summary_column_key, summary_method, summary_type, table_id]);
298
+ useEffect(() => {
299
+ const handleResize = () => {
300
+ const container = chartContainerRef.current;
157
301
  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
- }
302
+ width,
303
+ height
304
+ } = getMapCanvasStyle(container, 2.1);
305
+ chartRef.current.changeSize(width, height);
172
306
  };
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();
307
+ window.addEventListener('resize', handleResize);
308
+ return () => {
309
+ window.removeEventListener('resize', handleResize);
243
310
  };
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;
311
+ }, []);
312
+
313
+ // used to fetch mapJson data
314
+ // only triggered once
315
+ useEffect(() => {
316
+ (async () => {
317
+ try {
318
+ const mediaUrl = context.getSetting('mediaUrl');
319
+ const mapJson = await fetchMapJson(MAP_LEVEL.WORLD, '', mediaUrl);
320
+ setMapData(mapJson);
321
+ setIsLoading(false);
322
+ } catch (error) {
323
+ console.error(error);
324
+ setIsLoading(false);
264
325
  }
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();
326
+ })();
327
+ }, []);
328
+
329
+ // used to init map background
330
+ // if no statistics data, then render empty map
331
+ useEffect(() => {
332
+ if (!chartRef.current) {
333
+ chartRef.current = createChart(chartContainerRef.current);
337
334
  }
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
335
+ // triggered after mapData is set
336
+ if (!mapData) return;
337
+ const currentChart = chartRef.current;
338
+ initChart(currentChart, props);
339
+ const dataSet = new DataSet();
340
+ dataSetRef.current = dataSet;
341
+ // transform map data
342
+ const data = dataSet.createView('mapDataModel').source(mapData, {
343
+ type: 'GeoJSON'
352
344
  });
353
- }
345
+ const mapView = currentChart.createView();
346
+ // // draw background map
347
+ mapView.data(data.rows);
348
+ mapView.tooltip(false);
349
+ mapView.polygon().position('longitude*latitude').style({
350
+ fill: '#e2e2e2',
351
+ stroke: '#bdbdbd',
352
+ lineWidth: 1
353
+ });
354
+ dataSet.createView('statisticViewModel');
355
+ mapView.render();
356
+ return () => {
357
+ currentChart.destroy();
358
+ };
359
+ },
360
+ // eslint-disable-next-line react-hooks/exhaustive-deps
361
+ [mapData]);
362
+ useEffect(() => {
363
+ const currentChart = chartRef.current;
364
+ // need mapData and statisticData to render
365
+ if (!Array.isArray(statisticData) || !mapData) return;
366
+ const countryMap = new Map();
367
+ mapData.features.forEach(item => {
368
+ countryMap.set(item.properties.name, item.properties.name_cn);
369
+ countryMap.set(item.properties.name_cn, item.properties.name);
370
+ });
371
+ const mapFormattedData = fixData(statisticData, countryMap, type);
372
+ if (mapFormattedData.length === 0) {
373
+ currentChart.legend(false);
374
+ currentChart.render();
375
+ return;
376
+ }
377
+ let currentView;
378
+ if (type.includes('bubble')) {
379
+ currentView = renderBubbleChart(mapFormattedData);
380
+ } else {
381
+ currentView = renderCommonChart(mapFormattedData);
382
+ }
383
+ currentChart.render();
384
+ return () => {
385
+ currentView && currentView.destroy();
386
+ };
387
+ }, [statisticData, mapData, type, renderCommonChart, renderBubbleChart]);
388
+ return /*#__PURE__*/React.createElement(React.Fragment, null, isLoading && /*#__PURE__*/React.createElement("div", {
389
+ className: 'statistic-chart-loading-container'
390
+ }, /*#__PURE__*/React.createElement(_Loading, null)), /*#__PURE__*/React.createElement("div", {
391
+ className: classNames('sea-chart-container '),
392
+ style: {
393
+ display: 'flex',
394
+ justifyContent: 'center',
395
+ alignItems: 'center'
396
+ },
397
+ ref: chartContainerRef
398
+ }));
354
399
  }
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
400
  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.99",
4
4
  "main": "./dist/index.js",
5
5
  "dependencies": {
6
6
  "@antv/data-set": "0.11.8",