Apache ECharts

Apache ECharts介绍:

Apache ECharts 是一款基于 Javascript 的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。

官网地址:https://echarts.apache.org/zh/index.html

Apache ECharts入门程序:

进入官网,按照官方给的步骤:

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>ECharts</title><!-- 引入刚刚下载的 ECharts 文件 --><script src="echarts.js"></script></head><body><!-- 为 ECharts 准备一个定义了宽高的 DOM --><div id="main" style="width: 600px;height:400px;"></div><script type="text/javascript">// 基于准备好的dom,初始化echarts实例var myChart = echarts.init(document.getElementById('main'));// 指定图表的配置项和数据var option = {title: {text: 'ECharts 入门示例'},tooltip: {},legend: {data: ['销量']},xAxis: {data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']},yAxis: {},series: [{name: '销量',type: 'bar',data: [5, 20, 36, 10, 10, 20]}]};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);</script></body>
</html>

 

营业额统计:

业务规则及接口设计:

  • 营业额指订单状态为已完成的订单金额合计
  • 基于可视化报表的折线图展示营业额数据,X轴为日期,Y轴为营业额
  • 根据时间选择区间,展示每天的营业额数据

 

 前端想展示数据,也要设计接口从后端获取数据。

返回数据这一块,因为是前端来展示数据,所以我们提供的数据是要依照前端的规则。

 具体代码实现:

Controll层:

@Autowiredprivate ReportService reportService;/*** 营业额统计* @param begin* @param end* @return*/@GetMapping("/turnoverStatistics")@ApiOperation("营业额统计")public Result<TurnoverReportVO> turnoverStatistics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){log.info("营业额统计");TurnoverReportVO turnoverReportVO = reportService.turnoverStatistics(begin,end);return Result.success(turnoverReportVO);}

这里有个小细节,就是查询统计营业额,前端传的参数是日期的起始时间和结束时间,

格式是yyyy-MM-dd这种形式,所以,我们也要用这种形式来进行接收。

@DateTimeFormat(pattern = "yyyy-MM-dd"),就用到了这个方法。

 Service层:

package com.sky.service.impl;import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import com.sky.service.ReportService;
import com.sky.vo.TurnoverReportVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.validation.constraints.Min;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Service
public class ReportServiceImpl implements ReportService {@Autowiredprivate OrderMapper orderMapper;@Overridepublic TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {//封装TurnoverReportVO的dateList对象List<LocalDate> datelist = new ArrayList<>();datelist.add(begin);while(!begin.equals(end)){//将日期加到list集合中begin = begin.plusDays(1);datelist.add(begin);}String datejoin = StringUtils.join(datelist, ",");//封装TurnoverReportVO的turnoverList对象List<Double> turnoverlist = new ArrayList<>();for (LocalDate localDate : datelist) {//查询date日期对应的营业额数据,营业额是指:状态为“已完成”的订单金额合计LocalDateTime beginTime = LocalDateTime.of(localDate, LocalTime.MIN);LocalDateTime endTime = LocalDateTime.of(localDate,LocalTime.MAX);//select sum(amount) from orders where order_time > ? and order_time < ? and status = 5Map map = new HashMap();map.put("begin",beginTime);map.put("end",endTime);map.put("status", Orders.COMPLETED);Double turnover = orderMapper.TurnoverOfSum(map);turnover = turnover==null?0.0:turnover;turnoverlist.add(turnover);}for (Double v : turnoverlist) {System.out.println("今日份营业额:"+ v);}//封装TurnoverReportVO对象TurnoverReportVO turnoverReportVO = new TurnoverReportVO();turnoverReportVO.setDateList(datejoin);turnoverReportVO.setTurnoverList(StringUtils.join(turnoverlist,","));return  turnoverReportVO;}
}
思路:

我们观察TurnoverReportVO对象里面有两个值,dateList,turnoverList

一个是日期列表,一个是营业额列表。

我们观察前端页面也能看成

横坐标:是日期   纵坐标:是营业额。

 所以我们Service层的思路就很简单了

1:封装dateList对象

创建一个LocalDate的列表,然后通过LocalDate提供的库函数plusDay,将日期由begin一直加到end,并且TurnoverReportVO对象中的dateList对象是一个String,所以我们再调用String.utils的方法对这个列表进行逗号分割。

2:封装turnoverList对象

我们已经有了每一天的日期了,我们需要每一天的营业额(当然这里也不一定是每一天的,我们前端界面是可以选择的,有可能是一周,也有可能是一个月)。

这个turnoverList对象的封装就需要查询数据库了

select sum(amout) from orders where order_time > ? and order_time < ? and status = 5

我们创建一个map对象里面有beginTime,endTime,status,然后传到mapper层,查询数据中的数据。

3:最后再封装TurnoverReportVO对象返回。

Mapper层及注解:

/*** 动态查询营业额* @param map* @return*/Double TurnoverOfSum(Map map);
<select id="TurnoverOfSum" resultType="java.lang.Double">select sum(amount) from sky_take_out.orders<where><if test="begin != null">and order_time &gt; #{begin}</if><if test="end != null">and order_Time &lt; #{end}</if><if test="status != null"> and status = #{status} </if></where></select>

用户统计:

业务规则及接口设计:

业务规则:

  • 基于可视化报表的折线图展示用户数据,X轴为日期,Y轴为用户数
  • 根据时间选择区间,展示每天的用户总量和新增用户量数据

 

用户统计和上面的不同点就是我们的返回值有三个列表:

  • dateList
  • newUserList
  • totalUserList

 具体代码实现:

整体的思路和上面的营业额统计差不多

Controll层:

/*** 用户数量统计* @param begin* @param end* @return*/@GetMapping("/userStatistics")@ApiOperation("用户数量统计")public Result<UserReportVO> userStatistics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){log.info("用户数量统计");UserReportVO userReportVO = reportService.userStatistics(begin,end);return Result.success(userReportVO);}

Service层:

    /*** 用户数量统计* @param begin* @param end* @return*/@Overridepublic UserReportVO userStatistics(LocalDate begin, LocalDate end) {//封装UserReportVO的dateList对象List<LocalDate> dateList = new ArrayList<>();while (!begin.equals(end)){dateList.add(begin);begin = begin.plusDays(1);}String datejoin = StringUtils.join(dateList, ",");//封装UserReportVO的totalUserList对象//select count(id) from user where create_time < endTime//封装UserReportVO的newUserList对象//select count(id) from user where create_time > beginTime and create_time < endTimeList<Integer> totalUserList =  new ArrayList<>();List<Integer> newUserList = new ArrayList<>();for (LocalDate date : dateList) {LocalDateTime beginTime = LocalDateTime.of(date,LocalTime.MIN);LocalDateTime endTime = LocalDateTime.of(date,LocalTime.MAX);Map map = new HashMap();map.put("end",endTime);Integer totalUser = userMapper.UserofSum(map);map.put("begin",beginTime);Integer newUser = userMapper.UserofSum(map);totalUserList.add(totalUser);newUserList.add(newUser);}String totaluserjoin = StringUtils.join(totalUserList, ",");String newluserjoin = StringUtils.join(newUserList, ",");UserReportVO userReportVO = new UserReportVO();userReportVO.setDateList(datejoin);userReportVO.setTotalUserList(totaluserjoin);userReportVO.setNewUserList(newluserjoin);return userReportVO;}

这里Service层的业务就是封装三个列表

要想封装这个用户,我们需要去调userMapper

我们想要知道总共的用户的sql是:

//select count(id) from user where create_time < endTime

截至到这个end时间时候的用户数量。

而新增用户的sql是:

//select count(id) from user where create_time > beginTime and create_time < endTime

我们要给这个新增确定一个日期范围。 

userMapper及注解:

Integer UserofSum(Map map);
<select id="UserofSum" resultType="java.lang.Integer">select count(id) from sky_take_out.user<where><if test="begin != null">and create_time > #{begin}</if><if test="end != null">and create_time &lt; #{end}</if></where></select>

 订单统计:

业务规则及接口设计:

业务规则:

  • 有效订单指状态为 “已完成” 的订单
  • 基于可视化报表的折线图展示订单数据,X轴为日期,Y轴为订单数量
  • 根据时间选择区间,展示每天的订单总数和有效订单数
  • 展示所选时间区间内的有效订单数、总订单数、订单完成率,订单完成率 = 有效订单数 / 总订单数 * 100%

具体的代码实现: 

Controll层:

    /*** 订单统计* @param begin* @param end* @return*/@GetMapping("/ordersStatistics")@ApiOperation("订单统计")public Result<OrderReportVO> orderStatistics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){log.info("订单统计");OrderReportVO orderReportVO = reportService.ordersStatistics(begin,end);return Result.success(orderReportVO);}

