forked from wuhan2020/WebApp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEChartsMap.tsx
More file actions
149 lines (127 loc) · 4.06 KB
/
EChartsMap.tsx
File metadata and controls
149 lines (127 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import 'echarts-jsx/dist/renderers/SVG';
import 'echarts-jsx/dist/components/geo';
import { DataObject } from 'dom-renderer';
import { EChartsOption, EChartsType, init, registerMap } from 'echarts';
import { observable } from 'mobx';
import { attribute, component, observer,WebCell } from 'web-cell';
import { formatDate } from 'web-utility';
import { getHistory, Province } from '../../../service/Epidemic';
import { long2short } from '../adapter';
export interface EChartsMapProps {
/**
* 地图 JSON 文件地址
*/
mapUrl?: string;
/**
* Echarts 中的所有 options(注意:地图的 map 项值为 'map')
*/
chartOptions?: EChartsOption;
mapName?: string;
/**
* 点击地图后的回调函数
*/
onSeriesClick?: (event: CustomEvent<DataObject>) => any;
/**
* 地图缩放事件回调函数
*/
onChartGeoRoam?: (event: CustomEvent<DataObject>) => any;
onChartLabelAdjust?: (event: CustomEvent<EChartsType>) => any;
}
export interface EChartsMap extends WebCell<EChartsMapProps> {}
/**
* WebCell ECharts 热力图-地图可视化通用组件
*
* 本地图组件为热力图-地图定制化开发提供了最高的自由度
*
* @author shadowingszy
*/
@component({ tagName: 'echarts-map' })
@observer
export class EChartsMap
extends HTMLElement
implements WebCell<EChartsMapProps>
{
@attribute
@observable
accessor mapUrl = '';
@attribute
@observable
accessor mapName = 'map';
@observable
accessor chartOptions: EChartsOption = {};
chart: EChartsType;
mountedCallback() {
this.classList.add('w-100', 'h-100');
this.chart = init(this);
this.listen();
this.loadData();
self.addEventListener('resize', () => {
this.chart.resize();
this.adjustLabel();
});
}
adjustLabel() {
this.emit('chartlabeladjust', this.chart);
}
listen() {
const { chart, chartOptions } = this;
const { data } = chartOptions.baseOption.timeline;
// implement hover-then-click on mobile devices
let hovered = '';
chart
.on('mouseover', 'series', ({ name }) => {
// prevent click event to trigger immediately
setTimeout(() => (hovered = name));
})
.on('mouseout', 'series', () => {
hovered = '';
})
.on('click', 'series', params => {
if (hovered) {
this.emit('seriesclick', params);
hovered = '';
}
})
.on('click', 'timeline', ({ dataIndex }) => {
const formattedDate = formatDate(dataIndex, 'YYYY-MM-DD');
chart.dispatchAction({
type: 'timelineChange',
// index of time point
currentIndex: data.findIndex(d => d === dataIndex)
});
getHistory(formattedDate).then(this.updateChartData);
});
}
async loadData() {
const { chart, mapUrl, mapName, chartOptions } = this;
chart.showLoading();
const data = await (await fetch(mapUrl)).json();
for (const { properties } of data.features)
properties.name = long2short(properties.name);
registerMap(mapName, data);
this.renderChart(chartOptions);
this.adjustLabel();
chart.hideLoading();
}
renderChart(chartOptions: EChartsOption) {
return (
<ec-svg-renderer >
<ec-geo
map={this.mapName}
data={chartOptions.options[0].series[0]?.data}
/>
</ec-svg-renderer>
);
}
updateChartData = (newData: Province[]) =>
this.chart.setOption({
series: [
{
data: newData.map(item => ({
name: item.provinceShortName,
value: item.confirmedCount
}))
}
]
});
}