elementUI使用echarts的空气质量地图统计

发布时间 2023-08-23 17:09:07作者: lytcreate

准备工作:

前端安装: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)'})

  页面效果呈现: