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)'})
页面效果呈现:
