使用Vue3和Echarts?5繪制帶有立體感流線中國地圖(推薦收藏!)
本文繪制的地圖效果圖如下:
一、Echarts 使用五部曲
1、下載并引入 echarts
Echarts 已更新到了 5.0 版本,安裝完記得檢查下自己的版本是否是 5.0 。
npm install echarts --save
下載地圖的 json 數(shù)據(jù)
可以下載中國以及各個省份地圖數(shù)據(jù)。免費(fèi)的文件下載地址:
http://datav.aliyun.com/portal/school/atlas/area_selector#&lat=30.332329214580188&lng=106.72278672066881&zoom=3.5
記得收藏哦!免得浪費(fèi)加班時間。
引入:
import * as echarts from "echarts" import chinaJSON from '../../assets/json/china.json'
2、準(zhǔn)備容器
給元素定義寬高確定的容器用來裝地圖。
<template> <div id="chinaMap"></div> </template>
3、實(shí)例化 echarts 對象
import * as echarts from 'echarts' import chinaJson from '../../assets/json/china.json' var myChart = echarts.init(document.getElementById('chinaMap')) // 創(chuàng)建了一個 myChart 對象
4、指定配置項(xiàng)和數(shù)據(jù)
var option = { // 存放需要繪制圖片類型,以及樣式設(shè)置 }
5、給 echarts 對象設(shè)置配置項(xiàng)
myChart.setOption(option)
就這么簡單幾步還用你告訴我嗎?不瞞你說,官網(wǎng)也有這東東。雖然這些你都知道,但是并不影響你還是不知道流線圖是怎么繪制出來的。下面我們看看是如何繪制的。
二、開始繪制流線中國地圖
第一步:先繪制一個中國地圖
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, //設(shè)置中心點(diǎn) center: [105.194115019531, 35.582111640625], map: 'china', roam: true, //是否允許縮放,拖拽 zoom: 1, //初始化大小 //縮放大小限制 scaleLimit: { min: 0.1, //最小 max: 12, //最大 }, //各個省份模塊樣式設(shè)置 itemStyle: { normal: { areaColor: '#3352c7',//背景色 color: 'red',//字體顏色 borderColor: '#5e84fd', borderWidth: 2, }, }, //高亮狀態(tài) emphasis: { itemStyle: { areaColor: '#ffc601', }, label: { show: true, color: '#fff', }, }, // 顯示層級 z: 10, }, } myChart.setOption(option) }
一個簡單的地圖就繪制好了,繼續(xù)研究如何添加流線。
第二步:添加流線
通過 series 屬性來設(shè)置發(fā)色點(diǎn)的樣式,接受點(diǎn)的樣式,以及線條和線條上的動畫。
設(shè)置 series 的值:
// 中國地理坐標(biāo)圖 var chinaGeoCoordMap: Object = { 西安: [108.906866, 34.162109], 拉薩: [91.140856, 29.645554], } //發(fā)射點(diǎn) var chinaDatas = [ [ { name: '拉薩', value: 2, }, ], ] //投射點(diǎn) const scatterPos = [108.906866, 34.162109] // 數(shù)據(jù)轉(zhuǎn)換 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( //設(shè)置指向箭頭信息 { type: 'lines', zlevel: 2, effect: { show: true, period: 4, //箭頭指向速度,值越小速度越快 trailLength: 0.02, //特效尾跡長度[0,1]值越大,尾跡越長重 symbol: 'arrow', //箭頭圖標(biāo) symbolSize: 8, //圖標(biāo)大小 }, lineStyle: { normal: { color: '#adffd0', width: 1, //尾跡線條寬度 opacity: 1, //尾跡線條透明度 curveness: 0.3, //尾跡線條曲直度 }, }, data: convertData(item[1]), }, // 發(fā)射點(diǎn)位置漣漪等效果 { type: 'effectScatter', coordinateSystem: 'geo', zlevel: 2, rippleEffect: { //漣漪特效 period: 4, //動畫時間,值越小速度越快 brushType: 'stroke', //波紋繪制方式 stroke, fill scale: 4, //波紋圓環(huán)最大限制,值越大波紋越大 }, label: { normal: { show: true, position: 'right', //顯示位置 offset: [5, 0], //偏移設(shè)置 formatter: function (params) { //圓環(huán)顯示文字 return params.data.name }, fontSize: 13, }, emphasis: { show: true, }, }, symbol: 'circle', symbolSize: function (val: Array<any>) { return 5 + val[2] * 5 //圓環(huán)大小 }, 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]), } }), }, //被攻擊點(diǎn) { type: 'effectScatter', coordinateSystem: 'geo', zlevel: 2, rippleEffect: { //漣漪相關(guān) period: 2, brushType: 'stroke', scale: 5, }, label: { normal: { show: true, position: 'right', color: '#0f0', formatter: '', 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 屬性。
第三步:添加立體投影
添加立體投影的時候,由于并沒有這樣的屬性,所以需要通過設(shè)置邊框投影,再加一個偏移。
實(shí)現(xiàn)原理:繪制兩個地圖,設(shè)置中心點(diǎn)是一樣的,然后一個設(shè)置邊框投影+偏移,它的層級設(shè)置小一點(diǎn),上邊再繪制一個地圖不設(shè)置投影,這樣就能夠?qū)崿F(xiàn)上述效果。
// 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 ************************************/ //中國地理坐標(biāo)圖 var chinaGeoCoordMap: Object = { 西安: [108.906866, 34.162109], 柯橋區(qū): [120.476075, 30.078038], 拉薩: [91.140856, 29.645554], 沈陽: [123.431474, 41.805698], 新疆: [87.627704, 43.793026], 臺灣: [121.508903, 25.044319], } var chinaDatas = [ [ { name: '柯橋區(qū)', value: 0, }, ], [ { name: '拉薩', value: 2, }, ], [ { name: '沈陽', value: 1, }, ], [ { name: '新疆', value: 1, }, ], [ { name: '臺灣', value: 1, }, ], ] //設(shè)置投射點(diǎn) 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, }, }, }, //設(shè)置指向箭頭信息 { type: 'lines', zlevel: 2, effect: { show: true, period: 4, //箭頭指向速度,值越小速度越快 trailLength: 0.02, //特效尾跡長度[0,1]值越大,尾跡越長重 symbol: 'arrow', //箭頭圖標(biāo) symbolSize: 8, //圖標(biāo)大小 }, lineStyle: { normal: { color: '#adffd0', width: 1, //尾跡線條寬度 opacity: 1, //尾跡線條透明度 curveness: 0.3, //尾跡線條曲直度 }, }, data: convertData(item[1]), }, // 發(fā)射點(diǎn)位置漣漪等效果 { type: 'effectScatter', coordinateSystem: 'geo', zlevel: 2, rippleEffect: { //漣漪特效 period: 4, //動畫時間,值越小速度越快 brushType: 'stroke', //波紋繪制方式 stroke, fill scale: 4, //波紋圓環(huán)最大限制,值越大波紋越大 }, label: { normal: { show: true, position: 'right', //顯示位置 offset: [5, 0], //偏移設(shè)置 formatter: function (params) { //圓環(huán)顯示文字 return params.data.name }, fontSize: 13, }, emphasis: { show: true, }, }, symbol: 'circle', symbolSize: function (val: Array<any>) { return 5 + val[2] * 5 //圓環(huán)大小 }, 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]), } }), }, //被攻擊點(diǎn) { type: 'effectScatter', coordinateSystem: 'geo', zlevel: 2, rippleEffect: { //漣漪相關(guān) period: 2, brushType: 'stroke', scale: 5, }, label: { normal: { show: true, position: 'right', // offset:[5, 0], color: '#0f0', formatter: '', 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) { //根據(jù)業(yè)務(wù)自己拓展要顯示的內(nèi)容 var res = '' var name = params.name var value = params.value[params.seriesIndex + 1] res = "<span style='color:#fff;'>" + name + '</span> 數(shù)據(jù):' + value return res }, }, geo: { show: true, center: [105.194115019531, 35.582111640625], map: 'china', roam: true, //是否允許縮放,拖拽 zoom: 1, //初始化大小 //縮放大小限制 scaleLimit: { min: 0.1, //最小 max: 12, //最大 }, //設(shè)置中心點(diǎn) //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, }, //高亮狀態(tài) emphasis: { itemStyle: { areaColor: '#ffc601', }, label: { show: true, color: '#fff', }, }, z: 10, }, //配置屬性 series: series, } myChart.setOption(option) } </script>
總結(jié)
到此這篇關(guān)于使用Vue3和Echarts 5繪制帶有立體感流線中國地圖的文章就介紹到這了,更多相關(guān)Vue3 Echarts5繪制中國地圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue項(xiàng)目實(shí)現(xiàn)圖片上傳功能
這篇文章主要為大家詳細(xì)介紹了vue項(xiàng)目實(shí)現(xiàn)圖片上傳功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-12-12使用vue.js實(shí)現(xiàn)checkbox的全選和多個的刪除功能
這篇文章主要介紹了使用vue.js實(shí)現(xiàn)checkbox的全選和多個的刪除功能,需要的朋友可以參考下2017-02-02Vue項(xiàng)目中使用WebUploader實(shí)現(xiàn)文件上傳的方法
WebUploader是由 Baidu WebFE(FEX) 團(tuán)隊(duì)開發(fā)的一個簡單的以 HTML5為主 , FLASH為輔 的現(xiàn)代 文件上傳組件 。這篇文章主要介紹了在Vue項(xiàng)目中使用WebUploader實(shí)現(xiàn)文件上傳,需要的朋友可以參考下2019-07-07vue學(xué)習(xí)筆記之slot插槽用法實(shí)例分析
這篇文章主要介紹了vue學(xué)習(xí)筆記之slot插槽用法,結(jié)合實(shí)例形式對比分析了vue使用slot插槽的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2020-02-02vue如何使用router.meta.keepAlive對頁面進(jìn)行緩存
這篇文章主要介紹了vue如何使用router.meta.keepAlive對頁面進(jìn)行緩存問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05