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.
- package/dist/components/color-popover/color-rules/rule-filters/index.css +2 -2
- package/dist/components/color-popover/color-rules-popover.css +1 -1
- package/dist/settings/stacks-settings/index.css +1 -1
- package/dist/settings/widgets/summary-method-setting.js +1 -1
- package/dist/view/wrapper/area.js +4 -2
- package/dist/view/wrapper/index.js +2 -1
- package/dist/view/wrapper/world-map.js +378 -341
- package/package.json +1 -1
|
@@ -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: #
|
|
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: #
|
|
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: #
|
|
140
|
+
color: #555555;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
.statistic-btn-add-color-rule-filter.disabled:hover .popover-add-icon,
|
|
@@ -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 {
|
|
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
|
-
|
|
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,400 @@
|
|
|
1
|
-
import
|
|
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
|
|
5
|
-
import {
|
|
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 {
|
|
9
|
+
import { getMapCanvasStyle } from '../../utils';
|
|
10
10
|
import { COLOR_OPTIONS } from '../../constants/color-rules';
|
|
11
|
-
import { CHART_SUMMARY_TYPE, MAP_LEVEL, CHART_TYPE,
|
|
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
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
-
|
|
132
|
-
|
|
287
|
+
align: legendDirection === 'vertical' ? 'right' : 'bottom',
|
|
288
|
+
formatter: value => {
|
|
289
|
+
return mapGetNumberDisplayString(value, columnData, summary_method);
|
|
133
290
|
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const
|
|
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
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
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
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
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;
|