下载Echarts组件引入Echarts


准备好渲染地图的dom
| <div class="map" ref="map"></div> |
复制
实例化echarts
| const mycharts = echarts.init(this.$refs.map) |
复制
声明地图需要使用的变量数据
| data() { |
| return { |
| mapOption: null, |
| mapList: [], |
| mapList1: [], |
| mor: 2, |
| activeButton: 'value1' |
| } |
| }, |
复制
获取地图json数据的请求方法,传递两个参数,
| this.getMapJson = async (mapName, lenvl) => { |
| const url = 'https://www.isqqw.com/asset/get/areas_v3/' + lenvl + '/' + mapName + '.json' |
| const mapJson = await fetch(url).then(res => res.json()) |
| return mapJson |
| }, |
复制
封装地图需要的option可选项,由于代码太多,只提供一个省级的option吧,市级的跟省级的类似
| |
| function getRandomItems(arr, num) { |
| const shuffled = arr.sort(() => 0.5 - Math.random()); |
| return shuffled.slice(0, num); |
| } |
| var tool = { |
| show: true, |
| backgroundColor: 'rgba(0, 0, 0, 0.6)', |
| borderColor: '#66ccff', |
| borderWidth: 3, |
| borderRadius: 5, |
| padding: [10, 10], |
| textStyle: { |
| color: 'white', |
| fontSize: 14, |
| }, |
| formatter: function (params) { |
| |
| if (params && !params.data) { |
| |
| return ` |
| 暂无数据 |
| ` |
| } |
| if (params && params.data.value2) { |
| const { adcode, name, data } = params.data; |
| |
| return ` |
| <div>参与量  ${params.data.value[2]}</div> |
| <div>业务量  ${params.data.value2}</div> |
| <div>核销量  ${params.data.value3}</div> |
| <div style=" |
| position: absolute; |
| bottom: -10px; |
| left: 50%; |
| transform: translateX(-50%); |
| width: 0; |
| height: 0; |
| border-left: 10px solid transparent; |
| border-right: 10px solid transparent; |
| border-top: 10px solid #66ccff;"></div> |
| </div> |
| ` |
| } |
| if (params && params.data.value) { |
| |
| return ` |
| <div>领券量  ${params.data.value[2]}</div> |
| <div>核销量  ${params.data.value2}</div> |
| <div style=" |
| position: absolute; |
| bottom: -10px; |
| left: 50%; |
| transform: translateX(-50%); |
| width: 0; |
| height: 0; |
| border-left: 10px solid transparent; |
| border-right: 10px solid transparent; |
| border-top: 10px solid #66ccff;"></div> |
| </div> |
| ` |
| } |
| }, |
| extraCssText: 'box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);', |
| position: function (point,) { |
| |
| return [point[0] - 60, point[1] - 100]; |
| } |
| } |
| var pie = [ |
| { min: 0, max: 0, color: '#10184d' }, |
| { min: 1, max: 9, color: '#122666' }, |
| { min: 10, max: 29, color: '#133780' }, |
| { min: 30, max: 49, color: '#124d99' }, |
| { min: 50, max: 99, color: '#1067b3' }, |
| { min: 100, max: 199, color: '#0c86cc' }, |
| { min: 200, max: 299, color: '#07aae6' }, |
| { min: 300, max: 499, color: '#00d4ff' } |
| ] |
| var ric = { |
| fline: { |
| padding: [0, 25], |
| color: '#fff', |
| textShadowColor: '#030615', |
| textShadowBlur: '0', |
| textShadowOffsetX: 1, |
| textShadowOffsetY: 1, |
| fontSize: 14, |
| fontWeight: 400, |
| }, |
| tline: { |
| padding: [0, 27], |
| color: '#ABF8FF', |
| fontSize: 12, |
| }, |
| } |
| var img2 = 'image://https://niecaihang.oss-cn-beijing.aliyuncs.com/kuang.png' |
| |
| |
| export const setOptions = (mapName, mapData, dime) => { |
| var randomItems = getRandomItems(mapData, 2) |
| var imagePath = '@/assets/images/fangk.png'; |
| |
| |
| return { |
| tooltip: tool, |
| visualMap: { |
| type: 'piecewise', |
| orient: 'vertical', |
| show: true, |
| selectedMode: 'multiple', |
| dimension: dime, |
| pieces: pie, |
| splitNumber: 0, |
| left: "440", |
| bottom: '30', |
| padding: 5, |
| itemHeight: 10, |
| backgroundColor: 'rgba(0, 0, 0, 0.5)', |
| }, |
| geo: { |
| map: mapName, |
| roam: true, |
| selectedMode: false, |
| select: false, |
| zoom: 0.8, |
| |
| |
| |
| label: { |
| show: true, |
| fontSize: 12, |
| position: 'insideTopLeft', |
| textStyle: { |
| color: '#fff', |
| }, |
| formatter: function (params) { |
| return params.name.replace(/省|自治区|县|维吾尔|壮族|回族|特别行政区|地区|自治州|香港|澳门/g, ''); |
| } |
| }, |
| itemStyle: { |
| borderWidth: 1, |
| borderColor: '#031534', |
| areaColor: '#025fa1', |
| }, |
| emphasis: { |
| itemStyle: { |
| borderColor: 'red', |
| borderWidth: 1, |
| areaColor: null |
| } |
| }, |
| }, |
| series: [ |
| { |
| type: "map", |
| map: mapName, |
| data: mapData, |
| selectedMode: false, |
| zoom: 1.0, |
| geoIndex: 0, |
| }, |
| |
| { |
| type: 'effectScatter', |
| coordinateSystem: 'geo', |
| showEffectOn: 'render', |
| rippleEffect: { |
| period: 1, |
| scale: 2, |
| brushType: 'fill' |
| }, |
| data: randomItems, |
| rippleEffect: { |
| color: '#00ffff', |
| period: 20, |
| scale: 6, |
| brushType: 'fill', |
| }, |
| symbolOffset: [0, -10], |
| }, |
| { |
| type: 'scatter', |
| coordinateSystem: 'geo', |
| textStyle: { |
| color: 'white', |
| fontSize: 14, |
| }, |
| label: { |
| normal: { |
| show: true, |
| padding: 15, |
| formatter: function (params) { |
| if (params && params.data.value2) { |
| |
| var value = params.data.data; |
| var text = `参与量: ${params.data.value[2]}\n\n业务量: ${params.data.value2}\n\n核销量: ${params.data.value3}`; |
| return text; |
| } |
| |
| if (params && params.data.value) { |
| |
| var value = params.data.data; |
| var text = `领券量: ${params.data.value[2]}\n\n核销量: ${params.data.value3}`; |
| return text; |
| } |
| |
| }, |
| color: '#fff', |
| rich: ric |
| }, |
| emphasis: { |
| show: true, |
| }, |
| }, |
| itemStyle: { |
| color: '#fff', |
| }, |
| symbol: img2, |
| symbolSize: function (val) { |
| if (val) { |
| return val[2] / 6 + 80; |
| } |
| }, |
| symbolOffset: [-10, -50], |
| data: randomItems, |
| }, |
| ] |
| } |
| } |
复制
组件引入option可选项文件
| import { setOptions, setOptions1 } from '../utils/MapOption' |
复制
封装渲染地图的方法
| this.renderMapEcharts = async (mapName, lenvl) => { |
| console.log(this.pass); |
| const mapJson = await this.getMapJson(mapName, lenvl) |
| echarts.registerMap(mapName, mapJson); |
| const mapdata = mapJson.features.map((item) => { |
| const data = (Math.random() * 200 + 0).toFixed(0) |
| const data2 = (Math.random() * 300 + 0).toFixed(0) |
| const data3 = (Math.random() * 420 + 0).toFixed(0) |
| const center = { data, data2, data3 }; |
| const tempValue = item.properties.center ? [...item.properties.center, data, data2, data3] : item.properties.center |
| return { |
| name: item.properties.name, |
| value: tempValue, |
| value1: data, |
| value2: data2, |
| value3: data3, |
| adcode: item.properties.adcode, |
| level: item.properties.level, |
| } |
| }); |
| |
| if (mapName != 'china') { |
| mycharts.resize() |
| this.mapOption = setOptions1(mapName, mapdata, this.mor) |
| } |
| |
| else { |
| mycharts.resize() |
| this.mapOption = setOptions(mapName, mapdata, this.mor) |
| } |
| this.$nextTick(() => { |
| mycharts.setOption(this.mapOption) |
| mycharts.resize() |
| }) |
| |
| } |
复制
接着调用渲染地图的方法,进入页面初次渲染地图
| this.$nextTick(() => { |
| this.renderMapEcharts('china', 'country') |
| mycharts.resize() |
| }) |
复制
接着开始写地图下钻的事件,我这里只判断下钻到市级,区级设了限制,如果想下钻到区县级可以根据以下调试一下代码
| |
| mycharts.on('click', (param) => { |
| if (param.data === undefined) { |
| this.$message({ |
| type: 'error', |
| message: '已经在最下层了,无法继续下钻', |
| }) |
| return; |
| } |
| if (param.seriesType !== 'map') return |
| const { adcode, level } = param.data; |
| |
| if (level === 'city') { |
| this.$message({ |
| type: 'error', |
| message: '已经在最下层了,无法继续下钻', |
| }) |
| return; |
| } |
| const mapName = level === 'city' ? adcode : adcode + '_full'; |
| |
| if (this.mapList[this.mapList.length - 1] === mapName) { |
| |
| this.$message({ |
| type: 'error', |
| message: '已经在最下层了,无法继续下钻', |
| }) |
| return; |
| } |
| this.$nextTick(() => { |
| this.mapList.push(mapName); |
| this.mapList1.push(level); |
| this.renderMapEcharts(mapName, level); |
| mycharts.resize() |
| }) |
| }); |
复制
接着写一个地图返回的dom跟方法
| <div class="back"> |
| <span v-show="mapList.length !== 0" class="Mapback" @click="back">地图返回</span> |
| </div> |
复制
methods:
| back() { |
| const level = this.mapList1[this.mapList.length - 2] || 'country'; |
| const mapName = this.mapList[this.mapList.length - 2] || 'china'; |
| this.mapList.pop(); |
| this.renderMapEcharts(mapName, level); |
| }, |
复制
结尾:
需要注意的是,我在渲染方法下边部分去判断了一下如果mapName是China那就使用封装好的setOption方法,我还封装了一个setOption1是市区的option,这些都可以根据自己的需求自己封装,可以以我封装的setOption进行更改就行