Skip to content

天气趋势 A

作者:江月迟迟
发表于:2024-12-10
字数统计:2091 字
预计阅读7分钟

介绍

日常生活中,气象数据对于人们的生活具有非常重要的意义,数据的表现形式多种多样,使用图表进行展示使数据在呈现上更加直观。

本题请实现一个 Y 城 2022 年的天气趋势图。

准备

开始答题前,需要先打开本题的项目代码文件夹,目录结构如下:

txt
├── css
│   └── style.css
├── effect-1.gif
├── effect-2.gif
├── index.html
└── js
    ├── axios.js
    ├── echarts.min.js
    ├── vue.min.js
    └── weather.json

其中:

  • css/style.css 是样式文件。
  • index.html 是主页面。
  • js/axios.js 是 axios 文件。
  • js/vue.min.js 是 vue2.x 文件。
  • js/echarts.min.js 是 echarts 文件。
  • js/weather.json 是请求需要用到的天气数据。
  • effect-1.gif 是当月和未来七天切换的效果图。
  • effect-2.gif 是最终完成的效果图。

注意:打开环境后发现缺少项目代码,请手动键入下述命令进行下载:

bash
cd /home/project
wget https://labfile.oss.aliyuncs.com/courses/9788/08.zip && unzip 08.zip && rm 08.zip

在浏览器中预览 index.html 页面效果如下:

初始效果

目标

请在 index.html 文件中补全代码,具体需求如下:

  1. 完成数据请求(数据来源 ./js/weather.json),weather.json 中存放的数据为 12 个月对应的温度数据。在项目目录下已经提供了 axios,考生可自行选择是否使用。注意:调试完成后请将请求地址写死为 ./js/weather.json
  2. data 中的月份数据 monthList, 在 class=month 标签下面的 li 上完成渲染,点击月份则切换对应月份的温度数据同时被点击的月份会变成激活状态( .active 类),x 轴为日期,y 轴为温度,默认显示 1 月份数据。

目标2示例图

  1. 如果点击的月份是当天(通过时间函数动态获取的时间)所在月份,本月和未来七天切换的 tab (即 id=currentMonth 元素)显示,其他月份 currentMonth 元素不显示。
  • 默认显示本月数据。
  • 点击本月显示当月数据,点击未来七天显示从当天(包含当天)开始未来七天的数据,当显示未来七天数据时 x 轴需要显示为月/日格式。
  • 点击 tab本月未来七天会切换激活状态(.active)。

以当天为 5 月 29 号为例,未来七天 x 轴显示示例(即 x 轴显示成:5/29,5/30,5/31,6/1,6/2,6/3,6/4):

目标3示例图

本月未来七天 切换效果见文件夹下 effect-1.gif

最终效果见文件夹下面的 gif 图,图片名称为 effect-2.gif(提示:可以通过 VS Code 或者浏览器预览 gif 图片)

规定

  • 请求地址为./js/weather.json,切勿写成其他地址格式,以免造成无法判题通过。
  • 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径、class 名、id 名、图片名等,以免造成无法判题通过。

判分标准

  • 完成目标 1,得 5 分。
  • 完成目标 2,得 5 分。
  • 完成目标 3,得 10 分。

题解

这题我把火星子都搓出来了,下面代码业务是实现的,不过逻辑可能有可以优化的地方。让我学习一下视频讲解 视频讲解

题解的函数调用更为合理,对日期的判断使用内置函数来判断,可以不用手动写函数,推迟一天。然后忘了一点v-for遍历对象用三个属性:(val, key, index) in Object.

js
for(let i = 0; i < 7; i++) {
   let now = new Date()
   now.setTime(now.getTime() + 1000 * 60 * 60 * 24 * i)
   newX.push(`${now.getMonth() + 1}/${now.getDate()}`)
   newY.push(this.list[now.getMonth()][now.getDate() - 1])
}
[this.xData, this.yData] = [newX, newY]
this.initChart
js
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>天气趋势</title>
    <meta
      name="viewport"
      content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"
    />
    <link rel="stylesheet" type="text/css" href="css/style.css" />
    <script src="./js/axios.js"></script>
    <script src="js/vue.min.js" type="text/javascript" charset="utf-8"></script>
    <script
      src="js/echarts.min.js"
      type="text/javascript"
      charset="utf-8"
    ></script>
  </head>

  <body>
    <div id="app">
      <div class="top-bar">2022年 Y 城全年温度统计图</div>
      <!-- 主体 -->
      <div class="container">
        <!-- 月份 -->
        <div class="month">
          <ul>
            <!-- TODO:待补充代码 在下面的 li 标签中完成 12个月份 (即 monthList) 的渲染  -->
            <li :class="value === showMonth ? 'active' : ''" v-for="(value, key) in monthList" @click="changeMonth(value)">{{ value }}</li>
          </ul>
        </div>
        <div class="chart">
          <!-- TODO:待补充代码  -->
          <!-- currentMonth  未来七天和本月 tab 切换,只有当前月才显示 -->
          <div id="currentMonth" v-if="showIndex === new Date().getMonth() + 1">
            <div class="title">
              <h3>{{!isCurentMonth ? '未来7天天气' : '本月天气'}}</h3>
              <div class="type">
                <span id="seven" :class="!isCurentMonth ? 'active' : ''" @click="changeSeven(true)">未来7天</span>
                <span id="current" :class="isCurentMonth ? 'active' : ''" @click="changeSeven(false)">本月</span>
              </div>
            </div>
          </div>
          <div id="chart"></div>
        </div>
      </div>
    </div>
  </body>
