zoukankan      html  css  js  c++  java
  • 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',  '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',  '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>
  • 相关阅读:
    C++中的深拷贝和浅拷贝构造函数
    C++中构造函数的手动和自动调用方式
    C++中的构造函数
    P1709 [USACO5.5]隐藏口令Hidden Password
    [TJOI2007]segment
    11.28
    1565
    某数学题1
    某模拟题
    某看起来会做的数据结构题
  • 原文地址:https://www.cnblogs.com/badaoliumangqizhi/p/15606797.html
Copyright © 2011-2022 走看看