首页>>前端>>Vue->vue2项目中给echarts地图设置背景图和打点

vue2项目中给echarts地图设置背景图和打点

时间:2023-11-30 本站 点击:0

以前写过 vue项目中封装echarts的比较优雅的方式,vue2项目中封装echarts地图比较优雅的方式,这次对地图做一个小拓展,在vue2项目中封装echarts地图比较优雅的方式 的基础上进行。

能学到的知识

1、ECharts地图背景图设置,可以设置随意的地图纹理

2、echarts地图打点,显示数据

效果图

虽然不明显,但是打点是真的在闪动的

实现

在 vue2项目中封装echarts地图比较优雅的方式 的基础上稍微做点改变。

echarts地图模块封装

|-- src    |-- components        |-- chart            |-- options    // 存放各种图表的option                |-- map    // 地图option                    |-- index.js

具体代码如下:

// import echarts from 'echarts'import * as echarts from 'echarts'import mapbg from '@/assets/images/map-bg.png'const getSimpleMap = (jsonMap, data, config) => {  if (!echarts.getMap(jsonMap.mark)) {    echarts.registerMap(jsonMap.mark, jsonMap.json)  }  const convertData = (data) => {    console.log(data)    var res = []    for (var i = 0; i < data.length; i++) {      const mapData = data[i].hoverObj      const center = data[i].mapProperty.center      if (center && mapData) {        res.push({          name: mapData.name,          value: center.concat(mapData.num)        })      }    }    return res  }  const defaultConfig = {    tooltip: {      // 窗口外框      trigger: 'item',      padding: 0,      borderWidth: 0,      borderColor: '#FFFFFF',      backgroundColor: '#FFFFFF',      formatter: (params) => {        const { data } = params        const str = `<div style="width:300px;height: 98px;box-shadow: 0px 4px 20px 0px rgba(0, 0, 0, 0.8);                    color: #fff;text-align:left;border-radius: 6px;">                    <div style="background-color: rgba(102, 182, 255, 1);height: 44px;line-height: 44px;font-size:14px;font-weight:400;border-top-left-radius: 6px;border-top-right-radius: 6px;display: flex;align-items: center;">                        <img style="width: 13px;height:16px;margin-left: 24px;margin-right: 3px;" src="images/map-ic.png">${data.name}                    </div>                    <div style="width: 100%;height:54px;display: flex;flex-wrap: wrap;">                        <div style="display: flex;justify-content: space-between;width: 100%;padding-left:15px;padding-right: 15px;">                            <div style="display:flex;align-items:center;width:132px;">                                <div style="font-size: 12px;color: #555555;margin-right:10px;">区号:</div>                                <div style="font-size: 14px;color: #333333;">${data.hoverObj == null ? '' : data.hoverObj.adcode}</div>                            </div>                        </div>                    </div>                </div>`        return str      }    },    geo: {      map: jsonMap.mark,      type: 'map',      layoutCenter: ['50%', '50%'],      layoutSize: '150%',      zoom: 0.65,      roam: false,      // 样式一      // itemStyle: {      //   normal: {      //     areaColor: 'rgba(13, 110, 191, 1)',      //     shadowColor: 'rgba(13, 110, 191, 0.5)',      //     shadowOffsetX: 6,      //     shadowOffsetY: 12      //   }      // }      // 样式二      itemStyle: {        normal: {          borderColor: '#AEF3FF',          borderWidth: 2,          areaColor: {            image: mapbg, //            repeat: 'repeat' // // 是否平铺,可以是 'repeat-x', 'repeat-y', 'no-repeat'          },          shadowColor: 'rgba(13, 110, 191, 0.5)',          shadowOffsetX: 6,          shadowOffsetY: 12        }      }    },    series: [      {        type: 'map',        map: jsonMap.mark, // 自定义扩展图表类型        zoom: 0.65, // 缩放        animationDuration: 1200,        // 点击选中后的效果        select: {          label: {            color: '#FFFFFF',            fontSize: 12,            fontWeight: 400          },          // 清除点击选中后的背景色          itemStyle: {            color: null          }        },        // 样式一        // itemStyle: {        //   // 地图样式        //   normal: {        //     borderColor: '#FFFFFF',        //     borderWidth: 3,        //     areaColor: 'rgba(201, 229, 255, 1)'        //   }        // },        // 样式二        itemStyle: {          // 地图样式          normal: {            borderColor: '#AEF3FF',            borderWidth: 2,            areaColor: {              image: mapbg, //              repeat: 'repeat' // // 是否平铺,可以是 'repeat-x', 'repeat-y', 'no-repeat'            }          }        },        // 样式一        // label: {        //   show: true,        //   color: '#666666',        //   fontSize: 12,        //   fontWeight: 400        // },        // 样式二        label: {          show: true,          color: '#FFFFFF',          fontSize: 12,          fontWeight: 400        },        emphasis: {          // 鼠标移入动态的时候显示的默认样式          label: {            show: true,            color: '#FFFFFF',            fontSize: 15,            fontWeight: 600          },          itemStyle: {            areaColor: 'rgba(102, 182, 255, 0.7)',            borderColor: '#FFFFFF',            borderWidth: 2          }        },        layoutCenter: ['50%', '50%'],        layoutSize: '150%',        data: data      },      {        type: 'effectScatter',        coordinateSystem: 'geo',        symbol: 'image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAABhdJREFUaEPtWW9sU1UU/51XCPuAMfR1DPGDiUFJGAETiFtvUYMoMr4YSdZXEPAvGhVRENQYjRj0A4LoUBMV/wK6vjYR/SKKICL0dTNAhDASFE1MkADrG/7BZML6jrnte91r147XrgMxu8mS3XvPPb/zu+fcc899JVzijS5x+zFE4GJ7cMgD/ysPpHZHGmgYN8PCTQDqiFDHwFkCTnLmj3YRrF1QhifVxo//rAb5qoTQaUNbaBEeBqPBm1F0DEDLiWPp9fXh+Flva4pLDYhAyojMIFjLAZpViREE7LfAqwIi9lkl6+WaigmcTkaWWMwtecCEA2C0K4RDacvq6EHPITk/DMMm+hSl3mJMBKEBjMnudQqwdJTQX6uEREUEupLanczYnG88bUh3p5eNnh4/058hp3Y2j/TV+NaBeVG+nNKkitYvyyVRNgHT0JoBxHJAjBSIbldF1CgH3DQiAsyfgxBw1lmEKbVBfX85esoi8Pfe+Vd0nz23F8BYG+S4KvQrCwGP75wbqKlJj2em+kycEnd0d/uOjJ3emiqUNQ3tN0cfAd/6hT590Ah0JsIrFaLnczuWxvjaG/Qf3YCmoclYfqyEES2q0B93z3Xu1q5VfDiS08n8Qm0ottIrCc8e+H33vFFpX1oeyszuM3hxQMTedAOljPBJAo3uD5zBpwIiVlew7hECveGM9TDG1YX0n72Q8EzA3BPRoHA0o5T5azUUm5lnREJbT4RHXWPbmLM7S4TxAHLyzHg9ENKX5HkuEd4Goluz8vSQPxh9q7oEDO1dAPfZBNaroVguTFKJ8Hwi2pQDJHyoBvV78gxMah+AcbczxswLAqFYLpOZiXALiGxSvEUVsTnVJiAP7xRb6YOq0N9xALoMbSMDC+zdftkf1J8qBt6V1FYz48mMHLDJL/SFjpxpaA8AeNvuH1SFnndXlCLjPYRc2cJSrKm1jfF9LvADACbJfuFc3oFta56iWIrcCNnyjOx0zcm6KSD0MdX2ADsKVaHnETcNreRcoRH9yZajx9Hr2QNdSa2TOXvpjFCUMSMbW0+6PJALL1KUyf7G1oNFQ6ht7iS2LOkt2fapQp/qyJ1pm1v3j2WdsMMw5Q/qtdX2wB4AoYxSxm1qSN/WSyDyHsD32v24KvRwMXDT0OQNLm9yeQreV0U0mxQAmAltJghf2d2EKvRp1SWQl0VohSqia3Pge7T7oWCD07eKXEaFlyAsLFKn6TKzZQkYkeUAr8ly65vFSpHxHEL5BtA3qojOcCs1DW07APeY7P9iy1wN4BaX/A5V6O6+JLAD4JulTLENGDABs615Aiylo1cRhQoLuJSh/UTAuP5cz8DRgNCvyScfEQAncmOKVa82xg9XNYSybnbFMOEVNagvLwQxDU3WOq+WAF+qFqn7zaS2Fown7DUlz1AxnZ5DyCaQK6Vlrvaxr2FU6JNfCxX/9V1zbTf56n0KT5BzaYsO13C647Ib452FsqcT865KU7qdAKc+CqtCj3vZ/exxKbOZRqQd4Ouzy3itKmIrylSRJ24a4TUA2Z6k71UR9fiuzqopm0DK0BYS8JFtRTcpSkOpvH8+Yl3Ze6EdQE1mO4C7AkLfeL517vmyCdihlMs4RLTZH4xm6qByW1cysomZ59vr+mQmL/oqIpAymu8gKJ86AMz8XCAUe9ELoCOTSoSfJaJVOR2w5gREfEs5OioKoV4D+tT/ng9f4bu62PvAK5GKPOAoNw3tCwBNdv84KUrT+c6DHfdbXe/qrarQZ3s1uFBuQAT+MJrHnYOy1XV5/TBCUWa5Cz03oF2wyU8n19mH9uhwWE2Xi/jRi0JAgnYltSZmSE84zVCFni36CpppaPK2Fc4wEWb7g7r0RsVtQB5wUDPfRntTq0yHOwIFtU7K0LaTq1aqJGUWY1kVAhlPGNpiBl7P7a7ryeh+cmZDp+8XjUpdUDUC2XCKPMPML+WMIVqW+Z95XW/Y0NP+YHR1pQZX9RAXM6JP3e8SKqdM9kqwqh5wQIuRGAzjJd6gEJCK3SQGy/hBJSCVy98QeizLX863Tq+h40oW5S75b8kPWghdKJpDBC7UTpfCGfLAxfbAv/mAaE9adPIDAAAAAElFTkSuQmCC',        symbolSize: [16, 16],        // symbolOffset: [],        label: {          normal: {            show: true,            offset: [0, -18],            textStyle: {              color: '#fff',              fontSize: 12,              fontWeight: 500            },            formatter(value) {              return '{a|' + value.data.value[2] + '}'            },            rich: {              a: {                color: '#FFFFFF',                backgroundColor: '#06406A',                width: 28,                height: 16,                lineHeight: 16,                align: 'center',                borderWidth: 1,                borderColor: '#79D6FE',                borderRadius: 2,                padding: [0, 4, 0, 4]              }            }          }        },        itemStyle: {          normal: {            color: 'rgba(255, 178, 76, 1)'          }        },        data: convertData(data),        showEffectOn: 'render',        rippleEffect: {          brushType: 'stroke'        },        hoverAnimation: true,        zlevel: 9      }    ]  }  const opt = Object.assign({}, defaultConfig, config)  const { legend, tooltip, series, geo, grid } = opt  const chartOpt = {    grid,    legend,    tooltip,    geo,    series  }  return chartOpt}export default {  getSimpleMap}

