使用 echarts 实现世界地图、中国地图、以及飞线、标牌、3D柱状图绘制 您所在的位置:网站首页 echarts线路图 使用 echarts 实现世界地图、中国地图、以及飞线、标牌、3D柱状图绘制

使用 echarts 实现世界地图、中国地图、以及飞线、标牌、3D柱状图绘制

2023-08-14 10:11| 来源: 网络整理| 查看: 265

一、需求 1. 世界地图效果图

01.png

02.png

在世界地图上实现飞线效果、IP地址显示

2. 中国地图效果图

03.png

在中国地图上实现黄、蓝标牌、 3D 柱状图等,并带有十段线

二、开发说明

echarts v5.0.0+ node v12.0.0+ react class 组件形式

三、开发步骤 引入 echarts npm 下载 npm install echarts 复制代码 cdn 引入 复制代码 开始使用 引入地图资源,注册地图(这里以世界地图为例) import worldJson from "./world.json"; class WorldMap extends Component { ... componentDidMount() { this.createMap(); } createMap = () => { constructor(props) { super(props); this.state = { options: {}, ipOptions: {}, mapChart: null, }; } ... //获取配置数据 const dom = document.getElementById(componentConfig.id); // 保证每个地图唯一 var mapChart = echarts.init(dom); // 初始化 echarts.registerMap("world", worldJson); // 注册地图 this.setState({ options, ipOptions }); // 飞线、IP都存state mapChart.setOption(displayMode === 0 ? options : ipOptions); // 显示方式切换;配置地图选项 this.setState({ mapChart }) }; } 复制代码 配置地图选项 options 地图飞线的配置实现 const options = { radius: '100%', tooltip: { trigger: 'item', }, legend: { orient: 'horizontal', //图例的排列方向 // textStyle: { color: '#1a1e45' }, x: 'left', //图例的位置 y: '-20000000000000', }, visualMap: { //颜色的设置 dataRange // textStyle: { color: '#1a1e45' }, x: 'left', y: 'bottom', // splitList: [{ start: 0, end: 150000 }], show: false, // text:['高','低'],// 文本,默认为数值文本 color: [flyColor], // 组件配置变量 }, geo: { map: 'world', // 此处需与注册地图命名保持一致 type: 'map', zoom: 1.2, label: { normal: { show: false, textStyle: { color: '#FFFFFF', }, }, emphasis: { show: false, }, }, roam: false, //是否允许缩放 itemStyle: { normal: { color: bgColor, //地图背景色,用到组件配置的变量 borderColor: borderColor, //省市边界线 borderWidth: 1, textStyle: '#fff', }, emphasis: { areaColor: selectColor, //悬浮背景 }, }, data: [], }, series: this.getSeries(centerPoint, mainData, flyLineArr, coordData, flyDirection), // 飞线的配置 } //飞线配置 getSeries = (centerPoint, mainData, flyLineArr, coordData, flyDirection) => { let series = []; let centerPointName = Object.keys(centerPoint)[0] || '北京区域中心'; let centerPointValue = Object.values(centerPoint)[0] || [116, 39]; [[centerPointName, flyLineArr]].forEach((item, i) => { series.push( { type: 'lines', coordinateSystem: 'geo', zlevel: 2, effect: { show: true, period: 5, //箭头指向速度,值越小速度越快 trailLength: 0, //特效尾迹长度[0,1]值越大,尾迹越长重 symbol: 'arrow', //箭头图标 symbolSize: 5, //图标大小 color: mainData.iconColor, // 图标颜色 }, lineStyle: { normal: { show: true, width: 1, //尾迹线条宽度 opacity: 1, //尾迹线条透明度 curveness: 0.3, //尾迹线条曲直度 color: mainData.flyColor, // 飞线颜色 - 细线 }, }, data: this.convertData(item[1], coordData, flyDirection, centerPointValue), }, { type: 'effectScatter', radius: '100%', coordinateSystem: 'geo', zlevel: 2, rippleEffect: { //涟漪特效 period: 4, //动画时间,值越小速度越快 brushType: 'stroke', //波纹绘制方式 stroke, fill scale: 3, //波纹圆环最大限制,值越大波纹越大 color: mainData.rippleColor, }, label: { normal: { show: false, position: 'right', //显示位置 offset: [5, 0], //偏移设置 formatter: (params) => { return params.data.name //圆环显示文字 }, fontSize: 13, }, emphasis: { show: false, }, }, symbol: 'circle', symbolSize: (val) => { return 5 //圆环大小 }, itemStyle: { normal: { show: true, // areaColor: mainData.pointColor, // color: mainData.pointColor, areaColor: "#ade9f4", color: "#ade9f4", }, emphasis: { // areaColor: mainData.pointColor, areaColor: "#ade9f4", }, }, data: item[1].map((dataItem) => { return { //在这里定义你所要展示的数据 name: dataItem[0].name, value: coordData[dataItem[0].name]?.concat([dataItem[0].value]), } }), }, //中心点 { type: 'effectScatter', radius: '100%', coordinateSystem: 'geo', zlevel: 15, rippleEffect: { period: 4, brushType: 'stroke', scale: 4, color: '#FFD246', }, label: { normal: { show: false, position: 'right', //offset:[5, 0], color: '#FFD246', formatter: '{b}', textStyle: { color: '#FFD246', }, }, emphasis: { show: false, color: '#FFD246', }, }, symbol: 'circle', symbolSize: 5, itemStyle: { color: '#FFD246', }, data: [ { name: item[0], value: coordData[item[0]]?.concat([10]), }, ], } ) }) return series }; 复制代码 配置 IP 地址显示 const ipOptions = { tooltip: { backgroundColor: "rgba(0,0,0,0)", trigger: "axis", }, legend: { show: false, }, geo: { map: 'world', type: 'map', zoom: 1.2, label: { normal: { show: false, textStyle: { color: '#FFFFFF', }, }, emphasis: { show: false, }, }, roam: false, //是否允许缩放 itemStyle: { normal: { color: bgColor, //地图背景色 borderColor: borderColor, //省市边界线00fcff 516a89 borderWidth: 1, textStyle: '#fff', }, emphasis: { areaColor: selectColor, //悬浮背景 }, }, data: [], }, series: [ { tooltip: { show: false, }, type: "effectScatter", coordinateSystem: "geo", rippleEffect: { scale: 10, brushType: "stroke", }, showEffectOn: "render", itemStyle: { normal: { color: "#00FFFF", //ip 涟漪颜色 }, }, label: { normal: { color: "#fff", }, }, symbol: "circle", // symbolSize: [10, 5], symbolSize: [10, 5], data: this.convertIPData(ipData, ipCoordData), zlevel: 1, }, { type: "scatter", coordinateSystem: "geo", itemStyle: { color: "#00FFF6", // 光标颜色 }, symbol: img.arrow, // symbol: 'arrow', symbolSize: [44, 34], symbolOffset: [0, -10], // symbolRotate: 180, z: 999, data: this.convertIPData(ipData, ipCoordData), }, { type: "scatter", coordinateSystem: "geo", label: { normal: { show: true, formatter: function (params) { let name = params.name; let value = params.value[2]; let text = `{fline|${value}}`; return text; }, color: "#fff", rich: { fline: { padding: [0, 25], color: "#fff", fontSize: 14, fontWeight: 600, }, tline: { padding: [0, 27], color: "#ABF8FF", fontSize: 12, }, }, }, emphasis: { show: true, }, }, itemStyle: { color: "#00FFF6", }, symbol: img.ipbg, // symbol: "roundRect", symbolSize: [125, 32], symbolOffset: [0, -35], z: 999, data: this.convertIPData(ipData, ipCoordData), }, ], }; // IP数据转换 convertIPData = (data, gdGeoCoordMap) => { // 校验 if (!data) { return } let res = []; for (let i = 0; i < data.length; i++) { let geoCoord = gdGeoCoordMap[data[i].name]; if (geoCoord) { res.push({ name: data[i].name, value: geoCoord.concat(data[i].value), }); } } return res; }; 复制代码

至此,即可完成世界地图的基本配置。

四、开发过程问题及解决方案 1.中国地图和世界地图如何配置?

两者在注册地图时切换地图资源即可展现不同的地图效果。

echarts.registerMap("china", chinaJson); echarts.registerMap("world", worldJson); 复制代码

注:中国地图十段线的配置也在地图资源数据内完成。

2.世界地图飞线方向如何控制?

飞线涉及到飞线中心点,飞线方向由coordArr控制,调换coordArr内坐标位置即可改变飞线攻击方向。

注:若需要实现多飞线中心,则需修改地图数据结构。

convertData = (data, coordData, flyDirection, centerPointValue) => { if (!data) { return } //判空 let res = [] for (let i = 0; i < data.length; i++) { let dataItem = data[i] let fromCoord = coordData[dataItem[0].name] let toCoord = centerPointValue //中心点地理坐标 if (fromCoord && toCoord) { let coordArr = [{ coord: fromCoord, // 飞线去往哪里 value: dataItem[0].value, }, { coord: toCoord, // 飞线从哪里出发 }, ]; res.push( flyDirection === 0 ? coordArr : coordArr.reverse() ) // 通过 flyDirection 控制飞线方向 } } return res } 复制代码 3.地图自定义图标如何引入?

echarts 的series方法中的symbol属性可以引入图片路径,一共有三种方法:

链接引入

在symbol中直接引入图片的路径,注意格式,要加image://

{ type: "scatter", coordinateSystem: "geo", label: { ... }, itemStyle: { color: "#00FFF6",}, symbol: "image://http:...", symbolSize: [600, 240], symbolOffset: [360, -150], symbolRotate: 180, z: 999, data: this.convertIPData2(dataCenter, ipCoordData), } 复制代码 base64格式引入

base64格式引入,需要注意base64代码串不能换行

{ type: "scatter", coordinateSystem: "geo", label: { ... }, itemStyle: { color: "#00FFF6",}, symbol: "image://data:image/png;data:image/png;base64,iVBORw...", symbolSize: [600, 240], symbolOffset: [360, -150], symbolRotate: 180, z: 999, data: this.convertIPData2(dataCenter, ipCoordData), } 复制代码 svg图引入

svg图可用notepad++软件或者记事本打开,将属性值复制出来前面加path://即可

{ type: "scatter", coordinateSystem: "geo", label: { ... }, itemStyle: { color: "#00FFF6",}, symbol: "path://M512....", symbolSize: [600, 240], symbolOffset: [360, -150], symbolRotate: 180, z: 999, data: this.convertIPData2(dataCenter, ipCoordData), } 复制代码 4.中国地图边缘高亮实现

04.png

echarts提供的series内itemStyle -normal-boderColor设置的是各省份之间的边界线颜色,要实现单独的地图边缘高亮,可用geo属性结合series生成两个地图叠加,实现想要的效果。

const options = { ..., geo: { silent: true, radius: '100%', map: "china", zoom: 1.20, // zoom: 0.8, // top: "-6%", label: { normal: { show: false, textStyle: { color: "#fff", }, }, emphasis: { textStyle: { color: "#fff", }, }, }, roam: false, itemStyle: { normal: { areaColor: "rgba(0,255,255,.02)", borderColor: { type: 'linear', //设置边缘色渐变 x: 0, y: 1, x2: .5, y2: 0, colorStops: [ { offset: 0, color: '#f7e914' }, { offset: 0.5, color: '#fbaa0e' }, { offset: 1, color: '#306a9f' }], global: false }, borderWidth: 7, shadowColor: "#35a8ff", // shadowColor: "#3071a7", shadowOffsetX: 0, shadowOffsetY: 38, shadowBlur: 45, }, emphasis: { areaColor: "transparent", //悬浮背景 textStyle: { color: "#fff", }, }, }, }, series: [ // 地图 { map: 'china', type: 'map', radius: '100%', zoom: 1.20, label: { normal: { show: false, textStyle: { color: '#FFFFFF', }, }, emphasis: { show: false, }, }, roam: false, //是否允许缩放 itemStyle: { normal: { // color: bgColor, //地图背景色 areaColor: bgColor, //地图背景色 borderColor: borderColor, //内边缘颜色 borderWidth: 2, textStyle: '#fff', }, emphasis: { areaColor: selectColor, //悬浮背景 }, }, data: [], }, ... //其他配置 ] } 复制代码 5. 如何在地图上实现3D柱状图

05.png

地图上元素的配置均在options的series内完成,柱状图分主干、顶部、底部 三部分绘制实现,代码如下:

series: [ ... //其他配置 // 柱状体的主干 { type: "lines", zlevel: 5, effect: { show: false, // period: 4, //箭头指向速度,值越小速度越快 // trailLength: 0.02, //特效尾迹长度[0,1]值越大,尾迹越长重 // symbol: 'arrow', //箭头图标 // symbol: imgDatUrl, symbolSize: 5, // 图标大小 }, lineStyle: { width: 60, // 尾迹线条宽度 // color: "#f60", //柱状颜色 color: { type: 'linear', // 线性渐变 x: 0, // x: 从左向右 1 ——> 0 y: 0, // y: 从上向下 1 ——> 0 x2: 0, // x2: 从右向左 1 ——> 0 y2: 1, // y2: 从下向上 1 ——> 0 colorStops: [ { offset: 0, color: '#ffd43c' }, { offset: 1, color: '#bf5b2d' } ] }, opacity: .8, // 尾迹线条透明度 curveness: 0, // 尾迹线条曲直度 }, label: { show: 0, position: "end", formatter: "245", }, silent: true, data: this.lineData(dataCenter, ipCoordData), }, // 柱状体的顶部 { type: "scatter", coordinateSystem: "geo", // geoIndex: 0, // zlevel: 5, label: { normal: { show: true, formatter: () => { return ''; }, color: "#fff", }, emphasis: { show: true, }, }, itemStyle: { color: "#fff", //##柱状顶部颜色 // opacity: .9, }, symbol: img.orange, symbolSize: [60, 96], symbolOffset: [0, -30], z: 999, // silent: true, data: this.scatterData(dataCenter, ipCoordData), }, // 柱状体的底部 { type: "scatter", coordinateSystem: "geo", geoIndex: 0, zlevel: 4, label: { formatter: "{b}", position: "bottom", color: "#fff", fontSize: 36, distance: 10, show: true, }, symbol: "circle", symbolSize: [60, 30], itemStyle: { color: '#f60', opacity: .6, }, silent: true, data: this.scatterData2(dataCenter, ipCoordData), }, ] 复制代码

柱状体各部分data数据转换

// 柱状体的主干 lineData = (dataCenter, ipCoordData) => { if (!dataCenter) { return } return dataCenter.map((item) => { return { coords: [ ipCoordData[item.name], [ ipCoordData[item.name], ipCoordData[item.name] + item.times * this.lineMaxHeight(dataCenter), ], ], }; }); } // 柱状体的顶部 scatterData = (dataCenter, ipCoordData) => { if (!dataCenter) { return } return dataCenter.map((item) => { return [ ipCoordData[item.name], ipCoordData[item.name] + item.times * this.lineMaxHeight(dataCenter), ]; }); } // 柱状体的底部 scatterData2 = (dataCenter, ipCoordData) => { if (!dataCenter) { return } return dataCenter.map((item) => { return { name: item.name, value: ipCoordData[item.name], }; }); } 复制代码 6.中国地图黄色标牌如何配置?

自定义标牌的实现也在options的series内配置完成。

series:[ ..., //其他配置 // 黄色标牌 { type: "scatter", coordinateSystem: "geo", label: { normal: { show: true, formatter: function (params) { let value = params.value[2]; let times = params.data.times; let system = params.data.system; let text = `{fline|数据中心(${value})}\n{tline|攻击总量:${times} 次}\n{tline|攻击系统:${system} 个}`; return text; }, color: "#fff", rich: { // 富文本配置 fline: { padding: [0, 5], // 调整标牌文字位置 backgroundColor: { type: 'linear', x: 0, y: 0, x2: 1, y2: 0, colorStops: [{ offset: 0, color: '#f7c91c' // 0% 处的颜色 }, { offset: 1, color: '#ffffff00' // 100% 处的颜色 }], globalCoord: false // 缺省为 false }, lineHeight: 72, fontSize: 42, width: 500, height: 80, }, tline: { padding: [0, 25], color: "#fff", fontSize: 36, lineHeight: 60, width: 500, }, }, }, emphasis: { show: true, }, }, itemStyle: { color: "#00FFF6", }, symbol: img.yellow, //自定义图标 symbolSize: [600, 240], symbolOffset: [360, -150], z: 999, data: this.convertIPData2(dataCenter, ipCoordData), }, ] 复制代码 五、经验总结

关于UI图效果还原,基本都能在options上配置实现,可多测试看效果。

echarts 组件案例合集:

www.isqqw.com/

www.ppchart.com/#/

codepen.io/



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有