elementUI使用echarts的空气质量地图统计
准备工作:
前端安装:yarn install echarts 、 yarn install vue-baidu-map --save
前端在public文件夹下的index.html中 head标签中加入:
<script src="https://api.map.baidu.com/api?v=2.0&ak=你的AK"></script>
其中,key的申请地址:https://lbsyun.baidu.com/apiconsole/key#/home 注册认证后创建浏览器端的应用,粘贴里面的AK到这里
前端页面:
<template> <div> <div style="width: 30%"> <el-form ref="ruleForm" :model="ruleForm" label-width="80px"> <el-form-item label="数据时间"> <el-col :span="10"> <el-form-item> <el-date-picker type="date" placeholder="开始日期" v-model="ruleForm.date1" style="width: 100%;" value-format="yyyy-MM-dd" format="yyyy/MM/dd"></el-date-picker> </el-form-item> </el-col> <el-col class="line" :span="2">-</el-col> <el-col :span="10"> <el-form-item> <el-date-picker type="date" placeholder="结束日期" v-model="ruleForm.date2" style="width: 100%;" value-format="yyyy-MM-dd" format="yyyy/MM/dd"></el-date-picker> </el-form-item> </el-col> <el-col :span="2"> <el-button type="primary" @click="onSubmit">查询</el-button> </el-col> </el-form-item> </el-form> </div> <div class="card-board"> <el-card shadow="hover" class="card-item"> <div slot="header" class="card-header"> 总营业额 </div> <div class="card-content"> <p class="card-value">¥ {{ turnover }}</p> </div> </el-card> <el-card shadow="hover" class="card-item"> <div slot="header" class="card-header"> 总认养销售额 </div> <div class="card-content"> <p class="card-value">¥ {{ adoptionAmount }}</p> </div> </el-card> <el-card shadow="hover" class="card-item"> <div slot="header" class="card-header"> 总商城销售额 </div> <div class="card-content"> <p class="card-value">¥ {{ mallAmount }}</p> </div> </el-card> <el-card shadow="hover" class="card-item"> <div slot="header" class="card-header"> 总订单数 </div> <div class="card-content"> <p class="card-value">{{ totalOrders }}</p> </div> </el-card> <el-card shadow="hover" class="card-item"> <div slot="header" class="card-header"> 总用户数 </div> <div class="card-content"> <p class="card-value">{{ totalUsers }}</p> </div> </el-card> </div> <br> <div> <el-row class="row-container-bottom" :gutter="20"> <el-col :span="6" style="height: 600px; border: 1px solid #DCDCDC"> <div ref="chartLeft" style="width: 100%; height: 600px;">加载中,请稍后...</div> </el-col> <el-col :span="12" style="height: 600px;"> <div ref="chartDom" style="height: 600px; width: 100%;">加载中,请稍后...</div> </el-col> <el-col :span="6" style="height: 600px; border: 1px solid #DCDCDC"> <div ref="chartRight" style="width: 100%; height: 600px;">加载中,请稍后...</div> </el-col> </el-row> </div> </div> </template> <script> import axios from "axios"; import {showError, showSuccess} from "@/api/api"; //////////////////////////////// import * as echarts from 'echarts'; import 'echarts/extension/bmap/bmap'; import {geoCoordMap} from "@/api/city" //////////////////////////////// export default { name: "DataStatistics", data() { return { turnover: "", adoptionAmount: "", mallAmount: "", totalOrders: "", totalUsers: "", ruleForm: { date1: '', date2: '' }, geoCoordMap: geoCoordMap, map_data: [], left_data: [], right_data: [], } }, created() { const today = new Date(); const yesterday = new Date(today); yesterday.setDate(today.getDate() - 1); const weekday = new Date(today); weekday.setDate(today.getDate() - 7); this.ruleForm.date1 = weekday.toISOString().substring(0, 10); this.ruleForm.date2 = yesterday.toISOString().substring(0, 10); this.onSubmit() }, mounted() { document.title = '数据统计' // 睡眠一秒防止数据未被加载 setTimeout(() => { this.echartsLeft() this.echartsRight() this.echartsInit() // 其他代码 }, 1000) }, methods: { onSubmit() { if (this.ruleForm.date1 === '' || this.ruleForm.date1 === null) { const message = "未填写开始日期!" showError(message) } else if (this.ruleForm.date2 === '' || this.ruleForm.date2 === null) { const message = "未填写开始日期!" showError(message) } else { axios.post(this.$webSite + '/manage/datastatistics/', this.ruleForm) .then(response => { // 处理成功响应 if (response.data.code === 200) { showSuccess(response.data.msg) console.log(response.data.data) this.turnover = response.data.data.turnover[0] this.adoptionAmount = response.data.data.adoptionAmount[0] this.totalOrders = response.data.data.totalOrders[0] this.mallAmount = response.data.data.mallAmount[0] this.totalUsers = response.data.data.totalUsers[0] this.map_data = response.data.data.map_data this.left_data = response.data.data.left_data this.right_data = response.data.data.right_data } else { this.turnover = '-' this.adoptionAmount = '-' this.totalOrders = '-' this.mallAmount = '-' this.totalUsers = '-' showError(response.data.msg) } }) .catch(error => { // 处理错误响应 showError("请联系管理员处理!") console.error(error) }); } }, echartsInit() { const chartDom = this.$refs.chartDom; this.myChart = echarts.init(chartDom); // let option; const data = this.map_data; const geoCoordMap = this.geoCoordMap; const convertData = function (data) { var res = []; for (var i = 0; i < data.length; i++) { var geoCoord = geoCoordMap[data[i].name]; if (geoCoord) { res.push({ name: data[i].name, value: geoCoord.concat(data[i].value) }); } } return res; }; this.option = { title: { text: '全国认养用户主要城市分布', subtext: 'data from whole', sublink: '', left: 'center' }, tooltip: { trigger: 'item' }, bmap: { center: [134.6, 39], zoom: 5, roam: false, // 是否允许鼠标滚轮滑动 mapStyle: { styleJson: [ { featureType: 'water', elementType: 'all', stylers: { color: '#66CCFF' } }, { featureType: 'land', elementType: 'all', stylers: { color: '#f3f3f3' } }, { featureType: 'railway', elementType: 'all', stylers: { visibility: 'off' } }, { featureType: 'highway', elementType: 'all', stylers: { color: '#fdfdfd' } }, { featureType: 'highway', elementType: 'labels', stylers: { visibility: 'off' } }, { featureType: 'arterial', elementType: 'geometry', stylers: { color: '#fefefe' } }, { featureType: 'arterial', elementType: 'geometry.fill', stylers: { color: '#fefefe' } }, { featureType: 'poi', elementType: 'all', stylers: { visibility: 'off' } }, { featureType: 'green', elementType: 'all', stylers: { visibility: 'off' } }, { featureType: 'subway', elementType: 'all', stylers: { visibility: 'off' } }, { featureType: 'manmade', elementType: 'all', stylers: { color: '#d1d1d1' } }, { featureType: 'local', elementType: 'all', stylers: { color: '#d1d1d1' } }, { featureType: 'arterial', elementType: 'labels', stylers: { visibility: 'off' } }, { featureType: 'boundary', elementType: 'all', stylers: { color: '#1E90FF' } }, { featureType: 'building', elementType: 'all', stylers: { color: '#32CD32' } }, { featureType: 'label', elementType: 'labels.text.fill', stylers: { color: '#A9A9A9' } } ] } }, series: [ { name: '认养数', type: 'scatter', coordinateSystem: 'bmap', data: convertData(data), color: '#32CD32', symbolSize: function (val) { return val[2] / 10; }, encode: { value: 2 }, label: { formatter: '{b}', position: 'right', show: false, }, emphasis: { label: { show: true, } } }, { name: 'Top5认养数', type: 'effectScatter', coordinateSystem: 'bmap', color: '#FF0000', data: convertData( data.sort(function (a, b) { return b.value - a.value; }) .slice(0, 5) ), symbolSize: function (val) { return val[2] / 10; }, encode: { value: 2 }, showEffectOn: 'render', rippleEffect: { brushType: 'stroke' }, label: { formatter: '{b}', position: 'right', show: true }, itemStyle: { shadowBlur: 20, shadowColor: '#7CFC00' }, emphasis: { scale: true }, zlevel: 1 } ] }; this.option && this.myChart.setOption(this.option); }, echartsLeft() { const chartLeft = this.$refs.chartLeft; const myChart = echarts.init(chartLeft); let option let left_data = this.left_data; setTimeout(function () { const option = { title: {text: '近七天订单数统计'}, legend: { top: '6%', left: '10%' }, tooltip: { trigger: 'axis', showContent: false }, dataset: { source: left_data, }, xAxis: {type: 'category'}, yAxis: {gridIndex: 0}, grid: {top: '55%'}, series: [ { type: 'line', smooth: true, seriesLayoutBy: 'row', emphasis: {focus: 'series'}, color: '#91cc75' }, { type: 'line', smooth: true, seriesLayoutBy: 'row', emphasis: {focus: 'series'}, color: '#fac858' }, { type: 'pie', id: 'pie', radius: '30%', center: ['50%', '25%'], emphasis: { focus: 'self' }, color: ['#91cc75', '#fac858'], label: { formatter: '{b}: ({d}%)' }, // encode: { // itemName: 'product', // value: this.leftValue, // tooltip: this.leftValue // }, } ] }; myChart.on('updateAxisPointer', function (event) { const xAxisInfo = event.axesInfo[0]; if (xAxisInfo) { const dimension = xAxisInfo.value + 1; myChart.setOption({ series: { id: 'pie', label: { formatter: '{d}%' }, encode: { value: dimension, tooltip: dimension } } }); } }); myChart.setOption(option); }); option && myChart.setOption(option); }, echartsRight() { const chartRight = this.$refs.chartRight; const myChart = echarts.init(chartRight); let option let right_data = this.right_data; setTimeout(function () { const option = { title: {text: '近七天销售额统计'}, legend: { top: '6%', left: '10%' }, tooltip: { trigger: 'axis', showContent: false }, dataset: { source: right_data, }, xAxis: {type: 'category'}, yAxis: {gridIndex: 0}, grid: {top: '55%'}, series: [ { type: 'line', smooth: true, seriesLayoutBy: 'row', emphasis: {focus: 'series'}, color: '#87CEFA' }, { type: 'line', smooth: true, seriesLayoutBy: 'row', emphasis: {focus: 'series'}, color: '#FFB6C1' }, { type: 'pie', id: 'pie', radius: '30%', center: ['50%', '25%'], emphasis: { focus: 'self' }, color: ['#87CEFA', '#FFB6C1'], label: { formatter: '{b}:({d}%)' }, // encode: { // value: '', // tooltip: '' // }, } ] }; myChart.on('updateAxisPointer', function (event) { const xAxisInfo = event.axesInfo[0]; if (xAxisInfo) { const dimension = xAxisInfo.value + 1; myChart.setOption({ series: { id: 'pie', label: { formatter: '{d}%' }, encode: { value: dimension, tooltip: dimension } } }); } }); myChart.setOption(option); }); option && myChart.setOption(option); }, } } </script> <style scoped> .card-board { display: flex; justify-content: space-between; } .card-item { width: 18%; } .card-header { background-color: #f5f7fa; text-align: center; font-size: 16px; padding: 10px 0; font-weight: bold; } .card-content { text-align: center; height: 3vh; } .card-value { font-size: 24px; color: #409eff; /*margin-bottom: 10px;*/ margin-top: 10px; } .card-description { font-size: 14px; color: #909399; } </style>
后端处理:
class DataStatistics(APIView): @check_role def post(self, request): try: token = request.META.get('HTTP_AUTHORIZATION') user_name = get_username(token) date_start = request.data.get('date1') date_end = request.data.get('date2') turnover = 200000, adoptionAmount = 50000, mallAmount = 80000, totalOrders = 500, totalUsers = 100, map_data = [ {"name": '海门', "value": 9}, {"name": '鄂尔多斯', "value": 12}, {"name": '招远', "value": 12}, {"name": '舟山', "value": 12}, {"name": '齐齐哈尔', "value": 14}, {"name": '盐城', "value": 15}, {"name": '赤峰', "value": 16}, {"name": '青岛', "value": 299}, {"name": '乳山', "value": 18}, {"name": '金昌', "value": 19}, {"name": '泉州', "value": 21}, {"name": '莱西', "value": 21}, {"name": '日照', "value": 21}, {"name": '胶南', "value": 22}, {"name": '南通', "value": 23}, {"name": '拉萨', "value": 24}, {"name": '云浮', "value": 24}, {"name": '梅州', "value": 25}, {"name": '文登', "value": 25}, {"name": '上海', "value": 25}, {"name": '攀枝花', "value": 25}, {"name": '威海', "value": 25}, {"name": '承德', "value": 25}, {"name": '厦门', "value": 26}, {"name": '汕尾', "value": 26}, {"name": '潮州', "value": 26}, {"name": '丹东', "value": 27}, {"name": '太仓', "value": 27}, {"name": '曲靖', "value": 27}, {"name": '烟台', "value": 28}, {"name": '福州', "value": 29}, {"name": '瓦房店', "value": 30}, {"name": '即墨', "value": 30}, {"name": '抚顺', "value": 31}, {"name": '玉溪', "value": 31}, {"name": '张家口', "value": 31}, {"name": '阳泉', "value": 31}, {"name": '莱州', "value": 32}, {"name": '湖州', "value": 32}, {"name": '汕头', "value": 32}, {"name": '昆山', "value": 33}, {"name": '宁波', "value": 33}, {"name": '湛江', "value": 33}, {"name": '揭阳', "value": 34}, {"name": '荣成', "value": 34}, {"name": '连云港', "value": 35}, {"name": '葫芦岛', "value": 35}, {"name": '常熟', "value": 36}, {"name": '东莞', "value": 36}, {"name": '河源', "value": 36}, {"name": '淮安', "value": 36}, {"name": '泰州', "value": 36}, {"name": '南宁', "value": 37}, {"name": '营口', "value": 37}, {"name": '惠州', "value": 37}, {"name": '江阴', "value": 37}, {"name": '蓬莱', "value": 37}, {"name": '韶关', "value": 38}, {"name": '嘉峪关', "value": 38}, {"name": '广州', "value": 38}, {"name": '延安', "value": 38}, {"name": '太原', "value": 39}, {"name": '清远', "value": 39}, {"name": '中山', "value": 39}, {"name": '昆明', "value": 39}, {"name": '寿光', "value": 40}, {"name": '盘锦', "value": 40}, {"name": '长治', "value": 41}, {"name": '深圳', "value": 41}, {"name": '珠海', "value": 42}, {"name": '宿迁', "value": 43}, {"name": '咸阳', "value": 43}, {"name": '铜川', "value": 44}, {"name": '平度', "value": 44}, {"name": '佛山', "value": 44}, {"name": '海口', "value": 44}, {"name": '江门', "value": 45}, {"name": '章丘', "value": 45}, {"name": '肇庆', "value": 46}, {"name": '大连', "value": 47}, {"name": '临汾', "value": 47}, {"name": '吴江', "value": 47}, {"name": '石嘴山', "value": 49}, {"name": '沈阳', "value": 50}, {"name": '苏州', "value": 50}, {"name": '茂名', "value": 50}, {"name": '嘉兴', "value": 51}, {"name": '长春', "value": 51}, {"name": '胶州', "value": 52}, {"name": '银川', "value": 52}, {"name": '张家港', "value": 52}, {"name": '三门峡', "value": 53}, {"name": '锦州', "value": 54}, {"name": '南昌', "value": 54}, {"name": '柳州', "value": 54}, {"name": '三亚', "value": 54}, {"name": '自贡', "value": 56}, {"name": '吉林', "value": 56}, {"name": '阳江', "value": 57}, {"name": '泸州', "value": 57}, {"name": '西宁', "value": 57}, {"name": '宜宾', "value": 58}, {"name": '呼和浩特', "value": 58}, {"name": '成都', "value": 58}, {"name": '大同', "value": 58}, {"name": '镇江', "value": 59}, {"name": '桂林', "value": 59}, {"name": '张家界', "value": 59}, {"name": '宜兴', "value": 59}, {"name": '北海', "value": 60}, {"name": '西安', "value": 61}, {"name": '金坛', "value": 62}, {"name": '东营', "value": 62}, {"name": '牡丹江', "value": 63}, {"name": '遵义', "value": 63}, {"name": '绍兴', "value": 63}, {"name": '扬州', "value": 64}, {"name": '常州', "value": 64}, {"name": '潍坊', "value": 65}, {"name": '重庆', "value": 66}, {"name": '台州', "value": 67}, {"name": '南京', "value": 67}, {"name": '滨州', "value": 70}, {"name": '贵阳', "value": 71}, {"name": '无锡', "value": 71}, {"name": '本溪', "value": 71}, {"name": '克拉玛依', "value": 72}, {"name": '渭南', "value": 72}, {"name": '马鞍山', "value": 72}, {"name": '宝鸡', "value": 72}, {"name": '焦作', "value": 75}, {"name": '句容', "value": 75}, {"name": '北京', "value": 79}, {"name": '徐州', "value": 79}, {"name": '衡水', "value": 80}, {"name": '包头', "value": 80}, {"name": '绵阳', "value": 80}, {"name": '乌鲁木齐', "value": 84}, {"name": '枣庄', "value": 84}, {"name": '杭州', "value": 84}, {"name": '淄博', "value": 85}, {"name": '鞍山', "value": 86}, {"name": '溧阳', "value": 86}, {"name": '库尔勒', "value": 86}, {"name": '安阳', "value": 90}, {"name": '开封', "value": 90}, {"name": '济南', "value": 92}, {"name": '德阳', "value": 93}, {"name": '温州', "value": 95}, {"name": '九江', "value": 96}, {"name": '邯郸', "value": 98}, {"name": '临安', "value": 99}, {"name": '兰州', "value": 99}, {"name": '沧州', "value": 100}, {"name": '临沂', "value": 103}, {"name": '南充', "value": 104}, {"name": '天津', "value": 105}, {"name": '富阳', "value": 106}, {"name": '泰安', "value": 112}, {"name": '诸暨', "value": 112}, {"name": '郑州', "value": 113}, {"name": '哈尔滨', "value": 114}, {"name": '聊城', "value": 116}, {"name": '芜湖', "value": 117}, {"name": '唐山', "value": 119}, {"name": '平顶山', "value": 119}, {"name": '邢台', "value": 119}, {"name": '德州', "value": 120}, {"name": '济宁', "value": 120}, {"name": '荆州', "value": 127}, {"name": '宜昌', "value": 130}, {"name": '义乌', "value": 132}, {"name": '丽水', "value": 133}, {"name": '洛阳', "value": 134}, {"name": '秦皇岛', "value": 136}, {"name": '株洲', "value": 143}, {"name": '石家庄', "value": 147}, {"name": '莱芜', "value": 148}, {"name": '常德', "value": 152}, {"name": '保定', "value": 153}, {"name": '湘潭', "value": 154}, {"name": '金华', "value": 157}, {"name": '岳阳', "value": 169}, {"name": '长沙', "value": 175}, {"name": '衢州', "value": 177}, {"name": '廊坊', "value": 193}, {"name": '菏泽', "value": 194}, {"name": '合肥', "value": 229}, {"name": '武汉', "value": 273}, {"name": '大庆', "value": 279} ] left_data = [ ['product', '1', '2', '3', '4', '5', '6'], ['认养订单', 50, 82.1, 88.7, 70.1, 53.4, 85.1], ['商城订单', 50, 51.4, 55.1, 53.3, 73.8, 68.7], ] right_data = [ ['product', '1', '2', '3', '4', '5', '6'], ['认养金额', 50, 82.1, 88.7, 70.1, 53.4, 85.1], ['商城金额', 50, 51.4, 55.1, 53.3, 73.8, 68.7], ] return Response( {'code': 200, 'msg': "数据查询成功!", 'data': {'turnover': turnover, 'adoptionAmount': adoptionAmount, 'totalOrders': totalOrders, 'mallAmount': mallAmount, 'totalUsers': totalUsers, 'map_data': map_data, 'left_data': left_data, 'right_data': right_data}}) except Exception as e: print('Error: %s' % e) return Response( {'code': 405, 'msg': '未知错误,请联系管理员!(11000)'})
页面效果呈现: