current position:Home>Vue uses echart to draw national maps and overlay charts
Vue uses echart to draw national maps and overlay charts
2022-04-29 14:35:37【_ Xiao Zheng is a little sleepy】
scene :
Big data shows the information of all provinces in the country , Make a map , And overlay the chart on each province .
What needs to be done is
1、 Map the country ( Different provinces have different colors according to different data )
2、 Each province needs to overlay a chart separately ( The pie chart )
3、 Map zoom 、 The size of the chart scales with the scale
4、 Map drag , The chart moves together according toThere are some pits in it
design sketch :
Incomplete screenshot , Effect of the sample .
Complete code :
mapOption.js Configuration item :
let obj ={
}
export default {
geo: {
map: 'china',
show: false,
roam: false,
label: {
emphasis: {
show: false
}
},
layoutSize: "100%",
itemStyle: {
normal: {
}
}
},
visualMap: {
min: 0,
max: 1000,
left: 100,
bottom: 45,
showLabel: !0,
backgroundColor:"#fff",
text: [" high ", " low "],
pieces: [],
},
series: [
{
type: 'map',
zoom:1.1,
aspectScale: 0.9,
layoutCenter: ["50%", "60%"], // Map location
layoutSize: "100%",
zlevel: 3,
scaleLimit: {
// Limit control of wheel scaling
min: 1,
max: 1.5,
},
geo: {
show: true,
map: 'china',
label: {
normal: {
show: false
},
emphasis: {
show: false,
}
},
roam: false,
itemStyle: {
normal: {
areaColor: '#031525',
borderColor: '#3B5077',
},
emphasis: {
areaColor: '#2B91B7',
}
}
},
roam: true, // Whether to turn on mouse zoom and pan roaming
selectedMode: 'false', // Whether multiple areas are allowed to be selected
emphasis:{
label:{
show:true,
color:'#ffffff',
}
},
label: {
show: true,
color: "#FFFFFF",
fontSize: 12,
},
itemStyle: {
normal: {
areaColor: "#0c3653",
borderColor: "#1cccff",
borderWidth: 2,
},
emphasis: {
areaColor:"rgb(12,76,107)", // Mouse hovering / Choose a color
label: {
show: true,
color: "#fff",
borderColor:"rgb(2,241,177)",
},
},
},
data: [],
},
]
};
Other examples are china.json Move to datav Download it : The structure is as follows
<template>
<div class="chart pt-10">
<el-button type="primary" size="mini" @click="options.id=1"> Pattern 1</el-button>
<el-button type="primary" size="mini" @click="options.id=11"> Pattern 2</el-button>
<div id="mapChart" class="mapChart"></div>
</div>
</template>
<script>
import mapOption from './echarts/map'
import chinaData from '@/assets/china.json'
import liaoningPro from './echarts/liaoning.json'
import shenyangCity from './echarts/shenyang.json'
export default {
data(){
return{
myChart: null,
chinaCode:100000,
curMapName:'china', // Current map name
selectedMaps:[
{
name:'china',
code:'100000',
}
],
// Map scatter data
mapDotData:{
input:{
value:{
}
},
output:{
value:{
rows:[]
}
}
},
typeIndex:1,
// Last zoom level
lastZoomLevel:0,
// legend
options:{
id:1
}
}
},
props:{
},
async mounted(){
await this.getMapData('china');
window.addEventListener('resize',this.resizeCharts);
// // This is for map drilling Reserve it In the future, you need to directly release the continue writing logic. At present, it can be regarded as realizing the operation of drilling down
// this.myChart.on('click', (params) => {
// console.log(' Space ',params)
// const map = params.name;
// if(map){
// this.curMapName = params.name;
// this.getMapData(map);
// // Save... For the map title menu ( Filter multiple clicks on the same map ) Click map information
// let selectedCodes = [];
// this.selectedMaps.forEach( item => selectedCodes.push(item.code));
// if(!selectedCodes.includes(map)){
// this.$set(this.selectedMaps,this.selectedMaps.length,{
name: this.curMapName, code: map});
// }
// console.log(selectedCodes)
// }else{
// this.$message({
message: ' No map data yet ',type: 'warning',showClose: true});
// }
// });
window.addEventListener("resize", (params)=> {
if(Number(this.options.id)<10){
this.resetDot(this.myChart, params);
}else{
this.resetPie(this.myChart, params);
}
})
},
beforeDestroy() {
window.addEventListener('resize',this.resizeCharts);
},
watch:{
"options.id":{
async handler(v){
if(v){
this.myChart.dispose()
this.getMapData('china')
}
}
},
},
methods:{
// Make a map
async drawMapChart(mapName,mapJSON){
if (this.myChart != null && this.myChart != "" && this.myChart != undefined) {
this.myChart.dispose();
}
this.myChart = this.$echarts.init(document.getElementById('mapChart'));
this.$echarts.registerMap(mapName,mapJSON);
let seriesData = this.initMapData(mapJSON)
// Then call the interface to query the map information
await this.getMapDotData()
let arr = this.mapDotData.output.value.rows
for(var i =0;i<seriesData.length;i++){
arr.forEach((item,index)=>{ if(seriesData[i].name==item.xzqmc){ seriesData[i].value = item.total } }) } mapOption.series[0].map = mapName mapOption.series[0].data = seriesData // The legend is configured mapOption.visualMap.pieces =[{ gt: 100, color: "#7f1100" }, { gte: 60, lte: 80, color: "#ff5428" }, { gte: 20, lt: 60, color: "#ff8c71" }, { gt: 0, lt: 20, color: "#ffd768" }], // First there's a map base this.myChart.setOption(mapOption,true); if(Number(this.options.id)<10){ // Then overlay the chart this.addPieToMap(this.myChart, this.mapDotData.output.value.rows ); }else{ this.addPartPieToMap(this.myChart, this.mapDotData.output.value.rows ) } /* The pie chart moves with the map :pie*/ this.myChart.on('georoam', (params)=> { if(Number(this.options.id)<10){ this.resetDot(this.myChart, params); }else{ this.resetPie(this.myChart, params); } }); }, initMapData(mapJson) { let mapData = []; for (let i = 0; i < mapJson.features.length; i++) { mapData.push({ name: mapJson.features[i].properties.name }); } return mapData; }, // When the browser window size changes , Reload the chart to adapt resizeCharts(){ this.$echarts.init(document.getElementById('mapChart')).resize()
},
// Get map data
async getMapData(map){
if(map=='china'){
await this.drawMapChart(this.curMapName,chinaData[0]);
}else if(map==' Liaoning Province '){
this.drawMapChart(this.curMapName,liaoningPro);
}else{
this.drawMapChart(this.curMapName,shenyangCity);
}
},
// Interface to obtain scatter data
async getMapDotData(){
// Interface to get data
let rows = []
if(Number(this.options.id)<10){
rows =[
{
"xzqmc": " Sichuan Province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Liaoning Province ",
"total": 482.99,
"dw": " Million mu ",
"xzqdm": "540000"
},
{
"xzqmc": " Hunan province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Hubei province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Guizhou Province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Yunnan Province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Qinghai Province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Shaanxi Province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Shanxi Province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Xinjiang Uygur Autonomous Region ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Tibet Autonomous Region ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Ningxia Hui Autonomous Region ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Gansu Province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Henan province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Anhui Province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Shandong Province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Jiangsu Province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Jiangxi Province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
{
"xzqmc": " Fujian Province ",
"total": 9088.51,
"dw": " Million mu ",
"xzqdm": "510000"
},
]
}else{
rows=[
{
"xzqmc":" Liaoning Province ",
"xzqdm":"xxx",
"total":5.3,
"rows":[
{
"name":" Fifth class ",
"value":"26",
},
{
"name":" First class ",
"value":"12",
},
{
"name":" Fourth class place ",
"value":"45",
},
{
"name":" Third class ",
"value":"5",
},
]
},
{
"xzqmc":" Sichuan Province ",
"xzqdm":"xxx",
"total":5.3,
"rows":[
{
"name":" Fifth class ",
"value":"26",
},
{
"name":" First class ",
"value":"12",
},
{
"name":" Fourth class place ",
"value":"45",
},
{
"name":" Third class ",
"value":"5",
},
]
}
]
}
this.mapDotData.output.value.rows = rows
},
// Add scatter chart
addPieToMap(chart,data){
var sd = [];
for (var i = 0; i < data.length; i++) {
var randomValue = 20;
var radius = randomValue;
// var geoCoord = geoCoordMap[data[i].name];
let geoCoord = chinaData[0].features.find((item)=>{
return item.properties.name==data[i].xzqmc
}).properties.center
if (geoCoord) {
var vr = [];
// The data of pie chart is not mapped
vr.push({
name: data[i].xzqmc,
value: data[i].total,
visualMap: false
});
var p = chart.convertToPixel({
seriesIndex: 0
}, geoCoord);
sd.push({
name: data[i].xzqmc,
type: 'pie',
// roseType: 'radius',
// tooltip: {
// formatter: function(params) {
// // return params.seriesName + "<br/>" + params.name + " : " + params.value + ' One hundred million yuan ';
// return params.total + ' mu ';
// }
// },
radius: radius,
center: p,
data: vr,
zlevel: 4,
roam:false,
tooltip: {
formatter: '{a}<br/>{b}: {c} One hundred million yuan ({d}%)'
},
label: {
normal: {
show: true,
position: 'inside',
formatter: '{value|{c}}',
padding:[0,0,radius,0],
rich: {
value: {
fontSize: 12,
color:'#ffffff',
},
},
}
},
labelLine: {
normal: {
show: false
}
},
});
}
}
// Because this component is common , The of configuration items was found series Cannot reset , So here, reset manually in this way
mapOption.series = [ mapOption.series[0]]
mapOption.series = mapOption.series.concat(sd)
this.myChart.setOption(mapOption,true);
return sd;
},
// Reset scatter
resetDot(chart, params) {
var op = chart.getOption();
var ops = op.series;
var currentZoom = this.myChart.getOption().series[0].zoom
let that = this
ops.forEach(function(v, i) {
if (i > 0) {
let geoCoord = chinaData[0].features.find((item)=>{
return item.properties.name==v.name
}).properties.center
var p = chart.convertToPixel({
seriesIndex: 0
}, geoCoord);
v.center = p;
v.label = {
normal: {
show: true,
position: 'inside',
formatter: '{value|{c}}',
padding:[0,0,v.radius * params.zoom||v.radius,0],
rich: {
value: {
fontSize: 12,
color:'#ffffff',
},
},
}
}
// Exceed the maximum and minimum levels of the map Don't stretch this chart any more
if (params != 0 && params.zoom &¤tZoom!=1.5&¤tZoom!=1) {
v.radius = v.radius * params.zoom;
that.lastZoomLevel = params.zoom
return
}
}
});
chart.setOption(op, true);
},
// Add pie chart
addPartPieToMap(chart,data){
var sd = [];
for (var i = 0; i < data.length; i++) {
var randomValue = Math.round(Math.random() * 30);
var radius = randomValue <= 10 ? 10 : randomValue;
let geoCoord = chinaData[0].features.find((item)=>{
return item.properties.name==data[i].xzqmc
}).properties.center
if (geoCoord) {
var vr = [];
// The data of pie chart is not mapped
// vr.push({
// name: data[i].xzqmc,
// value: data[i].total,
// visualMap: false
// });
var p = chart.convertToPixel({
seriesIndex: 0
}, geoCoord);
sd.push({
name: data[i].xzqmc,
type: 'pie',
//clockWise: false,
itemStyle: {
normal: {
label: {
show: false
},
labelLine: {
show: false
},
shadowBlur: 20,
shadowColor: '#203665',
opacity:1,
}
},
tooltip: {
formatter: function(params) {
console.log(' ha-ha ',params)
// return params.seriesName + "<br/>" + params.name + " : " + params.value + ' One hundred million yuan ';
return params.value + ' mu ';
}
},
radius: [20, 30],
// center: ['15%', '50%'],
hoverAnimation: false,
// radius: radius,
center: p,
zlevel: 4,
data: data[i].rows
});
}
}
// Because this component is common , The of configuration items was found series Cannot reset , So here, reset manually in this way
mapOption.series = [ mapOption.series[0]]
mapOption.series = mapOption.series.concat(sd)
this.myChart.setOption(mapOption,true);
return sd;
},
// Reset pie chart
resetPie(chart, params){
var op = chart.getOption();
var ops = op.series;
ops.forEach(function(v, i) {
if (i > 0) {
let geoCoord = chinaData[0].features.find((item)=>{
return item.properties.name==v.name
}).properties.center
var p = chart.convertToPixel({
seriesIndex: 0
}, geoCoord);
v.center = p;
if (params != 0 && params.zoom) {
v.radius = v.radius * params.zoom;
}else if (params != 0 && params.selected) {
var rangeFirstNumber = params.selected[0];
var rangeSecondNumber = params.selected[1];
var pd = v.data[this.typeIndex].value;
if (pd < rangeFirstNumber || pd > rangeSecondNumber) {
// v.itemStyle.normal.opacity = 0;
v.itemStyle = {
normal: {
label: {
show: false
},
labelLine: {
show: false
},
shadowBlur: 20,
shadowColor: '#203665',
opacity:0,
}
}
} else {
// v.itemStyle.normal.opacity = 1;
v.itemStyle = {
normal: {
label: {
show: false
},
labelLine: {
show: false
},
shadowBlur: 20,
shadowColor: '#203665',
opacity:1,
}
}
}
}else{
let zoomVal = chart.getOption().series[0].zoom
let arr = [10, 15]
for(var j = 0;j<arr.length;j++){
arr[j] = arr[j] * zoomVal
}
v.radius = arr
}
}
});
chart.setOption(op, true);
}
},
}
</script>
<style lang="scss" scoped>
.chart{
background-size: 100% 100%;
#mapChart{
width: 100%;
height: 1000px;
}
.mapChoose {
color: #eee;
.title {
padding: 5px;
border-top: 1px solid rgba(132, 219, 233, 0.8);
border-bottom: 1px solid rgba(147, 235, 248, 0.8);
cursor: pointer;
}
.icon {
font-family: 'simsun';
font-size: 25px;
margin: 0 11px;
}
}
}
</style>
copyright notice
author[_ Xiao Zheng is a little sleepy],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2022/119/202204291256537296.html
The sidebar is recommended
- Introduction to basic methods of math built-in objects in JavaScript
- JavaWeb Tomcat (III) httpservlet
- Vue Za wiper technical scheme
- Differences, advantages and disadvantages between HTTP negotiation cache Etag and last modified
- After taking tens of millions less, the management of Lenovo holdings took the initiative to reduce the salary by 70%
- What if Vue introduces this file and reports an error?
- Use Hikvision Web3 in vue3 2. Live broadcast without plug-in version (II)
- How to learn high-order function "zero basis must see"
- Detailed explanation of JS promise
- Cesium drawcommand [1] draw a triangle without talking about the earth
guess what you like
The role of webpack cli in webpack packaging
Action system of coco2d-x-html5
Vxe table check box paging data memory selection problem
[hand tear series] hand tear promise -- this article takes you to realize promise perfectly according to promise a + specification!
QT use qdialog to realize interface mask (mask)
Differences between JSP comments and HTML comments
Bankless: Ethereum's data report and ecological highlights in the first quarter of 22 years
Spring mvc07: Ajax research
Understand the basic history and knowledge of HTTP
JQuery realizes picture switching
Random recommended
- Technology sharing | learning to do test platform development vuetify framework
- Technology sharing | test platform development - Vue router routing design for front-end development
- Return to the top - wepy applet - front end combing
- Install less / sass
- Node. JS basic tutorial
- Have you learned how to use Vue?
- The front end can't calm me down
- Introduction to JavaScript
- Vue
- Technology sharing | learning to do test platform development vuetify framework
- Vue starts with an error and prompts NPM install core- [email protected] // oryarn add core- [email protected]
- STM32 + esp8266 + air202 basic control chapter - 201 - server reverse proxy - server installation nginx (. Windows system)
- STM32 + esp8266 + air202 basic control chapter - 205 - server reverse proxy - Web server configuration HTTPS access (. Windows system)
- Element after the spring frame assembly is opened, the scroll bar returns to the top
- Java project: nursing home management system (java + springboot + thymeleaf + HTML + JS + MySQL)
- Java project: drug management system (java + springboot + HTML + layui + bootstrap + seals + MySQL)
- What are the similarities and differences between jQuery and native JS?
- The starting price is less than 90000 yuan, and the National University's seven seat super value SUV xinjietu x70s is officially pre sold
- Fastadmin modifies the list width (limit the list width, support CSS writing), and the width limit. It is too large or useless.
- Learning ajax in Vue is enough
- Rasa dialogue robot serial 7 lesson 122: rasa dialogue robot debugging project practical bank financial dialogue robot whole life cycle debugging practice - (III)
- CSS foundation-15-drop-down menu
- Only one message prompt pops up in the element UI at a time
- Leetcode 82. Delete duplicate elements in the sorting linked list II
- This beast was blessed with skills to test drive the DHT version of Harvard beast
- Vue Click to switch the background color randomly (small demo)
- In the era of man-machine war, how did Beijing magic cube and artificial intelligence produce chemical reaction
- About nginx + Nacos using domain name connection invalid things
- How strong is the giant wave hybrid blessing when GAC motor shadow cool makes its global debut?
- Layui framework application FAQ
- Layui style optimization
- Post request (http-c4e7.post)
- Is low code a blessing or a challenge for programmers?
- Use the pointer of the array to test the relationship between the two-dimensional elements and the column of the array in the order of "% 1-6", and then use the pointer of the array to output the data in the order of "% 1-6", and then use the pointer of t
- 6-2 pointer and the sum fraction of each column of array matrix 10 this problem requires the implementation of a function to find the sum of each column of a two-dimensional array with n (less than 10) rows and 7 columns. The columns and are stored in a o
- 7-1 find the specified element in the array
- When using uniapp for e-commerce projects, vuex is used to realize the global sharing of data to make shopping cart pages
- JQuery Basics
- `JQuery ` advanced
- Do not leave the market unless necessary! Zhongshan City issued specific requirements for campus epidemic prevention after the May Day holiday