第10章:权限控制与图像报表-02-图形报表(全)
2. 图形报表ECharts2.1 ECharts简介ECharts缩写来自Enterprise Charts商业级数据图表是百度的一个开源的使用JavaScript实现的数据可视化工具可以流畅的运行在 PC 和移动设备上兼容当前绝大部分浏览器IE8/9/10/11ChromeFirefoxSafari等底层依赖轻量级的矢量图形库 ZRender提供直观、交互丰富、可高度个性化定制的数据可视化图表。官网https://echarts.apache.org/zh/index.html下载地址https://echarts.apache.org/zh/download.html下载完成可以得到如下文件解压上面的zip文件我们只需要将dist目录下的echarts.js文件引入到页面上就可以使用了2.2 5分钟上手ECharts我们可以参考官方提供的5分钟上手ECharts文档感受一下ECharts的使用方式地址如下https://echarts.apache.org/handbook/zh/get-started/第一步创建html页面并引入echarts.js文件!DOCTYPE html html head meta charsetutf-8 !-- 引入 ECharts 文件 -- script srcecharts.js/script /head /html第二步在页面中准备一个具备宽高的DOM容器。body !-- 为 ECharts 准备一个具备大小宽高的 DOM -- div idmain stylewidth: 600px;height:400px;/div /body第三步通过echarts.init方法初始化一个 echarts 实例并通过setOption方法生成一个简单的柱状图script typetext/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效果如下2.3 查看ECharts官方实例ECharts提供了很多官方实例我们可以通过这些官方实例来查看展示效果和使用方法。官方实例地址https://echarts.apache.org/examples/zh/index.html可以点击具体的一个图形会跳转到编辑页面编辑页面左侧展示源码js部分源码右侧展示图表效果如下要查看完整代码可以点击右下角的Download按钮将完整页面下载到本地。通过官方案例我们可以发现使用ECharts展示图表效果关键点在于确定此图表所需的数据格式然后按照此数据格式提供数据就可以了我们无须关注效果是如何渲染出来的。在实际应用中我们要展示的数据往往存储在数据库中所以我们可以发送ajax请求获取数据库中的数据并转为图表所需的数据即可。3. 会员数量折线图3.1 需求分析会员信息是体检机构的核心数据其会员数量和增长数量可以反映出机构的部分运营情况。通过折线图可以直观的反映出会员数量的增长趋势。本章节我们需要展示过去一年时间内每个月的会员总数据量。展示效果如下图3.2 完善页面会员数量折线图对应的页面为/pages/report_member.html。3.2.1 导入ECharts库第一步将echarts.js文件复制到health_backend工程的plugins目录下第二步在report_member.html页面引入echarts.js文件script src../plugins/echarts/echarts.js/script3.2.2 参照官方实例导入折线图div classbox !-- 为 ECharts 准备一个具备大小宽高的 DOM -- div idchart1 styleheight:600px;/div /divscript typetext/javascript // 基于准备好的dom初始化echarts实例 var myChart1 echarts.init(document.getElementById(chart1)); //发送ajax请求获取动态数据 axios.get(/report/getMemberReport.do).then((res){ myChart1.setOption( { title: { text: 会员数量 }, tooltip: {}, legend: { data:[会员数量] }, xAxis: { data: res.data.data.months }, yAxis: { type:value }, series: [{ name: 会员数量, type: line, data: res.data.data.memberCount }] }); }); /script根据折线图对数据格式的要求我们发送ajax请求服务端需要返回如下格式的数据{ data:{ months:[2019.01,2019.02,2019.03,2019.04], memberCount:[3,4,8,10] }, flag:true, message:获取会员统计数据成功 }3.3 后台代码3.3.1 Controller在health_backend工程中创建ReportController并提供getMemberReport方法package com.liusp.controller; import com.alibaba.dubbo.config.annotation.Reference; import com.liusp.constant.MessageConstant; import com.liusp.entity.Result; import com.liusp.service.MemberService; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.*; /** * 统计报表 */ RestController RequestMapping(/report) public class ReportController { Reference private MemberService memberService; /** * 会员数量统计 * return */ RequestMapping(/getMemberReport.do) public Result getMemberReport(){ //获得日历对象 Calendar calendar Calendar.getInstance(); calendar.add(Calendar.MONTH,-12);//获得当前日期之前12个月的日期 ListString list new ArrayList(); for(int i0;i12;i){ calendar.add(Calendar.MONTH,1); list.add(new SimpleDateFormat(yyyy.MM).format(calendar.getTime())); } MapString,Object map new HashMap(); map.put(months,list); ListInteger memberCount memberService.findMemberCountByMonth(list); map.put(memberCount,memberCount); return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS,map); } }3.3.2 服务接口在MemberService服务接口中扩展方法findMemberCountByMonthpublic ListInteger findMemberCountByMonth(ListString month);3.2.3 服务实现类在MemberServiceImpl服务实现类中实现findMemberCountByMonth方法//根据月份统计会员数量 public ListInteger findMemberCountByMonth(ListString month) { ListInteger list new ArrayList(); for(String m : month){ m m .31;//格式2019.04.31 Integer count memberDao.findMemberCountBeforeDate(m); list.add(count); } return list; }3.3.4 Dao接口在MemberDao接口中扩展方法findMemberCountBeforeDatepublic Integer findMemberCountBeforeDate(String date);3.3.5 Mapper映射文件在MemberDao.xml映射文件中提供SQL语句!--根据日期统计会员数统计指定日期之前的会员数。lt;是号转义字符-- select idfindMemberCountBeforeDate parameterTypestring resultTypeint select count(id) from t_member where regTime lt; #{value} /select修改main.html 左侧导航点击会员数量统计跳转到我们的report_member.html页面{ path: 5, //菜单项所对应的路由路径 title: 统计分析, //菜单项名称 icon:fa-heartbeat, children:[//是否有子菜单若没有则为[] { path: /5-1, title: 会员数量统计, linkUrl:report_member.html, children:[] } ] }

相关新闻

从零搭建 AI 智能体陪练系统:基于 FastAPI + DeepSeek-V3 的题库生成 MVP 全记录

从零搭建 AI 智能体陪练系统:基于 FastAPI + DeepSeek-V3 的题库生成 MVP 全记录

从零搭建 AI 智能体陪练系统:基于 FastAPI DeepSeek-V3 的题库生成 MVP 全记录一个周末,一行代码都不浪费——用 OpenAI 兼容接口调用国产大模型,打造可落地的 AI 出题引擎。一、项目背景与定位 在 CTF(Capture The Flag&#xf…

2026/10/4 12:22:53 阅读更多 →
第7章:页面静态化-02-生成移动端静态页面

第7章:页面静态化-02-生成移动端静态页面

5. 生成移动端静态页面 前面我们已经学习了Freemarker的基本使用方法,下面我们就可以将Freemarker应用到项目中,帮我们生成移动端套餐列表静态页面和套餐详情静态页面。接下来我们需要思考几个问题: (1)什么时候生成…

2026/10/7 5:16:23 阅读更多 →
npm-g_nosudo:彻底告别Ubuntu下npm全局安装sudo依赖的终极解决方案

npm-g_nosudo:彻底告别Ubuntu下npm全局安装sudo依赖的终极解决方案

npm-g_nosudo:彻底告别Ubuntu下npm全局安装sudo依赖的终极解决方案 【免费下载链接】npm-g_nosudo A shell script which will fix the problem where you want to stop using sudo for npm -g on Ubuntu. 项目地址: https://gitcode.com/gh_mirrors/np/npm-g_nos…

2026/10/11 23:27:32 阅读更多 →

最新新闻

插件系统原理与failed to load plugins排查指南

插件系统原理与failed to load plugins排查指南

网上关于 plugins 的搜索,一半是“plugins 是干什么的”,另一半全是“failed to load plugins”这类报错。这其实很能说明问题:插件机制是软件生态里最巧妙的设计之一,但也是坑最多的地方。尤其当你拿到一条 “failed to load plu…

2026/10/14 16:02:07 阅读更多 →
主从复制SQL线程中断——字符集砸出的坑

主从复制SQL线程中断——字符集砸出的坑

## 一、问题现场:SQL 线程中断,但表结构一致告警响起:异步复制的 slave 端 SQL 线程中断了。查询表 replication_applier_status_by_worker检查报错信息:SQL GreatSQL > SELECT * FROM performance_schema.replication_applier…

2026/10/14 16:02:07 阅读更多 →
Intel SGX核心原理与开发入门:Enclave和硬件内存加密解析

Intel SGX核心原理与开发入门:Enclave和硬件内存加密解析

1. 引言:从一个被“偷看”的内存说起先从一个最直观的场景说起。假设你在云服务器上跑一个处理用户敏感数据的程序,比如医疗影像分析、金融风控模型,或者干脆就是一个简单的密码校验服务。这台服务器的操作系统是Linux,你有完整的…

2026/10/14 16:02:07 阅读更多 →
VS连接PostgreSQL全攻略:驱动选择、连接字符串与常见坑排查

VS连接PostgreSQL全攻略:驱动选择、连接字符串与常见坑排查

说实话,这个问题我在实际项目里见过太多次了。数据库换成了 PostgreSQL,后台开发还是 Visual Studio,结果新建连接向导里根本没有 PostgreSQL 的选项,只能手动写连接字符串,然后就是各种报错。尤其 VS2012 这种老版本&…

2026/10/14 16:02:07 阅读更多 →
插件系统加载激活机制详解:从报错 did not activate 到工程实践

插件系统加载激活机制详解:从报错 did not activate 到工程实践

开发工具用多了,早晚会遇到这么一行黑底白字的报错:failed to load plugins web boot: 2 entries did not activate我第一次看到它也懵了很久,以为是自己把环境变量搞坏了,后来才发现,问题出在我对“插件”这套机制的底…

2026/10/14 16:02:07 阅读更多 →
ECCV2020底层视觉论文盘点:超分去噪去雨去雾去模糊与复现

ECCV2020底层视觉论文盘点:超分去噪去雨去雾去模糊与复现

做底层视觉方向的论文整理,我一直有个习惯:每个顶会结束后,先不看社交平台上的碎片讨论,而是把官方论文列表整个拖下来,按关键词筛一遍,再逐个进仓库看有没有公开代码。最近在整理ECCV2020这批图像重建与底…

2026/10/14 16:01:07 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →