最近有一個(gè)項(xiàng)目,數(shù)據(jù)看板,里面都是餅形,折線圖,條形圖,還有一個(gè)沒研究過的地圖,因?yàn)槎际怯胑charts實(shí)現(xiàn)的,就研究下如何用echarts實(shí)現(xiàn)
先看看實(shí)現(xiàn)的效果圖

image.png
實(shí)現(xiàn)
- 首先創(chuàng)建容器
<div :id="id" class="o-echarts"></div>
- data里面配置option參數(shù)
option: {
title: { // 設(shè)置標(biāo)題
text: '選擇所要查詢的數(shù)據(jù)維度',
top: '3%',
left: '5%',
textStyle: {
fontSize: 18,
fontWeight: 300,
color: '#b6d7ff'
}
},
tooltip: { // 設(shè)置鼠標(biāo)移上去的彈框顯示效果
padding: 0,
backgroundColor: 'transparent',
formatter: params => {
// params.data
return `<table class="map__tooltip o_font20">
<thead>
<tr>
<th>總購買人數(shù)</th>
<th>本年度總購買人數(shù)</th>
<th>本月度總購買人數(shù)</th>
<th>總完成人數(shù)</th>
</tr>
</thead>
<tbody>
<tr>
<th>${params.data.obj.a}</th>
<th>${params.data.obj.b}</th>
<th>${params.data.obj.c}</th>
<th>${params.data.obj.d}</th>
</tr>
</tbody>
</table>`;
}
},
legend: {
orient: 'vertical',
top: '9%',
left: '5%',
icon: 'circle',
data: [],
selectedMode: 'single',
selected: {},
itemWidth: 12,
itemHeight: 12,
itemGap: 30,
inactiveColor: '#b6d7ff',
textStyle: {
color: '#ec808d',
fontSize: 14,
fontWeight: 300,
padding: [0, 0, 0, 15]
}
},
visualMap: { // 設(shè)置地圖范圍值顯示的顏色
min: 0,
max: 500,
show: false,
splitNumber: 5,
inRange: {
color: ['#FACD91', '#74DFB2', '#81D3F8', '#768FDE', '#e9969f'].reverse()
},
textStyle: {
color: '#fff'
}
},
geo: { // 設(shè)置地圖的顯示信息
map: '重慶', // 注意 哪個(gè)區(qū)域的就顯示哪個(gè)區(qū)域的名稱
label: {
normal: { // 設(shè)置字體相關(guān)信息
show: true,
color: '#000'
},
emphasis: { // 設(shè)置鼠標(biāo)移上去hover效果
show: true,
color: '#fff'
}
},
roam: false,
itemStyle: { // 設(shè)置地圖塊的相關(guān)顯示信息
normal: {
areaColor: '#8db200',
borderColor: '#6367ad',
borderWidth: 1
},
emphasis: {
areaColor: '#feb6aa' // hover效果
}
},
left: '5%',
right: '5%',
top: '5%',
bottom: '5%'
},
series: [{ // 地圖塊的相關(guān)信息
name: '年度總項(xiàng)目數(shù)據(jù)查詢',
type: 'map',
geoIndex: 0, // 不可缺少,否則無tooltip 指示效果
data: []
}]
}
- 引入需要顯示的省區(qū)JSON下載
百度云盤提取碼: 3nyg
import echarts from 'echarts';
import JSON from './chongqing.json';
monuted 初始化并渲染
this.echartObj = echarts.init(document.getElementById(this.id));
echarts.registerMap('重慶', JSON);
- 左上角的按鈕點(diǎn)擊事件
this.echartObj.on('legendselectchanged', params => {
this.radioActive = Object.keys(this.radioList)
.filter(item => this.radioList[item] === params.name)[0];
this.echartObj.clear(); // 清除
this.echartObj.setOption(this.getOptions());
});
- 監(jiān)聽瀏覽器大小變化重渲染組件
window.addEventListener('resize', () => {
if (this.echartObj && this.echartObj.resize) {
this.echartObj.resize();
}
});
methods
- getOptions 方法
getOptions() {
this.setOptions('legend', {
data: Object.values(this.radioList),
selected: (list => {
const obj = {};
Object.keys(list).map((item, index) => {
obj[list[item]] = item === this.radioActive;
});
return obj;
})(this.radioList)
});
this.setOptions('series', (() => {
const arr = [];
Object.values(this.radioList)
.map((item, index) => {
arr[this.radioList[this.radioActive] === item ? 'unshift' : 'push']({
name: item,
type: 'map',
geoIndex: 0, // 不可缺少,否則無tooltip 指示效果
data: this.getSeriesData(item)
});
});
return arr;
})());
return this.option;
}
- getSeriesData 獲取模擬數(shù)據(jù)方法
getSeriesData(item) {
return this.radioList[this.radioActive] === item ? JSON.features.map(item => {
return {
name: item.properties.name,
value: Math.ceil(Math.random() * 500),
obj: {
a: Math.ceil(Math.random() * 500),
b: Math.ceil(Math.random() * 500),
c: Math.ceil(Math.random() * 500),
d: Math.ceil(Math.random() * 500)
}
};
}) : [];
}
- setOptions 設(shè)置option里面的配置信息
setOptions(objKey, objVal) {
if (this.option[objKey] && typeof this.option[objKey] === 'object'
&& !Array.isArray(this.option[objKey])) {
this.option[objKey] = Object.assign(this.option[objKey], objVal);
} else {
this.option[objKey] = objVal;
}
this.$set(this.option, objKey, this.option[objKey]);
}
總體代碼
<style lang="less">
.o-echarts {
min-width: 30px;
min-height: 30px;
width: 100%;
height: 100%;
}
</style>
<template>
<div :id="id" class="o-echarts"></div>
</template>
<script>
import echarts from 'echarts';
import JSON from './chongqing.json';
export default {
name: 'echart-map',
data() {
return {
id: 'echarts_' + new Date().getTime() + Math.floor(Math.random() * 1000),
echartObj: null,
radioList: {
A: '年度總項(xiàng)目數(shù)據(jù)查詢',
B: '軍轉(zhuǎn)干部在崗培訓(xùn)項(xiàng)目',
C: '專技人員公需科目項(xiàng)目',
D: '專技人員新取得中級(jí)職稱崗前培訓(xùn)項(xiàng)目',
E: '事業(yè)單位新進(jìn)人員崗前培訓(xùn)項(xiàng)目'
},
radioActive: 'A',
option: {
title: {
text: '選擇所要查詢的數(shù)據(jù)維度',
top: '3%',
left: '5%',
textStyle: {
fontSize: 18,
fontWeight: 300,
color: '#b6d7ff'
}
},
tooltip: {
padding: 0,
backgroundColor: 'transparent',
formatter: params => {
// params.data
return `<table class="map__tooltip o_font20">
<thead>
<tr>
<th>總購買人數(shù)</th>
<th>本年度總購買人數(shù)</th>
<th>本月度總購買人數(shù)</th>
<th>總完成人數(shù)</th>
</tr>
</thead>
<tbody>
<tr>
<th>${params.data.obj.a}</th>
<th>${params.data.obj.b}</th>
<th>${params.data.obj.c}</th>
<th>${params.data.obj.d}</th>
</tr>
</tbody>
</table>`;
}
},
legend: {
orient: 'vertical',
top: '9%',
left: '5%',
icon: 'circle',
data: [],
selectedMode: 'single',
selected: {},
itemWidth: 12,
itemHeight: 12,
itemGap: 30,
inactiveColor: '#b6d7ff',
textStyle: {
color: '#ec808d',
fontSize: 14,
fontWeight: 300,
padding: [0, 0, 0, 15]
}
},
visualMap: {
min: 0,
max: 500,
show: false,
splitNumber: 5,
inRange: {
color: ['#FACD91', '#74DFB2', '#81D3F8', '#768FDE', '#e9969f'].reverse()
},
textStyle: {
color: '#fff'
}
},
geo: {
map: '重慶',
label: {
normal: {
show: true,
color: '#000'
},
emphasis: {
show: true,
color: '#fff'
}
},
roam: false,
itemStyle: {
normal: {
areaColor: '#8db200',
borderColor: '#6367ad',
borderWidth: 1
},
emphasis: {
areaColor: '#feb6aa' // hover效果
}
},
left: '5%',
right: '5%',
top: '5%',
bottom: '5%'
},
series: [{
name: '年度總項(xiàng)目數(shù)據(jù)查詢',
type: 'map',
geoIndex: 0, // 不可缺少,否則無tooltip 指示效果
data: []
}]
}
};
},
mounted() {
this.echartObj = echarts.init(document.getElementById(this.id));
echarts.registerMap('重慶', JSON);
this.echartObj.setOption(this.getOptions(), true);
this.echartObj.on('legendselectchanged', params => {
this.radioActive = Object.keys(this.radioList).filter(item => this.radioList[item] === params.name)[0];
this.echartObj.clear();
this.echartObj.setOption(this.getOptions());
});
window.addEventListener('resize', () => {
if (this.echartObj && this.echartObj.resize) {
this.echartObj.resize();
}
});
},
methods: {
getOptions() {
this.setOptions('legend', {
data: Object.values(this.radioList),
selected: (list => {
const obj = {};
Object.keys(list).map((item, index) => {
obj[list[item]] = item === this.radioActive;
});
return obj;
})(this.radioList)
});
this.setOptions('series', (() => {
const arr = [];
Object.values(this.radioList)
.map((item, index) => {
arr[this.radioList[this.radioActive] === item ? 'unshift' : 'push']({
name: item,
type: 'map',
geoIndex: 0, // 不可缺少,否則無tooltip 指示效果
data: this.getSeriesData(item)
});
});
return arr;
})());
return this.option;
},
getSeriesData(item) {
return this.radioList[this.radioActive] === item ? JSON.features.map(item => {
return {
name: item.properties.name,
value: Math.ceil(Math.random() * 500),
obj: {
a: Math.ceil(Math.random() * 500),
b: Math.ceil(Math.random() * 500),
c: Math.ceil(Math.random() * 500),
d: Math.ceil(Math.random() * 500)
}
};
}) : [];
},
setOptions(objKey, objVal) {
if (this.option[objKey] && typeof this.option[objKey] === 'object' && !Array.isArray(this.option[objKey])) {
this.option[objKey] = Object.assign(this.option[objKey], objVal);
} else {
this.option[objKey] = objVal;
}
this.$set(this.option, objKey, this.option[objKey]);
}
}
};
</script>