</html>
<script>
  // TODO:待补充代码
  var vm = new Vue({
    el: "#app",
    data: {
      chart: null, // 图表
      chartOptions: null, // 图表配置项
      typeTitle: "本月天气",
      monthList: {
        January: "1月",
        February: "2月",
        March: "3月",
        April: "4月",
        May: "5月",
        June: "6月",
        July: "7月",
        August: "8月",
        September: "9月",
        October: "10月",
        November: "11月",
        December: "12月",
      },
      list: [],
      // showMonth: (new Date().getMonth() + 1).toString() + '月', 
      // showIndex: new Date().getMonth() + 1,
      showIndex: 1,
      showMonth: '1月',
      isCurentMonth: true,
      sevenXaixs: [],
      sevenData: []
    },
    mounted: function () {
      // 先进行axios请求,然后初始化 echarts
      axios.get('./js/weather.json').then(res => {
        this.list = res.data.map(item => {
          return Object.values(item)[0]
        })
        this.$nextTick(() => {
        this.initChart();
        })
      })
       
    },
    methods: {
      initChart() {
        // 初始化图表
        this.chart = echarts.init(document.getElementById("chart"));
        // 配置项
        this.chartOptions = {
          grid: {
            top: 35,
            bottom: 5,
            left: 10,
            right: 10,
            containLabel: true,
          },
          tooltip: {
            trigger: "axis",
            axisPointer: {
              lineStyle: {
                color: {
                  type: "linear",
                  x: 0,
                  y: 0,
                  x2: 0,
                  y2: 1,
                  colorStops: [
                    {
                      offset: 0,
                      color: "rgba(255,255,255,0)",
                    },
                    {
                      offset: 0.5,
                      color: "rgba(255,255,255,1)",
                    },
                    {
                      offset: 1,
                      color: "rgba(255,255,255,0)",
                    },
                  ],
                  global: false,
                },
              },
            },
          },
          xAxis: [
            {
              type: "category",
              boundaryGap: false,
              axisLabel: {
                formatter: "{value}",
                fontSize: 12,
                margin: 20,
                textStyle: {
                  color: "#bfbfbf",
                },
              },
              axisLine: {
                lineStyle: {
                  color: "#e9e9e9",
                },
              },
              splitLine: {
                show: true,
                lineStyle: {
                  color: "#f7f7f7",
                },
              },
              axisTick: {
                show: false,
              },
              // x 轴显示的数据,日期
              data: !this.isCurentMonth ? this.sevenXaixs : [
                1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
                19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
              ],
            },
          ],
          yAxis: [
            {
              boundaryGap: false,
              type: "value",
              axisLabel: {
                textStyle: {
                  color: "#bfbfbf",
                },
                formatter: `{value}\u2103`,
              },
              nameTextStyle: {
                color: "#fff",
                fontSize: 12,
                lineHeight: 40,
              },
              splitLine: {
                lineStyle: {
                  color: "#f7f7f7",
                },
              },
              axisLine: {
                show: true,
                lineStyle: {
                  color: "#e9e9e9",
                },
              },
              axisTick: {
                show: false,
              },
            },
          ],
          series: [
            {
              name: "天气",
              type: "line",
              smooth: false,
              showSymbol: false,
              symbolSize: 0,
              zlevel: 3,
              itemStyle: {
                color: "#ff6600",
                borderColor: "#a3c8d8",
              },
              lineStyle: {
                normal: {
                  width: 3,
                  color: "#ff6600",
                },
              },
              areaStyle: {
                normal: {
                  color: new echarts.graphic.LinearGradient(
                    0,
                    0,
                    0,
                    1,
                    [
                      {
                        offset: 0,
                        color: "#ff6600",
                      },
                      {
                        offset: 0.8,
                        color: "#ff9900",
                      },
                    ],
                    false
                  ),
                },
              },
              //  Y 轴显示的数据,即温度数据
              data: !this.isCurentMonth ? this.sevenData : this.list[this.showIndex - 1],
            },
          ],
        };

        // 调用此方法设置 echarts 数据
        this.chart.setOption(this.chartOptions);
      },
      changeMonth(value) {
        this.showMonth = value
        let charArr = value.split('')
        charArr.pop()
        this.showIndex = parseInt(charArr.join(''))
        this.isCurentMonth = true
        this.$nextTick(() => {
        this.initChart();
      })
      },
      changeSeven(flag) {
        this.isCurentMonth = !flag
        // 处理七天数据和七天轴
        if (this.isCurentMonth === false) {
          let sevenData = []
          let sevenXaixs = []
          let count = 0
          let month = new Date().getMonth() + 1
          let date = new Date().getDate()
          for(let i = date; i < this.list[month - 1].length; i++) {
            sevenData.push(this.list[month - 1][i - 1])
            sevenXaixs.push(month.toString() + '/' + i.toString())
          }
          console.log(sevenData);
          console.log(sevenXaixs);
          if (sevenData.length > 7) {
            sevenData = sevenData.splice(0,7)
            sevenXaixs = sevenXaixs.splice(0, 7)
          } else {
            while (sevenData.length < 7) {
              sevenData.push(this.list[month][count++])
              sevenXaixs.push((month + 1).toString() + '/' + count.toString())
            }
          }
          this.sevenXaixs = sevenXaixs
          this.sevenData = sevenData
          console.log(sevenData);
          console.log(sevenXaixs);


        }
        this.$nextTick(() => {
        this.initChart();
        
      })
      }
    },
  });
</script>