VUE+Echarts调用天气API显示近日天气情况

一、引入依赖

在这里你可以使用很多前端框架调用echarts,我的项目是vue端app程序,所以在这里就用vue方式引入echarts

1.npm安装

npm install echarts --save
2.Echarts的模板

因为要在一个页面切换选项卡完成不同表格的显示,所以在这里使用一个vue文件,这样就可以根据不同选项卡的点击来个Echarts的options切换数据



<template>
  <div ref="myChart"></div>
</template>


<script>
  export default {
    name: 'echarts',
    props: ['type', 'width', 'height', 'options'],
    data() {
      return {
        init: false,
        opts: null
      }
    },
    watch: {
      opts(val) {
        let echarts = require('echarts/lib/echarts')
        require('./echartsStyle')
        require('echarts/lib/chart/bar')
        require('echarts/lib/chart/line')
        require('echarts/lib/chart/pie')
        require('echarts/lib/chart/radar')
        require('echarts/lib/chart/funnel')
        require('echarts/lib/chart/gauge')
        require('echarts/lib/chart/map')
        require('echarts/lib/component/tooltip')
        require('echarts/lib/component/title')
        require('echarts/lib/component/legend')
        let myChart;
        if (this.init) {
          myChart = echarts.getInstanceByDom(this.$refs.myChart)
        } else {
          myChart = echarts.init(this.$refs.myChart, 'echartsStyle')
          this.init = true
        }
        myChart.setOption(val, true)
      },
      options(val) {
        this.opts = val
      }
    },
    mounted() {
      this.opts = this.options
      this.$refs.myChart.style.width = this.width + 'px'
      this.$refs.myChart.style.height = this.height + 'px'
    }
  }
</script>


这里面还引入了自定义的样式ecahrtsStyle.js文件,其实你也可以完全省略掉这一步



var echarts = require('echarts/lib/echarts')
var colorPalette = ['#2ec7c9', '#b6a2de', '#5ab1ef', '#ffb980', '#d87a80', '#8d98b3', '#e5cf0d', '#97b552', '#95706d', '#dc69aa', '#07a2a4', '#9a7fd1', '#588dd5', '#f5994e', '#c05050', '#59678c', '#c9ab00', '#7eb00a', '#6f5553', '#c14089']


var theme = {
  color: colorPalette,
  title: {
    textStyle: {
      fontWeight: 'normal',
      color: '#008acd'
    }
  },


  visualMap: {
    itemWidth: 15,
    color: ['#5ab1ef', '#e0ffff']
  },


  toolbox: {
    iconStyle: {
      normal: {
        borderColor: colorPalette[0]
      }
    }
  },


  tooltip: {
    backgroundColor: 'rgba(50,50,50,0.5)',
    axisPointer: {
      type: 'line',
      lineStyle: {
        color: '#ff0000'
      },
      crossStyle: {
        color: '#008acd'
      },
      shadowStyle: {
        color: 'rgba(200,200,200,0.2)'
      }
    }
  },


  dataZoom: {
    dataBackgroundColor: '#efefff',
    fillerColor: 'rgba(182,162,222,0.2)',
    handleColor: '#008acd'
  },


  grid: {
    borderColor: '#eee'
  },


  categoryAxis: {
    axisLine: {
      lineStyle: {
        color: '#008acd'
      }
    },
    splitLine: {
      lineStyle: {
        color: ['#eee']
      }
    }
  },


  valueAxis: {
    axisLine: {
      lineStyle: {
        color: '#008acd'
      }
    },
    splitArea: {
      show: true,
      areaStyle: {
        color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)']
      }
    },
    splitLine: {
      lineStyle: {
        color: ['#eee']
      }
    }
  },


  timeline: {
    lineStyle: {
      color: '#008acd'
    },
    controlStyle: {
      normal: {
        color: '#008acd'
      },
      emphasis: {
        color: '#008acd'
      }
    },
    symbol: 'emptyCircle',
    symbolSize: 3
  },


  line: {
    smooth: true,
    symbol: 'emptyCircle',
    symbolSize: 3
  },


  candlestick: {
    itemStyle: {
      normal: {
        color: '#d87a80',
        color0: '#2ec7c9',
        lineStyle: {
          color: '#d87a80',
          color0: '#2ec7c9'
        }
      }
    }
  },


  scatter: {
    symbol: 'circle',
    symbolSize: 4
  },


  map: {
    label: {
      normal: {
        textStyle: {
          color: '#d87a80'
        }
      }
    },
    itemStyle: {
      normal: {
        borderColor: '#eee',
        areaColor: '#ddd'
      },
      emphasis: {
        areaColor: '#fe994e'
      }
    }
  },


  graph: {
    color: colorPalette
  },


  gauge: {
    axisLine: {
      lineStyle: {
        color: [[0.2, '#2ec7c9'], [0.8, '#5ab1ef'], [1, '#d87a80']],
        width: 10
      }
    },
    axisTick: {
      splitNumber: 10,
      length: 15,
      lineStyle: {
        color: 'auto'
      }
    },
    splitLine: {
      length: 22,
      lineStyle: {
        color: 'auto'
      }
    },
    pointer: {
      width: 5
    }
  }
}


