功能:javascript
1. 引入echartMapOptions.js文件
2. new MapDrillDown(dom, this).init() 传入参数便可使用
// js中使用document.getElementById('chart')获取dom对象
// Vue中使用this.$refs.chart获取dom对象
复制代码
echartMapOptions.js内容以下:html
import echarts from 'echarts' // javascript环境下注释掉
import $ from 'jquery' // javascript环境下注释掉
import china from './china.js' // javascript环境下注释掉
import {cityNameData, provinceNameChineseToEng, cityNameChineseToEng} from './geoNameDictionary.js' // javascript环境下注释掉
// geoNameDictionary.js 文件为全部省市区中英文对照json数据,以及中文名和英文名互相转换的方法
复制代码
function MapDrillDown (echartDom, obj) {
this.chartDom = echarts.init(echartDom) // 参数为地图div的dom对象
this.optionMap = null // 地图配置信息
this.tag = 0 // tag: 0全国 1省 2市 标记当前层级
this.timer = null // 点击事件定时器
this.provinceOrCityName = '' // 当前省/市名称
this.lastProvinceOrCityName = '' // 上一层级的省/市名称
this.loadingObj = obj.$message // showLoading()/hideLoading()调用对象, javascript环境下注释掉
}
复制代码
MapDrillDown挂事件vue
MapDrillDown.prototype = {
// 设置区域颜色
setRegions: function (regionsJson) {
var colors = ['#083967', '#13548d', '#1c74b2']
var colorsLen = colors.length
var features = regionsJson.features
var echatsRegions = []
// var echatsRegions=[{
// name: '南海诸岛',
// value: 0,
// itemStyle: {
// normal: {
// opacity: 0,
// label: {
// show: false
// }
// }
// }
// }];
for (var i = 0, len = features.length; i < len; i++) {
var regionsItem = {
name: features[i].properties.name,
itemStyle: {
normal: {
areaColor: colors[Math.floor(Math.random() * colorsLen)]
}
}
}
echatsRegions.push(regionsItem)
}
return echatsRegions
},
}
复制代码
地图样式配置信息java
MapDrillDown.prototype = {
...
setMap: function () {
this.optionMap = {
tooltip: {
trigger: 'item',
enterable: true, // 鼠标是否能进入提示框内
formatter: function (params) {
// 这里配置鼠标悬于散点时,提示框的样式及展现的内容
var content = ''
if (params.value !== undefined) {
content = `<p style='text-align: center;min-width: 100px;'><span class='dpb' style='padding: 5px 8px;font-family: 微软雅黑;font-size: 18px;color: #ffffff;'>${params.name}</span><br></p>`
}
return content
}
},
geo: {
map: 'china',
label: {
normal: {
show: true,
color: '#639bc3'
}
},
itemStyle: {
normal: {
areaColor: '#083967',
borderColor: '#48c7ff',
borderWidth: 2
},
emphasis: {
areaColor: '#48c7ff' // 高亮效果
}
}
},
series: [
{
name: '',
type: 'scatter',
coordinateSystem: 'geo',
opacity: 1,
// 散点数据
data: convertData(data),
symbolSize: 10, // 散点图的大小
label: {
normal: {
show: false
}
},
itemStyle: {
normal: {
color: '#00d0e4',
borderColor: '#fff',
borderWidth: 2
},
emphasis: {
borderColor: '#fff',
borderWidth: 2
}
}
}
]
}
// 图表自适应
window.addEventListener('resize', function () {
this.chartDom.resize()
}.bind(this))
this.optionMap.geo.regions = this.setRegions(china) // 设置区域颜色
this.chartDom.setOption(this.optionMap)
},
...
}
复制代码
注册单击/双击事件jquery
MapDrillDown.prototype = {
...
setClick: function () {
let that = this
// 点击事件
that.chartDom.on('click', function (params) { // 点击事件
clearTimeout(that.timer)
that.timer = setTimeout(function () {
if (params.componentType === 'geo') { // 点击地图区域
that.reFreshMap(params.name)
}
}, 300)
})
// 这里使用定时器的缘由是:双击是会触发两次单击事件,加时间是双击事件优先被执行,而后在双击事件回调中清除单击事件定时器
// 双击事件
that.chartDom.on('dblclick', function (params) {
clearTimeout(that.timer) // 清除单击事件定时器,使双击时再也不触发单击事件
that.tag = 0
that.optionMap.series[0].data = convertData(data)
that.optionMap.geo.map = 'china'
that.chartDom.setOption(that.optionMap)
})
},
...
}
复制代码
点击下钻处理函数git
MapDrillDown.prototype = {
...
reFreshMap: function (paramsName) {
let that = this
this.loadingObj.showLoading({
title: '正在加载...'
}) // javascript环境下注释掉
// 当前处于省级或直辖市级
if (that.tag === 0) {
// 获取当前点击的省级名称
this.provinceOrCityName = paramsName
let provinceEngName = provinceNameChineseToEng(this.provinceOrCityName)
// 将省级名称转为英文名称,并获取对应省的地图json资源
// 这里的json资源能够下载下来放在本地,引用本地路径,也能够是网络资源
$.get('https://orangleli.github.io/imagesResources/echartMapResources/geoProvince/' + provinceEngName + '.json', function (mapJson) {
that.tag++
that.loadingObj.hideLoading() // javascript环境下注释掉
that.optionMap.series[0].data = convertData(data, provinceEngName)
that.optionMap.geo.map = provinceEngName
echarts.registerMap(provinceEngName, mapJson)
that.chartDom.setOption(that.optionMap)
})
this.lastProvinceOrCityName = this.provinceOrCityName
} else if (that.tag === 1) {
// 当前处于市级
// 直辖市只能下钻到区层级
if (this.lastProvinceOrCityName.includes('直辖市') > 0 || this.lastProvinceOrCityName.includes('台湾省') > 0) {
that.loadingObj.hideLoading() // javascript环境下注释掉
return
}
this.provinceOrCityName = paramsName
var provinceEngName = provinceNameChineseToEng(this.lastProvinceOrCityName)
let cityNameEng = cityNameChineseToEng(that.provinceOrCityName, provinceEngName)
$.get('https://orangleli.github.io/imagesResources/echartMapResources/city/' + provinceEngName + '/' + cityNameEng + '.json', function (mapJson) {
that.tag++
that.loadingObj.hideLoading() // javascript环境下注释掉
that.optionMap.series[0].data = convertData(data, provinceEngName, cityNameEng)
that.optionMap.geo.map = provinceEngName
echarts.registerMap(provinceEngName, mapJson)
that.chartDom.setOption(that.optionMap)
})
} else {
that.loadingObj.hideLoading() // javascript环境下注释掉
}
},
init () {
this.setMap()
this.setClick()
}
...
}
复制代码
另:处理散点的方法github
// 当处于全国地图时,展现全部散点,
// provinceEngName 传入省名称时过滤掉全部非当前省的散点
// provinceEngName,cityNameEng 传入省,市名称时过滤掉全部非当前省,当前市的散点
var convertData = function (data, provinceEngName, cityNameEng) {
var res = []
for (var i = 0; i < data.length; i++) {
if (provinceEngName) {
let ret = cityIsInclude(provinceEngName, data[i].name, cityNameEng)
if (ret) {
var geoCoord = geoCoordMap[data[i].name]
if (geoCoord) {
res.push({
name: data[i].name,
value: geoCoord.concat(data[i].value)
})
}
}
} else {
let geoCoord = geoCoordMap[data[i].name]
if (geoCoord) {
res.push({
name: data[i].name,
value: geoCoord.concat(data[i].value)
})
}
}
}
return res
}
// 遍历判断全部散点是否属于provinceEngName传入的省,cityNameEng传入的市
let cityIsInclude = function (provinceEngName, cityName, cityNameEng) {
let cities = cityNameData[`cityName_${provinceEngName}`]
for (let city in cities) {
if ((!cityNameEng && city.indexOf(cityName) !== -1) || (cityNameEng && city.indexOf(cityName) !== -1 && cities[city] === cityNameEng)) {
return true
}
}
return false
}
复制代码
导出npm
// javascript环境下注释掉
export {
MapDrillDown
}
复制代码
以上是echartMapOptions.js的源码json
npm install echarts --save
npm install jquery --save
复制代码
<template>
<div ref="chart" class="mapCls"></div>
</template>
<script>
import {MapDrillDown} from './js/echartMapOptions.js'
export default {
name: 'echartMapShow',
mounted () {
new MapDrillDown(this.$refs.chart, this).init() // 参数为地图div的dom对象
}
}
</script>
<style scoped>
.mapCls{
width: 100%;
height: 1000px;
background-image: url(./bg.png);
background-size: 100% 100%;
background-repeat: no-repeat;
}
</style>
复制代码
Vue中使用echarts的源码bash
* npm install
* npm run dev
复制代码
<div class="container" v-if="isShow">
<img class="icon" :src="iconImg"/>
<div class="title">{{title}}</div>
</div>
复制代码
<script>
export default {
name: 'loading',
data () {
return {
isShow: false,
loadingImg: 'data:image/gif;base64,R0lGODlhZ...', // loading图片base64串
iconImg: '',
title: '加载中...',
duration: 1500,
timer: null
}
},
methods: {
showLoading (obj) {
let that = this
that.iconImg = that.loadingImg
that.isShow = true
if (obj) {
that.title = obj.title
}
that.duration = -1
},
hideLoading () {
let that = this
this.isShow = false
if (that.timer) {
clearInterval(that.timer)
that.timer = null
}
},
showToast (obj) {
let that = this
that.isShow = true
if (obj) {
that.title = obj.title || that.title
if (obj.icon === '') {
that.iconImg = that.loadingImg
} else if (obj.icon === 'success') {
that.iconImg = that.successImg
} else if (obj.icon === 'none') {
that.iconImg = ''
}
that.duration = obj.duration || that.duration
}
that.delayHide()
},
hideToast () {
this.isShow = false
},
delayHide () {
let that = this
if (that.duration >= 0) {
that.timer = window.setInterval(that.hideLoading, that.duration)
}
}
}
}
</script>
复制代码
仿微信的wx.showLoading()、wx.hideLoading()、wx.showToast()、wx.hideToast()方法
<div class="mask" v-if="isShow">
<div class="container">
<div class="contentGroup">
<div class="title">{{title}}</div> <!--标题-->
<div class="content">{{content}}</div> <!--内容-->
</div>
<div class="buttonGroup lineBorderBefore">
<div v-if="showCancel" class="cancel lineBorderRight" :style="'color: ' + cancelColor + ';'" @click.prevent.stop="cancelClick">{{cancelText}}</div> <!--取消按钮题-->
<div class="confirm" :style="'color: ' + confirmColor + ';'" @click.prevent.stop="confirmClick">{{confirmText}}</div> <!--肯定按钮-->
</div>
</div>
</div>
复制代码
<script>
export default {
name: 'wxModal',
data () {
return {
isShow: false,
title: '提示',
content: '点击确认',
showCancel: true,
cancelText: '取消',
cancelColor: '#000',
confirmText: '确认',
confirmColor: '#ff6a0b',
cancelCallback: null,
confirmCallback: null
}
},
methods: {
showModal (obj) {
let that = this
that.isShow = true
if (obj) {
that.title = obj.title
that.content = obj.content
that.showCancel = obj.showCancel === undefined || obj.showCancel === true
that.cancelText = obj.cancelText || that.cancelText
that.cancelColor = obj.cancelColor || that.cancelColor
that.confirmText = obj.confirmText || that.confirmText
that.confirmColor = obj.confirmColor || that.confirmColor
if (that.showCancel) {
that.cancelCallback = obj.cancelClick
}
that.confirmCallback = obj.confirmClick
}
},
cancelClick (callback) {
let that = this
that.isShow = false
that.cancelCallback && that.cancelCallback()
},
confirmClick (callback) {
let that = this
that.isShow = false
that.confirmCallback && that.confirmCallback()
}
}
}
</script>
复制代码
import loadingComponent from './loading.vue'
import wxModalComponent from './wxModal.vue'
const loading = {
install: function (Vue) {
let LoadingProfile = Vue.extend(loadingComponent)
let loadingPro = new LoadingProfile()
let AlertProfile = Vue.extend(wxModalComponent)
let alertPro = new AlertProfile()
document.body.appendChild(loadingPro.$mount().$el)
document.body.appendChild(alertPro.$mount().$el)
// 将方法挂到Vue原型对象上去,经过this.$message.showLoading() 就可使用
Vue.prototype.$message = {
showLoading (obj) {
return loadingPro.showLoading(obj)
},
hideLoading () {
return loadingPro.hideLoading()
},
showToast (obj) {
return loadingPro.showToast(obj)
},
hideToast () {
return loadingPro.hideToast()
},
showModal (obj) {
return alertPro.showModal(obj)
}
}
}
}
export default loading
复制代码
1. 将alertModal文件整个赋值到components文件夹下
2. 在main.js中添加:
import alertModal from './components/alertModal/alertModal.js'
Vue.use(alertModal)
3. 在组件中就可使用了,如 this.$message.showLoading(),注意this的指向哦
复制代码
注意this的指向:好比本文MapDrillDown原型对象挂载的方式中使用时,其this并不指向Vue原型对象,因此在组件中new MapDrillDown(this.$refs.chart, this).init()的时候,把this对象当作参数传递过去了
echartMapOptions.js文件稍做修改,不用import,export,因此如下代码要进行注释
// import echarts from 'echarts'
// import $ from 'jquery'
// import china from './china.js'
// import {cityNameData, provinceNameChineseToEng, cityNameChineseToEng} from './geoNameDictionary.js'
// export {
// MapDrillDown
// }
复制代码
同时loading组件和showModal组件也不能使用
function MapDrillDown (echartDom, obj) {
this.chartDom = echarts.init(echartDom)
this.optionMap = null
// tag: 0全国 1省 2市
this.tag = 0
this.timer = null
this.clickLock = true
this.provinceOrCityName = ''
this.lastProvinceOrCityName = ''
// this.loadingObj = obj.$message 这里要进行注释
}
// this.loadingObj.showLoading({
// title: '正在加载...'
// })
// that.loadingObj.hideLoading()
复制代码
HTML中引入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>地图下钻</title>
<style>
.mapCls{
width: 100%;
height: 1000px;
background-image: url(./bg.png);
background-size: 100% 100%;
background-repeat: no-repeat;
}
</style>
</head>
<script src="./resources/jquery.min.js"></script>
<script src="./resources/echarts.js"></script>
<script src="./resources/china.js"></script>
<script src="./resources/geoNameDictionary.js"></script>
<body>
<div id="chart" class="mapCls"></div>
</body>
<script src="./echartMapOptions.js"></script>
<script>
new MapDrillDown(document.getElementById('chart')).init();
</script>
</html>
复制代码
* 运行index.html文件
复制代码