Service层:

/*** 订单统计* @param begin* @param end* @return*/@Overridepublic OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {//封装OrderReportVO的dateList对象List<LocalDate> dateList = new ArrayList<>();while (!begin.equals(end)){dateList.add(begin);begin = begin.plusDays(1);}String datejoin = StringUtils.join(dateList, ",");//封装OrderReportVO的orderCountList对象//封装OrderReportVO的validOrderCountList对象List<Integer> orderCountList = new ArrayList<>();List<Integer> validOrderCountList = new ArrayList<>();for (LocalDate date : dateList) {LocalDateTime beginTime = LocalDateTime.of(date,LocalTime.MIN);LocalDateTime endTime = LocalDateTime.of(date,LocalTime.MAX);Map map = new HashMap();map.put("begin",beginTime);map.put("end",endTime);Integer totalorders = orderMapper.OrdersofSum(map);map.put("status",Orders.COMPLETED);Integer validorders = orderMapper.OrdersofSum(map);orderCountList.add(totalorders);validOrderCountList.add(validorders);}String totaljoin = StringUtils.join(orderCountList, ",");String validjoin = StringUtils.join(validOrderCountList,",");//计算时间区间内的订单总数量Integer totalOrderCount = orderCountList.stream().reduce(Integer::sum).get();//计算时间区间内的有效订单数量Integer validOrderCount = validOrderCountList.stream().reduce(Integer::sum).get();//计算订单完成率Double orderCompletionRate  = 0.0;if(totalOrderCount!=0){orderCompletionRate = validOrderCount.doubleValue()/totalOrderCount.doubleValue();}OrderReportVO orderReportVO = new OrderReportVO();orderReportVO.setDateList(datejoin);orderReportVO.setOrderCountList(totaljoin);orderReportVO.setValidOrderCountList(validjoin);orderReportVO.setTotalOrderCount(totalOrderCount);orderReportVO.setValidOrderCount(validOrderCount);orderReportVO.setOrderCompletionRate(orderCompletionRate);return orderReportVO;}

Mapper层及注解:

     /*** 订单统计* @param map* @return*/Integer OrdersofSum(Map map);
<select id="OrdersofSum" resultType="java.lang.Integer">select count(id) from sky_take_out.orders<where><if test="begin != null">and order_time > #{begin}</if><if test="end != null">and order_Time &lt; #{end}</if><if test="status != null">and status=#{status}</if></where></select>

销量排名统计(TOP10):

业务规则及接口设计:

业务规则:

  • 根据时间选择区间,展示销量前10的商品(包括菜品和套餐)
  • 基于可视化报表的柱状图降序展示商品销量
  • 此处的销量为商品销售的份数

具体的代码实现:

 Controll层:

/*** TOP10销量统计* @param begin* @param end* @return*/@GetMapping("/top10")@ApiOperation("TOP10销量统计")public Result<SalesTop10ReportVO> Top10Statostics(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){log.info("TOP10销量统计");SalesTop10ReportVO salesTop10ReportVO = reportService.Top10Statostics(begin,end);return Result.success(salesTop10ReportVO);}

Service层:

    /*** TOP10销量统计* @param begin* @param end* @return*/@Overridepublic SalesTop10ReportVO Top10Statostics(LocalDate begin, LocalDate end) {LocalDateTime beginTime = LocalDateTime.of(begin,LocalTime.MIN);LocalDateTime endTime = LocalDateTime.of(end,LocalTime.MAX);System.out.println("开始时间是:"+beginTime);System.out.println("结束时间是:"+endTime);List<GoodsSalesDTO> goodsSalesDTOList = orderMapper.GetTop10(beginTime,endTime);List<String> names = goodsSalesDTOList.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());String nameList = StringUtils.join(names, ",");List<Integer> numbers = goodsSalesDTOList.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());String numberList = StringUtils.join(numbers, ",");SalesTop10ReportVO salesTop10ReportVO = new SalesTop10ReportVO();salesTop10ReportVO.setNameList(nameList);salesTop10ReportVO.setNumberList(numberList);return salesTop10ReportVO;}

这题的从sql语句开始分析比较简单

