SpringBoot+Vue+Echarts實現選擇時間范圍內數據加載顯示柱狀圖


場景

若依前后端分離版本地搭建開發環境並運行項目的教程:

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108465662

在上面搭建架構的基礎上,實現使用ElementUI的el-date-picker選擇一段時間范圍,

統計后台數據庫中對應時間內的記錄數並在柱狀圖中顯示。

 

 

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi
關注公眾號
霸道的程序猿
獲取編程相關電子書、教程推送與免費下載。

實現

1、后台設計數據庫,新建帶時間字段的表

DROP TABLE IF EXISTS `bus_blog`;
CREATE TABLE `bus_blog`  (
  `id` int(0) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `add_time` datetime(0) NOT NULL COMMENT '添加時間',
  `blog_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '名稱',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '博客表' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

然后表中添加幾條帶時間的數據

 

 

2、使用若依自帶的代碼生成工具生成前后端代碼和菜單數據。

在實體類中添加開始時間和結束時間兩個字段,用來接收和傳遞時間范圍字段

package com.ruoyi.system.domain;

import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;

/**
 * 博客對象 bus_blog
 *
 * @author ruoyi
 * @date 2021-11-25
 */
public class BusBlog extends BaseEntity
{
    private static final long serialVersionUID = 1L;

    /** id */
    private Long id;

    /** 添加時間 */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "添加時間", width = 30, dateFormat = "yyyy-MM-dd")
    private Date addTime;

    /** 名稱 */
    @Excel(name = "名稱")
    private String blogName;

    //開始時間
    private String beginDate;

    //結束時間
    private String endDate;

    public String getBeginDate() {
        return beginDate;
    }

    public void setBeginDate(String beginDate) {
        this.beginDate = beginDate;
    }

    public String getEndDate() {
        return endDate;
    }

    public void setEndDate(String endDate) {
        this.endDate = endDate;
    }

    public void setId(Long id)
    {
        this.id = id;
    }

    public Long getId()
    {
        return id;
    }
    public void setAddTime(Date addTime)
    {
        this.addTime = addTime;
    }

    public Date getAddTime()
    {
        return addTime;
    }
    public void setBlogName(String blogName)
    {
        this.blogName = blogName;
    }

    public String getBlogName()
    {
        return blogName;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("id", getId())
            .append("addTime", getAddTime())
            .append("blogName", getBlogName())
            .toString();
    }
}

3、修改Controller層的獲取數據的接口

    @GetMapping("/list")
    public AjaxResult list(BusBlog busBlog)
    {
        BusBlog indexModel=new BusBlog();
        //構造返回數據,注意這里需要用LinkedHashMap
        Map<String,Integer> resultMap = new LinkedHashMap<String,Integer>();
        if(null!= busBlog.getBeginDate() && null!= busBlog.getEndDate()) {
            //獲取請求參數,開始時間和結束時間
            indexModel.setBeginDate(busBlog.getBeginDate());
            indexModel.setEndDate(busBlog.getBeginDate());
            List<String> rangeData = new ArrayList<String>();
            //查詢數據庫獲取指定時間內的數據
            rangeData = busBlogService.selectBlogCountByDate(busBlog);
            if (rangeData.size() >= 0) {
                // 日期格式化
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                try {
                    // 起始日期
                    Date d1 = sdf.parse(busBlog.getBeginDate());
                    // 結束日期
                    Date d2 = sdf.parse(busBlog.getEndDate());
                    Date tmp = d1;
                    Calendar dd = Calendar.getInstance();
                    dd.setTime(d1);
                    while (tmp.getTime() < d2.getTime()) {
                        int dayCount = 0;
                        tmp = dd.getTime();
                        //獲取查詢的數據每天的檔案數量
                        for (String oneDay:rangeData) {
                            Date oneDayDate = sdf.parse(oneDay);
                            if(oneDayDate.toString().equals(tmp.toString()))
                            {
                                dayCount++;
                            }
                        }
                        resultMap.put(sdf.format(tmp),dayCount);
                        // 天數加上1
                        dd.add(Calendar.DAY_OF_MONTH, 1);
                    }
                    System.out.println(resultMap);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
        return AjaxResult.success(resultMap);
    }

4、Service層和mapper略過

都是如下返回格式和請求數據格式

public List<String> selectBlogCountByDate(BusBlog queryParam);

5、mapper.xml具體查詢sql實現

    <select id="selectBlogCountByDate" parameterType="BusBlog" resultType="java.lang.String">
        SELECT
            add_time
        FROM
        bus_blog
        <where>
            <if test="beginDate != null">
                AND date_format(add_time,'%y%m%d') >=  date_format(#{beginDate},'%y%m%d')
            </if>
            <if test="endDate != null">
                AND date_format(#{endDate},'%y%m%d')  >=  date_format(add_time,'%y%m%d')
            </if>
        </where>

6、最終后台返回的數據格式為

 

 

7、前端新建一個組件BarChartDateRange.vue用來顯示柱狀圖

 

 

組件代碼:

<template>
  <div :style="{ height: '300px', width: '300px' }" />
</template>

<script>
import echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import request from '@/utils/request'
import { formatDate } from "@/utils/index";

export default {
  name: "BarChartDateRange",
  data() {
    return {
      chart: null,
      typeData: [
        { product: "2021.11.23", 博客數: 20 },
        { product: "2021.11.24", 博客數: 30 },
        { product: "2021.11.25", 博客數: 35 },
        { product: "2021.11.26", 博客數: 43 },
      ],
      yAxisMax: 0,
      queryParam: {
        beginDate: null,
        endDate: null,
      },
    };
  },
  created() {
    //默認開始時間為一周前
    this.queryParam.beginDate = formatDate(
      new Date().getTime() - 60 * 1000 * 60 * 24 * 6
    );
    //默認結束時間時間當前時間
    this.queryParam.endDate = formatDate(new Date().getTime());
    this.getList().then((response) => {
      var res = response.data;
      if (res) {
        //清空柱狀圖的數據源
        this.typeData = [];
        //遍歷后台響應數據,構造柱狀圖數據源
        for (var key in res) {
          this.typeData.push({ product: key, 博客數: res[key] });
        }
      }
      this.initChart(this.typeData);
    });
  },
  mounted() {},
  methods: {
    //調用后台接口查詢數據
    getList() {
      return request({
        url: "/system/blog/list",
        method: "get",
        params: this.queryParam,
      });
    },
    //父組件調用子組件的該方法進行重新渲染柱狀圖
    getSelectedRangeList(range) {
      var startDate = range[0];
      var endDate = range[1];
      this.queryParam.beginDate = startDate;
      this.queryParam.endDate = endDate;
      this.getList().then((response) => {
        var res = response.data;
        if (res) {
          this.typeData = [];
          for (var key in res) {
            this.typeData.push({ product: key, 博客數: res[key] });
          }
        }
        this.initChart(this.typeData);
      });
    },
    initChart(typeData) {
      this.chart = echarts.init(this.$el, "macarons");
      this.chart.setOption({
        tooltip: {
          trigger: "axis",
          axisPointer: {
            // 坐標軸指示器,坐標軸觸發有效
            type: "shadow", // 默認為直線,可選為:'line' | 'shadow'
          },
        },
        grid: {
          top: 10,
          left: "2%",
          right: "2%",
          bottom: "3%",
          containLabel: true,
        },
        legend: {
          //圖例
          data: ["博客數"],
        },
        xAxis: [
          {
            type: "category",
            axisPointer: {
              type: "shadow",
            },
            axisLabel: {
              interval: 0,
              rotate: 40,
            },
          },
        ],
        yAxis: [
          {
            type: "value",
            name: "單位:(條)",
            min: 0,
            max: 30,
            interval: 10,
            axisLabel: {
              formatter: "{value}",
            },
          },
        ],
        dataset: {
          source: typeData,
        },
        series: [
          {
            name: "博客數",
            type: "bar",
            barWidth: "40%",
          },
        ],
      });
    },
  },
};
</script>

8、然后在主頁面中引入該組件

import BarChartDateRange from "@/components/Echarts/BarChartDateRange";

export default {
  name: "Blog",
  components: {
    BarChartDateRange,
  },

並且在主頁面添加時間范圍選擇組件

  <div>
    <div>
      <BarChartDateRange ref="BarChartDateRange"></BarChartDateRange>
    </div>
    <div class="block">
      <el-date-picker
        size="large"
        type="daterange"
        v-model="value1"
        range-separator=""
        start-placeholder="開始日期"
        end-placeholder="結束日期"
        @change="dateSelectChange"
        :value-format="dateFormat"
      >
      </el-date-picker>
    </div>
  </div>

設置時間選擇組件的改變事件

@change="dateSelectChange"

實現該方法

    /** 查詢博客列表 */
      dateSelectChange(val) {
      if (val) {
        var startDate = new Date(val[0]).getTime();
        var endDate = new Date(val[1]).getTime();
        debugger;
        if (endDate - startDate > 6 * 24 * 60 * 60 * 1000) {
          this.$message({
            message: "所選時間范圍不能大於7天",
            type: "warning",
          });
        }else{
           this.$refs.BarChartDateRange.getSelectedRangeList(val);
        }
      }
    },

獲取選擇的時間進行范圍校驗,然后通過

 this.$refs.BarChartDateRange.getSelectedRangeList(val);

調用子組件的方法重新查詢數據並渲染柱狀圖

子組件需要聲明ref

<BarChartDateRange ref="BarChartDateRange"></BarChartDateRange>

在子組件中方法實現

    //父組件調用子組件的該方法進行重新渲染柱狀圖
    getSelectedRangeList(range) {
      var startDate = range[0];
      var endDate = range[1];
      this.queryParam.beginDate = startDate;
      this.queryParam.endDate = endDate;
      this.getList().then((response) => {
        var res = response.data;
        if (res) {
          this.typeData = [];
          for (var key in res) {
            this.typeData.push({ product: key, 博客數: res[key] });
          }
        }
        this.initChart(this.typeData);
      });
    },

9、柱狀圖組件完整示例代碼

<template>
  <div :style="{ height: '300px', width: '300px' }" />
</template>

<script>
import echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import request from '@/utils/request'
import { formatDate } from "@/utils/index";

export default {
  name: "BarChartDateRange",
  data() {
    return {
      chart: null,
      typeData: [
        { product: "2021.11.23", 博客數: 20 },
        { product: "2021.11.24", 博客數: 30 },
        { product: "2021.11.25", 博客數: 35 },
        { product: "2021.11.26", 博客數: 43 },
      ],
      yAxisMax: 0,
      queryParam: {
        beginDate: null,
        endDate: null,
      },
    };
  },
  created() {
    //默認開始時間為一周前
    this.queryParam.beginDate = formatDate(
      new Date().getTime() - 60 * 1000 * 60 * 24 * 6
    );
    //默認結束時間時間當前時間
    this.queryParam.endDate = formatDate(new Date().getTime());
    this.getList().then((response) => {
      var res = response.data;
      if (res) {
        //清空柱狀圖的數據源
        this.typeData = [];
        //遍歷后台響應數據,構造柱狀圖數據源
        for (var key in res) {
          this.typeData.push({ product: key, 博客數: res[key] });
        }
      }
      this.initChart(this.typeData);
    });
  },
  mounted() {},
  methods: {
    //調用后台接口查詢數據
    getList() {
      return request({
        url: "/system/blog/list",
        method: "get",
        params: this.queryParam,
      });
    },
    //父組件調用子組件的該方法進行重新渲染柱狀圖
    getSelectedRangeList(range) {
      var startDate = range[0];
      var endDate = range[1];
      this.queryParam.beginDate = startDate;
      this.queryParam.endDate = endDate;
      this.getList().then((response) => {
        var res = response.data;
        if (res) {
          this.typeData = [];
          for (var key in res) {
            this.typeData.push({ product: key, 博客數: res[key] });
          }
        }
        this.initChart(this.typeData);
      });
    },
    initChart(typeData) {
      this.chart = echarts.init(this.$el, "macarons");
      this.chart.setOption({
        tooltip: {
          trigger: "axis",
          axisPointer: {
            // 坐標軸指示器,坐標軸觸發有效
            type: "shadow", // 默認為直線,可選為:'line' | 'shadow'
          },
        },
        grid: {
          top: 10,
          left: "2%",
          right: "2%",
          bottom: "3%",
          containLabel: true,
        },
        legend: {
          //圖例
          data: ["博客數"],
        },
        xAxis: [
          {
            type: "category",
            axisPointer: {
              type: "shadow",
            },
            axisLabel: {
              interval: 0,
              rotate: 40,
            },
          },
        ],
        yAxis: [
          {
            type: "value",
            name: "單位:(條)",
            min: 0,
            max: 30,
            interval: 10,
            axisLabel: {
              formatter: "{value}",
            },
          },
        ],
        dataset: {
          source: typeData,
        },
        series: [
          {
            name: "博客數",
            type: "bar",
            barWidth: "40%",
          },
        ],
      });
    },
  },
};
</script>

10、顯示柱狀圖的父組件完整示例代碼

<template>
  <div>
    <div>
      <BarChartDateRange ref="BarChartDateRange"></BarChartDateRange>
    </div>
    <div class="block">
      <el-date-picker
        size="large"
        type="daterange"
        v-model="value1"
        range-separator=""
        start-placeholder="開始日期"
        end-placeholder="結束日期"
        @change="dateSelectChange"
        :value-format="dateFormat"
      >
      </el-date-picker>
    </div>
  </div>
</template>
<script>
import BarChartDateRange from "@/components/Echarts/BarChartDateRange";

export default {
  name: "Blog",
  components: {
    BarChartDateRange,
  },
  data() {
    return {
      value1: "",
      dateFormat: "yyyy-MM-dd",
    };
  },
  created() {
  },
  methods: {
    /** 查詢博客列表 */
      dateSelectChange(val) {
      if (val) {
        var startDate = new Date(val[0]).getTime();
        var endDate = new Date(val[1]).getTime();
        debugger;
        if (endDate - startDate > 6 * 24 * 60 * 60 * 1000) {
          this.$message({
            message: "所選時間范圍不能大於7天",
            type: "warning",
          });
        }else{
           this.$refs.BarChartDateRange.getSelectedRangeList(val);
        }
      }
    },
  },
};
</script>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM