Vue3 + Echarts 5 绘制带有立体感流线中国地图

本文绘制的地图效果图如下:

Vue3 + Echarts 5 绘制带有立体感流线中国地图_第1张图片

一、Echarts 使用五部曲

1、下载并引入 echarts

Echarts 已更新到了 5.0 版本,安装完记得检查下自己的版本是否是 5.0 。

npm install echarts --save

下载地图的 json 数据

可以下载中国以及各个省份地图数据。免费的文件下载地址:

http://datav.aliyun.com/portal/school/atlas/area_selector#&lat=30.332329214580188&lng=106.72278672066881&zoom=3.5

记得收藏哦!免得浪费加班时间。

引入:

import * as echarts from "echarts"
import chinaJSON from '../../assets/json/china.json'

2、准备容器

给元素定义宽高确定的容器用来装地图。

3、实例化 echarts 对象

import * as echarts from 'echarts'
import chinaJson from '../../assets/json/china.json'
var myChart = echarts.init(document.getElementById('chinaMap'))
// 创建了一个 myChart 对象

4、指定配置项和数据

var option = {
 // 存放需要绘制图片类型,以及样式设置
}

5、给 echarts 对象设置配置项

myChart.setOption(option)

Vue3 + Echarts 5 绘制带有立体感流线中国地图_第2张图片

就这么简单几步还用你告诉我吗?不瞒你说,官网也有这东东。虽然这些你都知道,但是并不影响你还是不知道流线图是怎么绘制出来的。下面我们看看是如何绘制的。

二、开始绘制流线中国地图

第一步:先绘制一个中国地图

Vue3 + Echarts 5 绘制带有立体感流线中国地图_第3张图片

import * as echarts from 'echarts'
import chinaJson from '../../assets/json/china.json'
import { onMounted, ref } from 'vue'
const chinaMap = ref()
onMounted(() => {
 drawChina()
})
function drawChina() {
 var myChart = echarts.init(chinaMap.value)
 echarts.registerMap('china', chinaJson) //注册可用的地图
 var option = {
  geo: {
   show: true,
   //设置中心点
   center: [105.194115019531, 35.582111640625],
   map: 'china',
   roam: true, //是否允许缩放,拖拽
   zoom: 1, //初始化大小
   //缩放大小限制
   scaleLimit: {
    min: 0.1, //最小
    max: 12, //最大
   },
   //各个省份模块样式设置
   itemStyle: {
    normal: {
     areaColor: '#3352c7',//背景色
     color: 'red',//字体颜色
     borderColor: '#5e84fd',
     borderWidth: 2,
    },
   },
   //高亮状态
   emphasis: {
    itemStyle: {
     areaColor: '#ffc601',
    },
    label: {
     show: true,
     color: '#fff',
    },
   },
   // 显示层级
   z: 10,
  },
 }
 myChart.setOption(option)
}

一个简单的地图就绘制好了,继续研究如何添加流线。

第二步:添加流线

通过 series 属性来设置发色点的样式,接受点的样式,以及线条和线条上的动画。

设置 series 的值:

// 中国地理坐标图
var chinaGeoCoordMap: Object = {
 西安: [108.906866, 34.162109],
 拉萨: [91.140856, 29.645554],
}
//发射点
var chinaDatas = [
 [
  {
   name: '拉萨',
   value: 2,
  },
 ],
]
//投射点
const scatterPos = [108.906866, 34.162109]
// 数据转换
var convertData = function (data: any) {
 var res = []
 for (var i = 0; i < data.length; i++) {
  var dataItem = data[i]
  var fromCoord = chinaGeoCoordMap[dataItem[0].name]
  var toCoord = scatterPos
  if (fromCoord && toCoord) {
   res.push([
    {
     coord: fromCoord,
     value: dataItem[0].value,
    },
    {
     coord: toCoord,
     },
    ])
  }
 }
 return res
}

var series: Array = []
;[['西安', chinaDatas]].forEach(function (item, i) {
 series.push(
  //设置指向箭头信息
  {
   type: 'lines',
   zlevel: 2,
   effect: {
    show: true,
    period: 4, //箭头指向速度,值越小速度越快
    trailLength: 0.02, //特效尾迹长度[0,1]值越大,尾迹越长重
    symbol: 'arrow', //箭头图标
    symbolSize: 8, //图标大小
   },
   lineStyle: {
    normal: {
     color: '#adffd0',
     width: 1, //尾迹线条宽度
     opacity: 1, //尾迹线条透明度
     curveness: 0.3, //尾迹线条曲直度
    },
   },
   data: convertData(item[1]),
  },
 // 发射点位置涟漪等效果
 {
  type: 'effectScatter',
  coordinateSystem: 'geo',
  zlevel: 2,
  rippleEffect: {
  //涟漪特效
  period: 4, //动画时间,值越小速度越快
  brushType: 'stroke', //波纹绘制方式 stroke, fill
  scale: 4, //波纹圆环最大限制,值越大波纹越大
  },
  label: {
   normal: {
   show: true,
   position: 'right', //显示位置
   offset: [5, 0], //偏移设置
   formatter: function (params) {
    //圆环显示文字
    return params.data.name
   },
   fontSize: 13,
  },
  emphasis: {
   show: true,
  },
 },
 symbol: 'circle',
 symbolSize: function (val: Array) {
  return 5 + val[2] * 5 //圆环大小
 },
 itemStyle: {
 normal: {
  show: false,
  color: '#f8f9f5',
  },
 },
 data: item[1].map(function (dataItem: any) {
  return {
   name: dataItem[0].name,
   value: chinaGeoCoordMap[dataItem[0].name].concat([dataItem[0].value]),
   }
  }),
 },
 //被攻击点
 {
  type: 'effectScatter',
  coordinateSystem: 'geo',
  zlevel: 2,
  rippleEffect: {
   //涟漪相关
   period: 2,
   brushType: 'stroke',
   scale: 5,
   },
  label: {
   normal: {
    show: true,
    position: 'right',
    color: '#0f0',
    formatter: '{b}',
    textStyle: {
     color: '#fff',
     fontSize: 12,
     },
    },
    emphasis: {
     show: true,
     color: '#f60',
    },
   },
   itemStyle: {
    normal: {
    color: '#f00',
   },
  },
  symbol: 'circle',
  symbolSize: 10, //圆圈大小
  data: [
   {
    name: item[0],
    value: chinaGeoCoordMap[item[0]].concat([10]),
    },
   ],
  },
 )
})

给上边的 option 添加 series 属性。

第三步:添加立体投影

添加立体投影的时候,由于并没有这样的属性,所以需要通过设置边框投影,再加一个偏移。

实现原理:绘制两个地图,设置中心点是一样的,然后一个设置边框投影+偏移,它的层级设置小一点,上边再绘制一个地图不设置投影,这样就能够实现上述效果。

// series 添加一个对象,绘制新地图
{
 //绘制一个新地图
 type: 'map',
 map: 'china',
 zoom: 1,
 center: [105.194115019531, 35.582111640625],
 z: -1,
 aspectScale: 0.75, //
 itemStyle: {
  normal: {
   areaColor: '#f00',
   borderColor: '#090438',
   borderWidth: '2',
   shadowColor: '#090438',
   shadowOffsetX: 0,
   shadowOffsetY: 15,
   },
 },
}

上述效果的完整源码:



你可能感兴趣的:(Echarts,echarts,地图)