select od.name,sum(od.number) number from order_detail od,orders o
where od.order_id = o.id and o.status = 5 and o.order_time < 2024-05-04 and o.order_time > 2024-05-10
group by od.name
order by number desc
limit 0,10

根据传入的时间范围来获取数据。

Mapper层及注解:

    /*** TOP10销量统计* @param beginTime* @param endTime* @return*/List<GoodsSalesDTO> GetTop10(LocalDateTime beginTime, LocalDateTime endTime);
<select id="GetTop10" resultType="com.sky.dto.GoodsSalesDTO">select od.name,sum(od.number) numberfrom sky_take_out.order_detail od,sky_take_out.orders owhere od.order_id = o.id and o.status = 5<if test="beginTime != null">and o.order_time > #{beginTime}</if><if test="endTime != null">and o.order_Time &lt; #{endTime}</if>group by od.nameorder by number desclimit 0,10</select>

结果展示:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/10452.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Stable Diffusion写真完整教程

前言 最近自己对AI非常痴迷&#xff0c;并且今后也会一直在这个领域深耕&#xff0c;所以就想着先入门&#xff0c;因此花时间研究了一番&#xff0c;还好&#xff0c;出了点小成果&#xff0c;接下来给大家汇报一下。 AI绘画 提到AI绘画&#xff0c;大家可能立马会想到made…

A-loam建图算法

A-LOAM构建3d点云地图并实时转存二维栅格地图 A-loam算法。源代码用的是velodyne雷达话题&#xff0c;但是现在用rslidar来处理。所以也会遇到另外一个包来转换相关的数据。 git clone https://github.com/HKUST-Aerial-Robotics/A-LOAM.githttps://github.com/HViktorTsoi/r…

重庆市工程技术生态环境专业职称申报条件

重庆市工程技术生态环境专业职称申报条件链接重庆市人力资源和社会保障局 重庆市生态环境局关于印发重庆市工程技术生态环境专业职称申报条件的通知_重庆市人力资源和社会保障局类别基本条件业绩成果备注工程师具备博士学位&#xff1b;或具备硕士学位或第二学士学位&#xff0…

cin.ignore()函数和stoll函数

cin.ignore()函数 cin.ignore() 是一个非常实用的函数&#xff0c;主要用于控制输入流 cin 的行为 cin.ignore(int n 1, char delimiter EOF); n&#xff1a;一个整数参数&#xff0c;表示要忽略的字符数量。默认值是1&#xff0c;意味着只忽略下一个字符。delimiter&#x…

Android 屏幕适配全攻略(下)-百变屏幕无压力,这才是Android屏幕适配的终极解决方案

在上一篇文章中&#xff0c;我们介绍了Android屏幕适配的基本方法&#xff0c;比如使用限定符资源、图片适配、矢量图等。 感兴趣的朋友&#xff0c;请前往查阅&#xff1a;Android 屏幕适配全攻略&#xff08;中&#xff09;-从九宫格到矢量图&#xff0c;揭秘Android多屏幕适…

模拟集成电路(3)----单级放大器(共源极)

模拟集成电路(3)----单级放大器&#xff08;共源极&#xff09; 放大是模拟电路的基本功能 大多数自然模拟信号太小而无法处理需要足够的信噪比 理想的放大器 线性&#xff1a;无限的幅度和频率范围 输入阻抗无限大 输出阻抗无限小 共源放大器 共源放大器就是将源极接A…

01面向类的讲解

指针指向类成员使用 代码&#xff1a; #include<iostream> using namespace std;class Test { public:void func() { cout << "call Test::func" << endl; }static void static_func();int ma;static int mb; //不依赖对象 }; void Test::static…

JavaScript 动态网页实例 —— 事件处理应用

前言 事件处理的应用很广泛。在事件处理的应用中,鼠标事件的应用是最常用到的。本章给出几个鼠标事件处理应用的示例,包括:页面预览、图像切换、点亮文本、鼠标跟随、鼠标感应和禁用鼠标按键。在这些示例中,有的可以直接拿来应用,有的则只提供了一种应用的方法,稍加拓展,…

示例十一、声音传感器

通过以下几个示例来具体展开学习,了解声音传感器原理及特性&#xff0c;学习声音传感器的应用&#xff08;干货版&#xff09;&#xff1a; 示例十一、声音传感器 ino文件源码&#xff1a; //Arduino C demo void setup() {Serial.begin(9600);pinMode(5, OUTPUT); }void loo…