echarts.registerTheme('echartsStyle', theme)


二、操作页面

1.引用Echars.vue

导入刚刚的创建的vue:

import Echarts from '../util/Echarts'
import axios from 'axios'

按钮的内容:

<echarts :type="active" :width="screenWidth" :height="screenHeight-160" :options="options[active]"></echarts>


<mt-tabbar v-model="active">
  <mt-tab-item id="wea"><span style="display:inline-block;padding: 6px">最近天气</span></mt-tab-item>
  <mt-tab-item id="shi"><span style="display:inline-block;padding: 6px">今日湿度</span></mt-tab-item>
  <mt-tab-item id="oth"><span style="display:inline-block;padding: 6px">详细温度</span></mt-tab-item>
</mt-tabbar>
2.具体方法






  data () {
    return {
      active: 'wea',
      options: {
        wea: {},
        oth: {},
        shi: {},
      }
    }
  },
  mounted(){
    this.loadWeatherInfo()
  },
  methods:{
    loadWeatherInfo() {
      var self = this;
      axios.get('https://tianqiapi.com/api?version=v1&appid=xxx&appsecret=xxx')
        .then((res) => {
          console.log(res.data)
          let d = res.data


          let dayArr = [], // 未來七天
            maxArr = [], // 最高氣溫
            minArr = [], // 最低氣溫
            weaArr = [], // 氣溫
            airArr = [], // 空氣質量
            dateArr = [], // 日期數據
            hourArr = [], // 今日小時數據
            hweaArr = []; // 小時氣溫數據


          for (let i = 0; i < d.data.length; i++) {
            let nowRow = d.data[i]
            dayArr.push(nowRow.day)
            maxArr.push(nowRow.tem1.substr(0, nowRow.tem1.length - 1))
            minArr.push(nowRow.tem2.substr(0, nowRow.tem2.length - 1))
            weaArr.push(nowRow.wea)
            airArr.push(nowRow.air_level)
            dateArr.push(nowRow.date)
          }


          for (let h = 0; h < d.data[0].hours.length; h++) {
            let nowHR = d.data[0].hours[h]
            hourArr.push(nowHR.day.substr(nowHR.day.lastIndexOf("日") + 1, nowHR.day.length))
            hweaArr.push(nowHR.tem.substr(0, nowHR.tem.length - 1))
          }
      
    // 設置Echarts所需的天氣option數據
    // 設置Echarts所需的湿度option數據
    // 設置Echarts所需的详细气温option數據
    // 代码在下面


        })
        // 輸出錯誤請求
        .catch((err) => {
          console.log(err);
        });
    }
3.数据渲染

折线图



// 設置Echarts所需的天氣option數據
self.options.wea = {
  title: {
    text: d.city + '最近温度', padding: 20
  },
  tooltip: {
    trigger: 'axis',
    formatter: function (params, ticket, callback) {
      var htmlStr = '';
      for (var j = 0; j < params.length; j++) {
        var param = params[j];
        var xName = param.name; // x轴的名称
        var seriesName = param.seriesName; // 图例名称
        var value = param.value == undefined ? '未知' : param.value; // y轴值
        if (j === 0) {
          htmlStr += xName + '<br/>';//x轴的名称
        }
        htmlStr += '<div>';
        if (seriesName === "最高温度" || seriesName === "最低温度") {
          htmlStr += seriesName + ':' + value + '℃<br/>';
        } else {
          htmlStr += seriesName + ':' + value + "<br/>";
        }
        htmlStr += '</div>';
      }
      return htmlStr;
    }
  },
  legend: {
    data: ['最高温度', '最低温度'], padding: [20, 20, 20, 200]
  },
  grid: {
    left: '5%', right: '10%', bottom: '10%', containLabel: true
  },
  toolbox: {
    feature: {
      saveAsImage: {}
    }
  },
  xAxis: {
    type: 'category',
    boundaryGap: false,
    data: dayArr,
    axisLabel: {
      inside: false,
      textStyle: {
        color: '#000',
        fontSize: '8',
      }
    }
  },
  yAxis: {
    type: 'value',
    boundaryGap: ['0%', '20%'],
    axisLabel: {formatter: '{value}℃'}
  },
  series: [
    {
      name: '最高温度',
      type: 'line',
      stack: 'tem1',
      color: 'red',
      smooth: true,
      data: maxArr
    },
    {
      name: '最低温度',
      type: 'line',
      stack: 'tem2',
      color: 'blue',
      smooth: true,
      data: minArr
    },
    {name: '日期', type: 'bar', data: dateArr},
    {name: '天气', type: 'bar', data: weaArr},
    {name: '空气质量', type: 'bar', data: airArr}
  ]
}
仪表盘

// 設置Echarts所需的濕度option數據
self.options.shi = {
  tooltip: {
    formatter: '{a} <br/>{b} : {c}%'
  },
  toolbox: {
    feature: {
      restore: {},
      saveAsImage: {}
    }
  },
  series: [{
    name: '今日湿度',
    type: 'gauge',
    detail: {
      formatter: '{value}%'
    },
    data: [{
      value: d.data[0].humidity,
      name: '湿度'
    }]
  }]
}


柱形图



// 設置Echarts所需的詳細option數據
self.options.oth = {
  title: {
    text: '今日小时温度'
  },
  legend: {
    data: '温度℃'
  },
  toolbox: {
    // y: 'bottom',
    feature: {
      magicType: {
        type: ['tem']
      },
      dataView: {},
      saveAsImage: {
        pixelRatio: 2
      }
    }
  },
  tooltip: {},
  xAxis: {
    data: hourArr,
    splitLine: {
      show: false
    }
  },
  yAxis: {
    type: 'value',
    boundaryGap: ['0%', '20%'],
    axisLabel: {formatter: '{value}℃'}
  },
  series: [{
    name: '温度',
    type: 'bar',
    data: hweaArr,
    itemStyle: {
      normal: {
        label: {
          show: true, //开启显示
          position: 'top', //在上方显示
          textStyle: { //数值样式
            color: 'black',
            fontSize: 10,
          },
          formatter: '{c}℃',
        }
      }
    },
    animationDelay: function (idx) {
      return idx * 10;
    }
  }],
  animationEasing: 'elasticOut',
  animationDelayUpdate: function (idx) {
    return idx * 5;
  }
}


4.调用api

这个就没啥说的了,我直接在本页面导入axios,当然你们可以封装http来调用接口。接口网上很多的,例举免费的:

1.第一个替换citykey即可,城市编码,即调即用

http://wthrcdn.etouch.cn/weather_mini?citykey=101020100

2.第二个注册一个账号即可用,3小时刷新一次天气数据,很全面

https://tianqiapi.com/api?version=v1&appid=xxx&appsecret=xxx

总结

无非就是调用了天气接口返回json,自行封装,然后给echarts设值就可以完成这些功能了





作者:小码哥

欢迎关注微信公众号 :码出宇宙

扫描添加好友邀你进技术交流群,加我时注明【姓名+公司(学校)+职位】