功能: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文件
複製代碼