新增的代码,最好在Visual Studio CodeTimeline里面对比查看,只是添加了地图纹理和地图打点。

地图纹理 (components--chart--options--map--index.js)

实现代码在:

geo样式二的itemStyle,这里控制鼠标移入地图模块时的纹理

series样式二的itemStyle,这里控制地图默认状态下的纹理

地图打点 (components--chart--options--map--index.js)

实现代码在effectScatter模块,主要是自定义了打点的图标,还有自定义了显示信息的label的样式,这里可以根据设计随意实现。

打点数据在convertData方法里面处理,可以根据接口数据看着办。

数据 (views--echartMapTest--index.js)

因为要在地图上打点,需要坐标,加载数据的时候,需要加上地图的坐标,主要是加上这一行,properties包含了地图所有基本数据了

mapProperty: item.properties

具体如下:

initMap(url) {      mapRequest(url).then((res) => {        const mapData = res.data        const jsonMap = { mark: this.mapName, json: mapData }        const data = mapData.features.map((item) => {          const { name, adcode } = item.properties          let hoverObj = {}          const objIndex = this.$utils.findElem(this.mapPopData, 'adcode', adcode)          if (objIndex !== -1) {            hoverObj = this.mapPopData[objIndex]          } else {            hoverObj = null          }          return {            name,            mapProperty: item.properties,            hoverObj: hoverObj          }        })        this.mapOpt = this.$eChartFn.getSimpleMap(jsonMap, data)      }).catch((err) => {        console.log(err, '加载地图失败')      })    }

代码总览

涉及的文件如下(具体参考代码):

|-- public    |-- data        |-- 4401.json        |-- mapdata.json|-- src    |-- api        |-- map.js    // 获取地图geojson数据、地图弹窗接口模拟数据    |-- components        |-- chart            |-- index.vue    // 图表单文件组件,供界面调用            |-- index.js    // 实现自动化导入options里的图表option            |-- options    // 存放各种图表的option                |-- map    // 地图option                    |-- index.js    |-- views        |-- echartMapTest    // 实例所在            |-- index.vue            |-- index.scss            |-- index.js    |-- utils        |---utils.js|-- main.js    // 全局引入echarts图表

代码

代码总览的目录去代码里找着看就行了。

总结

echarts地图的纹理不只可以纯色或者渐变色的,还可以根据设计随意设置。项目中UI设计的很好看,这里只是随意截取了纹理的一部分做了个例子。

以上,基本只要UI设计的出来,就可以实现任意纹理样式的地图。

原文;https://juejin.cn/post/7097136735963840542


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Vue/3769.html