前言
本文档旨在指导开发者如何结合 ECharts 和 Vue.js 制作交互式的中国地图,详细介绍了数据绑定和样式设置的具体方法。首先,使用 Axios 从外部获取地图数据,并将其注册到 ECharts 中,以便进行可视化展示。接着,文档深入讲解了如何配置地图的视觉映射、数据系列等关键项,从而实现动态显示和交互效果。为了提升用户体验,我们还提供了一系列实用技巧,包括时间显示的格式化、地图边框的装饰、自定义字体的应用及图表栏的样式调整等。这些内容将帮助开发者快速实现美观且功能丰富的地图展示,增强数据可视化的效果。
地图的制作
<template> <div class="score-map"> <div id="main" ref="main"> </div> </div> </template> <script> import * as echarts from 'echarts'; import 'echarts/extension/bmap/bmap'; import axios from 'axios'; export default { name: 'app', data() { return { } }, mounted() { axios.get("https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json").then((res) => { echarts.registerMap("china", { geoJSON: res.data }) let myChart = echarts.init(document.getElementById("main")); let arr = [ { name: "北京市", value: 54, }, { name: "天津市", value: 13, }, { name: "上海市", value: 40, }, { name: "重庆市", value: 75, }, { name: "河北省", value: 13, }, { name: "河南省", value: 83, }, { name: "云南省", value: 11, }, { name: "辽宁省", value: 19, }, { name: "黑龙江省", value: 15, }, { name: "湖南省", value: 69, }, { name: "安徽省", value: 60, }, { name: "山东省", value: 39, }, { name: "新疆省", value: 4, }, { name: "江苏省", value: 31, }, { name: "浙江省", value: 104, }, { name: "江西省", value: 36, }, { name: "湖北省", value: 1052, }, { name: "广西省", value: 33, }, { name: "甘肃省", value: 7, }, { name: "山西省", value: 9, }, { name: "内蒙古省", value: 7, }, { name: "陕西省", value: 22, }, { name: "吉林省", value: 4, }, { name: "福建省", value: 18, }, { name: "贵州省", value: 5, }, { name: "广东省", value: 98, }, { name: "青海市", value: 1, }, ]; let option = { tooltip: { formmater: '{c}<br />{b1}:{c1}' }, visualMap: { type: "piecewise", show: true, min: 0, max: 1000, left: "17%", bottom: "6%", showLabel: true, // text: ["高", "低"], textStyle: { color: "red", }, pieces: [ // 图例颜色 { min: 10000, max: 999999, label: ">10000", color: "#A9251B", symbol: "roundRect", }, { min: 1000, max: 9999, label: "1000-9999", color: "#D5514D", symbol: "roundRect", }, { min: 100, max: 999, label: "100-999", color: "#E57C6D", symbol: "roundRect", }, { min: 10, max: 99, label: "10-99", color: "#F19D8A", symbol: "roundRect", }, { min: 1, max: 9, label: "1-9", color: "#FBE6DC", symbol: "roundRect", }, { value: 0, label: "0", color: "#ffffff", symbol: "image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAeCAMAAAAB8C7XAAAAeFBMVEUAAADBIhzAIh+/ISDBHSHDHh6jMyHAISDAISC/ISDAIR/AISDAHiG/IR+6RjG+IiC/IiHAICC/IR/AISG+ISG+Ix+/ICDAIiC+IB/AIBzCHh68JRa/IiHAIB+/ISC9IiK/Hx+/IiC+IiK+Ih++ICDCJB/BJB+/ISDiIZL9AAAAJ3RSTlMALfv3HQwG0secl4NTQQPkvLWoo2xpZWFYJBkR693CkIx4WktHMjGv/nLNAAAAp0lEQVQoz4XNVwrEMAxFUcUlvfcyvWn/OxxBMASPxNyPBL9jMPwrNJ9gcwfTLfQt52ueRgqpeLQ0rJnGgP4BHtJNcqE7BNQJvRy0EgwSLBJAJUEnwSSBkQDO/l6XOyTe3lrYexxX1bzAte5TlWT9XFg4FNGs+xJ+SgnuwJQTGA42xYB7pGDhhjiw8ERMWbAKY2CLUYcsZIhvFgrEkYVQYw5s9QR8/tNf+EUpppEdkKMAAAAASUVORK5CYII=", }, ], }, geo: { map: "china", zoom: 1.7, top: "30%", label: { show: true, fontSize: "14", color: "#00D9A9", }, }, series: [ { type: "map", name: "china", geoIndex: 0, data: arr, }, ], }; myChart.setOption(option); }) } } </script> <style scoped> .score-map { width: 100%; } #main { width: 100%; height: 600px; } </style>
步骤
第一步需要映入 china.js 文件
import "@/assets/js/china"
js文件 需要 导出
let a = { b:"1", c:"2", } export default a;
存储代码
在 echarts文件夹下面
<template> <div id='map'> </div> </template> <script> import axios from "axios"; import "@/assets/js/china" import * as echarts from "echarts" import geoCoordMap from "@/assets/js/geoMap" import province from "@/assets/js/province" import test from "@/assets/js/test" export default { name: 'app', data() { return { } }, mounted() { let myChart = echarts.init(document.getElementById("map")); let BJData = province; var convertData = function (data) { var res = []; for (var i = 0; i < data.length; i++) { var dataItem = data[i]; var fromCoord = geoCoordMap[dataItem[0].name]; var toCoord = geoCoordMap[dataItem[1].name]; if (fromCoord && toCoord) { res.push([{ coord: fromCoord, value: dataItem[0].value }, { coord: toCoord, }]); } } return res; }; var series = []; [ ['太原', BJData] ].forEach(function (item, i) { series.push({ type: 'map', map: 'china', geoIndex: 1, layoutCenter: ['50%', '50%'], layoutSize: "125%", selectedMode: 'single', // 可不可以移动 roam: false, itemStyle: { normal: { // 面积 颜色 areaColor: '#00177B', borderColor: '#0073DA', borderWidth: 1 }, emphasis: { label: { show: false }, areaColor: '#00177B' } }, data: [{ name: '山西', selected: false, itemStyle: { areaColor: { type: 'radial', x: 0.5, y: 0.5, r: 0.5, colorStops: [{ offset: 0, color: 'rgba(0,255,255, 0.1)' }, { offset: 1, color: 'rgba(0,255,255, 0.7)' }], global: false // 缺省为 false } } } // selected:true 默认选中 ] }, { type: 'lines', zlevel: 2, effect: { show: true, period: 4, trailLength: 0.02, symbol: 'arrow', symbolSize: 5, }, lineStyle: { normal: { color: '#00FAFA', width: 2, opacity: 0.6, curveness: 0.2 } }, data: convertData(item[1]) }, { type: 'effectScatter', coordinateSystem: 'geo', zlevel: 2, rippleEffect: { period: 4, brushType: 'stroke', scale: 4 }, label: { normal: { show: true, position: 'inside', backgroundColor: 'rgba(1,247,248, 0.1)', formatter: '{b}', padding: [10, 12], borderRadius: 0, // borderWidth: 1, borderColor: 'rgba(0,0,0,0.1)', color: '#FFFFFF', }, emphasis: { show: true } }, symbol: 'circle', symbolSize: function (val) { return 1; }, itemStyle: { normal: { show: false, color: '#fff', shadowBlur: 10, } }, data: item[1].map(function (dataItem) { return { name: dataItem[0].name, value: geoCoordMap[dataItem[0].name].concat([dataItem[0].value]) }; }), }, //被攻击点 { type: 'scatter', coordinateSystem: 'geo', zlevel: 2, rippleEffect: { period: 4, brushType: 'stroke', scale: 4 }, label: { normal: { show: true, position: 'right', color: '#00ffff', formatter: '{b}', textStyle: { color: "#00ffff" } }, emphasis: { show: true } }, symbol: 'circle', symbolSize: 1, itemStyle: { normal: { color: '#fff', shadowBlur: 1, } }, data: [{ name: item[0], value: geoCoordMap[item[0]].concat([100]), }], } ); }); let option = { geo: { map: 'china', label: { emphasis: { show: false } }, roam: false, layoutCenter: ['50%', '50%'], layoutSize: "125%", itemStyle: { normal: { areaColor: '##33a3dc', borderWidth: 3, borderColor: '#00FEFF', shadowColor: 'rgba(3,221,255,0.8)', shadowBlur: 30 } } }, series: series }; myChart.setOption(option) }, methods: { test() { console.log(test); } } } </script> <style scoped> #map { margin-top: 40px; height: 1000px; width: 100%; } </style>
数据可视化
当前时间
mounted() { let t = null t = setTimeout(time, 1000); // 开始执行 function time() { clearTimeout(t) // 清楚 定时器 let dt = new Date() let y = dt.getFullYear() let mt = dt.getMonth() + 1 // 月份 需要 加一 let day = dt.getDate() let h = dt.getHours() // 时 let m = dt.getMinutes() let s = dt.getSeconds(); document.querySelector(".showTime").innerHTML = "当前时间:" + y + "年" + mt + "月" + day + "日" + h + "时" + m + "分" + s + "秒"; t = setTimeout(time, 1000) // 每一秒执行一次 } }
const formatDate = (current_datetime)=>{ return current_datetime.getFullYear() + "-" + (current_datetime.getMonth() + 1) + "-" + current_datetime.getDate() + " " + current_datetime.getHours() + ":" + current_datetime.getMinutes() + ":" + current_datetime.getSeconds(); }
let timer = new Date() let myDate=timer.toLocaleString() console.log(myDate)
给边框加小角
/* 左上角 写一个 小边框 */ /* before 和 after 智能每次加两个 */ .panel::before { position: absolute; top: 0; left: 0; content: ""; width: 10px; height: 10px; border-top: 2px solid #02a6b5; border-left: 2px solid #02a6b5; } .panel::after { position: absolute; top: 0; right: 0; content: ""; width: 10px; height: 10px; border-top: 2px solid #02a6b5; border-right: 2px solid #02a6b5; } /* 需要定位 */ /* 在div 里面 在弄一个div */ .panel .panel-footer { position: absolute; left: 0; bottom: 0; width: 100%; } /* 下 和 左, */ .panel .panel-footer::before { position: absolute; bottom: 0; left: 0; content: ""; width: 10px; height: 10px; border-bottom: 2px solid #02a6b5; border-left: 2px solid #02a6b5; } /* 下和右 */ .panel .panel-footer::after { position: absolute; bottom: 0; right: 0; content: ""; width: 10px; height: 10px; border-bottom: 2px solid #02a6b5; border-right: 2px solid #02a6b5; }
<div class="column"> <div class="panel"> <div class="panel-footer"></div> </div> </div>
改属性
var pageWidth = window.innerWidth; var pageHeight = window.innerHeight;
字体
导入 @font-face { font-family: electronicFont; src: url(../font/DS-DIGIT.TTF); } 使用 font-family: electronicFont; font-weight: bold;
给两个div中间加一条线
.no .no-hd ul li:first-child::after { content: ""; position: absolute; height: 50%; width: 1px; background: rgba(255, 255, 255, 0.2); right: 0; top: 25%; }
bar
mounted() { let chartDom = document.querySelector(".chart") let myChart = echarts.init(chartDom); let myData = [120, 132, 101, 134, 90, 230, 310]; let option = { tooltip: {}, axisTick: { alignWidthLabel: true }, tooltip: { trigger: "axis", axisPointer: { type: "shadow" } }, xAxis: { data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], // 在 那 写 就是那里 使用 axisLabel: { // 坐标轴的 颜色 // color: "red", axisLine: { show: false, } }, }, yAxis: { min: 0, max: 400, // 操作线 axisLine: { show: true, lineStyle: { // 字体颜色 // color: 'red', width: 0 } }, axisLabel: { // 坐标轴的 颜色 // color: "red", }, // 分割线的修改 splitLine: { lineStyle: { color: 'rgba(255,255,255,0.1)' } } }, grid: { left: "6px", top: "50px", right: "0", bottom: "4%", containLabel: true }, series: [{ name: 'people', type: 'bar', barWidth: "38%", data: myData, itemStyle: { barBorderRadius: 5, } }], }; myChart.setOption(option) // 按需缩放 window.addEventListener('resize', function () { myChart.resize(); }) }