Vue3 + Echarts 5 绘制带有立体感流线中国地图,建议收藏

vue

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

 

一、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、准备容器

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

<template>

<div id="chinaMap"></div>

</template>

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)

 

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

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

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

 

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<any> = []

;[['西安', 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<any>) {

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,

},

},

}

上述效果的完整源码:

<template>

<div>

首页

<div

ref="chinaMap"

class="chinaMap"

style="

height: 800px;

border: solid 1px red;

width: 100%;

background: #0b0873;

"

>

地图1

</div>

</div>

</template>

<style scoped>

.chinaMap {

transform: rotate3d(1, 0, 0, 35deg);

}

</style>

<script lang="ts" setup>

import * as echarts from 'echarts'

import chinaJson from '../../assets/json/china.json'

import { onMounted, ref } from 'vue'

const chinaMap = ref()

onMounted(() => {

drawChina()

})

/**************************** series start ************************************/

//中国地理坐标图

var chinaGeoCoordMap: Object = {

西安: [108.906866, 34.162109],

柯桥区: [120.476075, 30.078038],

拉萨: [91.140856, 29.645554],

沈阳: [123.431474, 41.805698],

新疆: [87.627704, 43.793026],

台湾: [121.508903, 25.044319],

}

var chinaDatas = [

[

{

name: '柯桥区',

value: 0,

},

],

[

{

name: '拉萨',

value: 2,

},

],

[

{

name: '沈阳',

value: 1,

},

],

[

{

name: '新疆',

value: 1,

},

],

[

{

name: '台湾',

value: 1,

},

],

]

//设置投射点

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,

},

])

}

}

console.log('res', res)

return res

}

var series: Array<any> = []

;[['西安', chinaDatas]].forEach(function (item, i) {

console.log(item, item[0])

series.push(

{

//绘制一个新地图

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,

},

},

},

//设置指向箭头信息

{

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<any>) {

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',

// offset:[5, 0],

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]),

},

],

},

)

})

/****************************************************************/

function drawChina() {

var myChart = echarts.init(chinaMap.value)

echarts.registerMap('china', chinaJson) //注册可用的地图

var option = {

tooltip: {

trigger: 'item',

backgroundColor: 'rgba(166, 200, 76, 0.82)',

borderColor: '#FFFFCC',

showDelay: 0,

hideDelay: 0,

enterable: true,

transitionDuration: 0,

extraCssText: 'z-index:100',

formatter: function (params, ticket, callback) {

//根据业务自己拓展要显示的内容

var res = ''

var name = params.name

var value = params.value[params.seriesIndex + 1]

res = "<span style='color:#fff;'>" + name + '</span><br/>数据:' + value

return res

},

},

geo: {

show: true,

center: [105.194115019531, 35.582111640625],

map: 'china',

roam: true, //是否允许缩放,拖拽

zoom: 1, //初始化大小

//缩放大小限制

scaleLimit: {

min: 0.1, //最小

max: 12, //最大

},

//设置中心点

//center: [95.97, 29.71],

//省份地图添加背景

//regions: regions,

itemStyle: {

normal: {

areaColor: '#3352c7',

color: 'red',

borderColor: '#5e84fd',

borderWidth: 2,

},

},

label: {

color: 'rgba(255,255,255,0.5)',

show: false,

},

//高亮状态

emphasis: {

itemStyle: {

areaColor: '#ffc601',

},

label: {

show: true,

color: '#fff',

},

},

z: 10,

},

//配置属性

series: series,

}

myChart.setOption(option)

}

</script>

以上是 Vue3 + Echarts 5 绘制带有立体感流线中国地图,建议收藏 的全部内容, 来源链接: utcz.com/z/381043.html

回到顶部