机器学习-无监督学习

无监督学习是机器学习和人工智能的另一个重要分支&#xff0c;它主要处理没有标签的数据集&#xff0c;目的是发现数据中的隐藏模式、结构或异常。无监督学习不依赖于预先定义的输出&#xff0c;而是让算法自己揭示数据的本质特征。 无监督学习的过程通常包括以下几个步骤&…

标准服务器控件

文本类型控件 通常指的是用于输入或显示文本的控件。 TextBox&#xff1a;这是最基本的文本输入控件。它允许用户在页面上输入文本。你可以设置它的属性来控制其行为&#xff0c;如MaxLength&#xff08;限制输入的最大字符数&#xff09;、ReadOnly&#xff08;是否只读&…

【C/C++笔试练习】DNS设置文件、应用层、Dos攻击、DNS服务、DNS、子网划分、http状态、路由设置、TCP连接、HTTP状态码、剪花布条、客似云来

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;DNS设置文件&#xff08;2&#xff09;应用层&#xff08;3&#xff09;Dos攻击&#xff08;4&#xff09;DNS服务&#xff08;5&#xff09;DNS&#xff08;6&#xff09;子网划分&#xff08;7&#xff09;http状态&am…

docker01-简介和概述

什么是docker&#xff1f; 我们现在开发项目是在windows操作系统使用idea开发&#xff0c;本地windows操作系统上有我们项目所需的jdk&#xff0c;mysql&#xff0c;redis&#xff0c;tomcat等环境&#xff0c;如果我们想打包我们的项目到一个别的服务器上&#xff0c;在别的服…

【Apache POI】Apache POI-操作Excel表格-简易版

Catalog Apache POI-操作Excel表格1. 需求2. 优点3. 缺点4. 应用场景5. 使用方法6. SpringBoot工程中处理Excel表格7. Demo示例 Apache POI-操作Excel表格 1. 需求 大多数项目的在运营过程中&#xff0c;会产生运营数据&#xff0c;如外卖系统中需要统计每日的订单完成数、每…

SpringBoot实现图片验证码

引入依赖 <dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6.2</version> </dependency>代码实现 package com.qiangesoft.captcha.controller;import com.wf.captcha.*…

最少数量线段覆盖-华为OD

系列文章目录 文章目录 系列文章目录前言一、题目描述二、输入描述三、输出描述四、java代码五、测试用例 前言 本人最近再练习算法&#xff0c;所以会发布一些解题思路&#xff0c;希望大家多指教 一、题目描述 给定坐标轴上的一组线段&#xff0c;线段的起点和终点均为整数…

C++:类与对象—继承

类与对象—继承 一、继承是什么&#xff1f;二、继承定义三、基类和派生类对象赋值转换四、继承中的作用域五、派生类的默认成员函数六、继承与友元七、继承与静态成员八、复杂的菱形继承及菱形虚拟继承九、继承的总结和反思十、考察重点 一、继承是什么&#xff1f; 继承(inh…

知识付费系统需要哪些资质要求,教育机构教务工作计划内容有哪些?

每个培训教育机构都是由很多人员组成&#xff0c;作为教育机构&#xff0c;老师不必须&#xff0c;是必不可少的&#xff0c;但是除了老师之外还得配备一定数量的销售人员和教务工作者&#xff0c;教务老师其实也就是搞后勤的&#xff0c;但是是必须的&#xff0c;那么教育机构…

Java的时间类

1. 日期类 1.1 第一代日期类 1) Date: 精确到毫秒&#xff0c;代表特定的瞬间 2) SimpleDateFormat: 格式和解析日期的类 SimpleDateFormat 格式化和解析日期的具体类。它允许进行格式化(日期-→>文本)、解析(文本->日期)和规范化. import java.text.ParseExce…

Java基础(27)Web应用中web.xml文件中可以配置哪些内容

在Java Web应用中&#xff0c;web.xml文件&#xff08;也被称为部署描述符&#xff09;是一个核心的配置文件&#xff0c;它位于应用的WEB-INF目录下。web.xml文件中可以配置多种不同的组件和参数&#xff0c;它们用来定义和调整应用的行为。以下是一些web.xml中可以配置的内容…