本文以echarts展示成都地图为例子。
获取所需地址的json数据
注意:目前成都市geojson数据没有新增的几大区(高新区,天府新区,东部新区),若需要可以在博士的资源下载,或者关注一波,私信可免费获得。
npm install echarts
注意:Echarts版本号超过4.9就不能使用地图软件了,所以需要先卸载高版本再安装
// 卸载echarts运行:
npm uninstall echarts
// 安装4.9版本的echarts
npm install echarts@4.9.0 --save
//vue3+ts
<div ref="centerChartmap" ></div>
//其他
<div id="centerChartmap" ></div>
import {ref,onMounted,markRaw,defineEmits} from "vue";
import * as echarts from "echarts";
import arrMap from "./map.json"; //地图json数据
const emit = defineEmits(["clickChild"]); //地图点击后传入父组件点击数据
let chartInstance = ref();// 初始化图表对象
onMounted(() => {
initChart(); // 图表初始化
});
const initChart = () => {
// 定义实例 vue3用ref定义echarts要使用markRaw 后文有解释
chartInstance.value =markRaw(echarts.init(centerChartmap.value, "myTheme"));
//或chartInstance.value=echarts.init(document.getElementById('centerChartmap')
echarts.registerMap("china", { geoJSON: arrMap });
//注册可用的地图并添加geojson数据,只在 geo组件或者 map 图表类型中使用。
let optionMap = {
geo: {
map: "china",
roam: true,
center: [ 103.909956,30.775001], //定义中心点
layoutSize: "100%",
selectedMode: "single",
regions: [ //隐藏南海诸岛
{
name: "南海诸岛",
itemStyle: {
// 隐藏地图
normal: {
opacity: 0, // 为 0 时不绘制该图形
},
},
label: {
show: false, // 隐藏文字
},
},
],
zoom: 12,
//点击后颜色样式设置
select: {
itemStyle: {
borderWidth: 2.5,
areaColor: "rgb(8, 207, 221)",
shadowColor: "rgba(255, 255, 255, 0.3)",
shadowBlur: 10,
shadowOffsetX: 4,
shadowOffsetY: 4,
},
},
//图形上的文本标签,可用于说明图形的一些数据信息
label: {
normal: {
show: true,
fontSize: "10",
color: "#fff",
},
},
//地图区域的多边形 图形样式,有 normal 和 emphasis 两个状态
itemStyle: {
//normal 是图形在默认状态下的样式;
normal: {
areaColor: "rgb(5,66,200,0.8)",
borderColor: "#26e3ff", //线
},
//emphasis 是图形在高亮状态下的样式,比如在鼠标悬浮或者图例联动高亮时。
emphasis: {
areaColor: "#26e3ff",
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowBlur: 20,
borderWidth: 0,
shadowColor: "rgba(0, 0, 0, 0.5)",
},
},
},
colorBy: "series",
series: [
{
name: "信息量",
type: "map",
mapType: "china",
geoIndex: 0,
data: [], //可设置初始选中值[{ name: '武侯区', selected: true }],
},
],
};
chartInstance.value.setOption(optionMap);
chartInstance.value.on("click", function (params) {
//将点击的区域数据传递给父组件
emit("clickChild", params.name);
});
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘type‘)
你可以有选择地退出默认的深度响应式/只读转换模式,并将原始的,未被代理的对象嵌入状态图中。它们可以根据情况灵活运用:
有些值不应该是响应式的,例如复杂的第三方类实例或 Vue 组件对象。(第三方实例)
当渲染具有不可变数据源的大列表时,跳过 proxy 转换可以提高性能。
在实例化echart时,将其指定为非响应式的
import { markRaw } from 'vue'
chartInstance.value = markRaw(echarts.init(centerChartmap.value, "myTheme"));
toRaw | markRaw |
---|---|
将一个由reactive生成的响应式对象转为普通对象。 | 标记一个对象,使其永远不会再成为响应式对象。 |
用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。 | 有些值不应被设置为响应式的,例如复杂的第三方类库等。当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。 |
let optionMap = {
...
geo: {
...
regions: [
{
name: "南海诸岛",
itemStyle: {
normal: {
opacity: 0, // 为 0 时不绘制该图形
},
},
label: {
show: false, // 隐藏文字
},
},
],
...
},
...
}
let optionMap = {
...
// 提示浮窗样式
tooltip: {
show: true,
trigger: "item", //坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用
axisPointer: {
// 坐标轴指示器,坐标轴触发有效
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
},
alwaysShowContent: false,
backgroundColor: "rgba(36, 215, 209, 1)", //提示框背景色
borderColor: "rgba(255, 255, 255, 1)",
triggerOn: "mousemove",
enterable: true, //鼠标是否可进入提示框浮层中
textStyle: {
fontSize: "12",
overflow: "break",
},
formatter: function (params) {
//提示框显示的内容
let str = "";
str = ` ` + params.name + ``;
return str;
},
},
...
}
下钻简而言之,在地图的点击事件回调中,加载了另一份地图的json并注册地图,然后再setOption中更改了地图名字,可以前端保存json数据,但最好还是后端返回,点击时前端请求比较好。
chartInstance.value.on("click", function (params) {
...
if (params.componentSubType == 'map') {
goDown(params.name,optionMap)
}
});
const goDown=(name,optionMap)=>{
if (!echarts.getMap(name)) {
const newMapJson = echarts.registerMap(name, { geoJSON: import('./map/'+name+'.json')})
optionMap.geo.map = mapname
optionMap.series[0].map = mapname
chartInstance.value.setOption(optionMap);
}
}
与下钻一个意思,不过回钻是往回走,我们只要把每一次地图的显示存入一个数组,回钻时取最后一个就行了。
//用来存放当前的地图名字
let currentName =ref('')
//用来存放下钻的历史记录
let history =ref([])
...
chartInstance.value.on("click", function (params) {
...
if (params.componentSubType == 'map') {
goDown(params.name,optionMap)
}
});
const goDown=(name,optionMap)=>{
if (!echarts.getMap(name)) {
const newMapJson = echarts.registerMap(name, { geoJSON: import('./map/'+name+'.json')})
optionMap.geo.map = mapname
optionMap.series[0].map = mapname
history.push(currentName) //点击时存入
chartInstance.value.setOption(optionMap);
currentName = name
}
}
const returnUpLevel=(optionMap)=>{
//先判断history有没有数据,能不能返回
if(history.length == 0){
return false
}
//取出要返回的那个名字
const name = history.pop() //pop删除数组最后一个元素并返回该元素。
const currentJson = echarts.getMap(mapname).geoJson
//修改地图配置重新绘制地图
//因为之前地图是已经绘制了的,只是把后面的遮盖了,所以数据是存在的,我们不需要在重新设置数据源了
optionMap.geo.map = mapname
optionMap.series[0].map = mapname
chart.setOption(optionMap)
//修改当前的层级,名字
currentName = name
}