echarts地图的简单使用
- 文章说明
- 核心源码
- 效果展示
- 源码下载
文章说明
主要介绍echarts地图组件的简单使用,记录为文章,供后续查阅使用
目前只是简单的示例,然后还存在着一些小bug,主要是首个Legend的点击会导致颜色全部不展示的问题,以及世界地图的区域展示有一些小问题,等待后续完善
核心源码
地图绘制组件
<script setup>
import * as echarts from "echarts";
import china from "@/assets/china.json";
import world from "@/assets/world.json";
import {onBeforeMount, onMounted, reactive} from "vue";
import {getAreaList} from "@/assets/getAreaList";
import {calculateColor} from "@/util";
const data = reactive({
mapName: "china",
chinaAreaList: [],
selectedChinaAreaList: [],
worldAreaList: [],
selectedWorldAreaList: [],
});
onBeforeMount(() => {
const {chinaAreaList, worldAreaList} = getAreaList();
data.chinaAreaList = chinaAreaList;
data.worldAreaList = worldAreaList;
});
const mapList = [
{
name: "china",
data: china,
},
{
name: "world",
data: world,
}
];
let myChart;
onMounted(() => {
for (let i = 0; i < mapList.length; i++) {
echarts.registerMap(mapList[i].name, mapList[i].data);
}
const chartDom = document.getElementById("basic-chart");
myChart = echarts.init(chartDom);
setOption();
window.onresize = () => {
myChart.resize();
};
});
const mapNameMap = {
china: "中国地图",
world: "世界地图",
}
let min = 0;
let max = 10000;
let selectedAreaDataList = [];
function setOption() {
let selectedAreaList = [];
if (data.mapName === "china") {
selectedAreaList = data.selectedChinaAreaList;
} else if (data.mapName === "world") {
selectedAreaList = data.selectedWorldAreaList;
}
const series = [];
const colors = [];
const notSortArray = [];
for (let i = 0; i < selectedAreaList.length; i++) {
let selectedAreaData;
for (let j = 0; j < selectedAreaDataList.length; j++) {
if (selectedAreaDataList[j].name === selectedAreaList[i]) {
selectedAreaData = selectedAreaDataList[j];
break;
}
}
let value;
if (selectedAreaData) {
value = selectedAreaData.value;
} else {
value = Math.ceil(Math.random() * max);
selectedAreaDataList.push({
value: value,
name: selectedAreaList[i],
});
}
notSortArray.push({
value: value,
name: selectedAreaList[i],
});
}
notSortArray.sort(function (o1, o2) {
return o1.value - o2.value;
});
if (!notSortArray.length) {
colors.push("#ffffff", "#000000");
}
const legendNames = [];
for (let i = 0; i < notSortArray.length; i++) {
const color = calculateColor(notSortArray[i].value, min, max);
colors.push(color);
const seriesItem = {
name: notSortArray[i].name,
type: 'map',
geoIndex: 0,
data: [
{
name: notSortArray[i].name,
value: notSortArray[i].value
}
],
color: color,
};
series.push(seriesItem);
legendNames.push(notSortArray[i].name);
}
myChart.setOption({
title: {
text: mapNameMap[data.mapName],
left: "center",
},
geo: {
map: data.mapName,
label: {
show: false,
},
},
legend: {
orient: 'vertical',
bottom: "50px",
left: '50px',
itemHeight: 10,
itemWidth: 30,
textStyle: {
fontSize: 12,
rich: {
a: {
verticalAlign: 'middle',
},
},
padding: [2, 0, 0, 0],
},
data: legendNames
},
series: series,
visualMap: {
left: 'right',
min: min,
max: max,
inRange: {
color: colors
},
text: ['High', 'Low'],
calculable: true
},
toolbox: {
show: true,
feature: {
saveAsImage: {
show: true
}
}
},
}, true);
}
</script>
<template>
<div class="container">
<div style="height: 6rem; display: flex; align-items: center; justify-content: center">
<el-select v-model="data.mapName" style="width: 10rem; margin-right: 2rem" @change="setOption">
<el-option label="中国地图" value="china"/>
<el-option label="世界地图" value="world"/>
</el-select>
<el-select v-show="data.mapName === 'china'" v-model="data.selectedChinaAreaList" collapse-tags
collapse-tags-tooltip filterable multiple placeholder="请选择地区" style="width: 30rem"
@change="setOption">
<template v-for="item in data.chinaAreaList" :key="item.id">
<el-option :label="item.name" :value="item.name"/>
</template>
</el-select>
<el-select v-show="data.mapName === 'world'" v-model="data.selectedWorldAreaList" collapse-tags
collapse-tags-tooltip filterable multiple placeholder="请选择地区" style="width: 30rem"
@change="setOption">
<template v-for="item in data.worldAreaList" :key="item.id">
<el-option :label="item.name" :value="item.name"/>
</template>
</el-select>
</div>
<div style="flex: 1">
<div id="basic-chart" class="chart"></div>
</div>
</div>
</template>
<style lang="scss">
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
}
.chart {
width: 100%;
height: 100%;
}
</style>
根据值生成颜色的工具函数
function hsvToRgb(h, s, v) {
const f = n => {
const k = (n + h / 60) % 6;
return v - v * s * Math.max(Math.min(k, 4 - k, 1), 0);
};
return [
Math.round(f(5) * 255),
Math.round(f(3) * 255),
Math.round(f(1) * 255)
];
}
export function calculateColor(value, minValue, maxValue) {
value = Math.max(minValue, Math.min(maxValue, value));
const factor = (value - minValue) / (maxValue - minValue);
const hue = (factor * 360) % 360;
const saturation = 1 - factor;
const valueV = 1;
const [r, g, b] = hsvToRgb(hue, saturation, valueV);
return `rgb(${r}, ${g}, ${b})`;
}
地图数据的下载,可以在该网站下载较为全面的中国地图的数据:DataV.GeoAtlas地理小工具系列
效果展示
中国地图
世界地图
源码下载
echarts地图组件的基本使用