图形报表
两个实例五分钟全面上手Echarts,包括后台实现
1:了解Echarts
2:掌握Echarts实现会员数量折线图的实现过程
1. 图形报表ECharts
【目标】
了解Echarts
【路径】
1:ECharts简介
2:5分钟上手ECharts
3:查看ECharts官方实例
【讲解】
1.1. ECharts简介
ECharts缩写来自Enterprise Charts,商业级数据图表,是百度的一个开源的使用JavaScript实现的数据可视化工具,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖轻量级的矢量图形库 ZRender,提供直观、交互丰富、可高度个性化定制的数据可视化图表。
下载地址:https://echarts.baidu.com/download.html
下载完成可以得到如下文件:
解压上面的zip文件:
我们只需要将dist目录下的echarts.js文件(已经压缩)引入到页面上就可以使用了
1.2. 5分钟上手ECharts
我们可以参考官方提供的5分钟上手ECharts文档感受一下ECharts的使用方式,地址如下:
[https://www.echartsjs.com/tutorial.html#5%20%E5%88%86%E9%92%9F%E4%B8%8A%E6%89%8B%20ECharts](#5 %E5%88%86%E9%92%9F%E4%B8%8A%E6%89%8B ECharts)
第一步:在工程中创建html页面并引入echarts.js文件
echartsDemo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<!-- 引入 ECharts 文件 -->
<script src="js/echarts.js"></script>
<body>
</body>
</html>
第二步:在页面中准备一个具备宽高的DOM容器。
<body>
<!-- 为 ECharts 准备一个具备大小(宽高)的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
</body>
第三步:通过echarts.init方法初始化一个 echarts 实例并通过setOption方法生成一个简单的柱状图
<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>
效果如下:
1.3. 查看ECharts官方实例
ECharts提供了很多官方实例,我们可以通过这些官方实例来查看展示效果和使用方法。
官方实例地址:https://www.echartsjs.com/examples/
可以点击具体的一个图形会跳转到编辑页面,编辑页面左侧展示源码(js部分源码),右侧展示图表效果,如下:
要查看完整代码可以点击右下角的Download按钮将完整页面下载到本地。
通过官方案例我们可以发现,使用ECharts展示图表效果,关键点在于确定此图表所需的数据格式,然后按照此数据格式提供数据就可以了,我们无须关注效果是如何渲染出来的。
在实际应用中,我们要展示的数据往往存储在数据库中,所以我们可以发送ajax请求获取数据库中的数据并转为图表所需的数据即可。
【小结】
- ECharts百度开发的一套商业报工具(库)
- 看官网, 关注案例,无需关注api,根据项目需求,选择合适报表
2. 会员数量折线图
【目标】
使用ECharts实现会员数量折线图
【路径】
1:需求分析
2:前台页面
(1)导入ECharts库
(2)参考官方实例导入折线图
3:后台代码
(1)ReportServlet类
(2)MemberService服务接口
(3)MemberServiceImpl服务实现类
(4)MemberMapper接口
【讲解】
2.1. 需求分析
展示效果如下图:
需要的sql:
#2019年05月31日之前入职的人数(11)
SELECT COUNT(id) FROM t_member WHERE regTime <= '2019-05-31'
#2019年06月31日之前入职的人数(12)
SELECT COUNT(id) FROM t_member WHERE regTime <= '2019-06-31'
#2019年07月31日之前入职的人数(16)
SELECT COUNT(id) FROM t_member WHERE regTime <= '2019-07-31'
2.2. 完善页面
会员数量折线图对应的页面为/pages/report_member.html。
2.2.1. 导入ECharts库
第一步:将echarts.js文件复制到工程中
第二步:在report_member.html页面引入echarts.js文件
<script src="../js/echarts.js"></script>
2.2.2. 参照官方实例导入折线图
1:定义
<div class="app-container">
<div class="box">
<!-- 为 ECharts 准备一个具备大小(宽高)的 DOM -->
<div id="chart1" style="height:600px;"></div>
</div>
</div>
2:定义script
<script>
// 基于准备好的dom,初始化echarts实例
var myChart1 = echarts.init(document.getElementById('chart1'));
// 使用刚指定的配置项和数据显示图表。
//myChart.setOption(option);
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请求,服务端需要返回如下格式的数据:
其中months和memberCount可以使用hashmap封装
其中data,是map集合
map集合的key:months; map集合的值:List
map集合的key:memberCount; map集合的值:List
{
"months":["2019-01","2019-02","2019-03","2019-04"],
"memberCount":[3,4,8,10]
}
Map<String,Object> map=...
map.put("moths",List<String>);
map.put("memberCount",List<Integer>)
2.3. 后台代码
2.3.1. Controller
在工程中创建ReportController并提供getMemberReport方法
/**
* 统计报表
*/
@WebServlet("/report/*")
public class ReportServlet extends BaseServlet {
private MemberService memberService=new MemberServiceImpl();
/**
* 会员数量统计
*/
private void getMemberReport(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MONTH,-12);//获得当前日期之前12个月的日期
List<String> list = new ArrayList<String>();
for(int i=0;i<12;i++){
calendar.add(Calendar.MONTH,1);
list.add(new SimpleDateFormat("yyyy-MM").format(calendar.getTime()));
}
Map<String,Object> map = new HashMap<String,Object>();
map.put("months",list);
List<Integer> memberCount = memberService.findMemberCountByMonth(list);
map.put("memberCount",memberCount);
String json=new ObjectMapper().writeValueAsString(map);
resp.setContentType("text/json;charset=utf-8");
resp.getWriter().write(json);
}
}
计算日期,可以使用test方法测试一下
2.3.2. 服务接口
在MemberService服务接口中扩展方法findMemberCountByMonth
List<Integer> findMemberCountByMonth(List<String> months);
2.3.3. 服务实现类
在MemberServiceImpl服务实现类中实现findMemberCountByMonth方法
// 根据月份统计会员数量
public List<Integer> findMemberCountByMonth(List<String> months) {
List<Integer> list = new ArrayList<>();
for(String m : months){
m = m + "-31";//格式:2019-04-31
Integer count = memberDao.findMemberCountBeforeDate(m);
list.add(count);
}
return list;
}
2.3.4. Dao接口
在MemberDao接口中扩展方法findMemberCountBeforeDate
<!--根据日期统计会员数,统计指定日期之前的会员数-->
@Select("select count(id) from t_member where regTime <= #{value}")
public Integer findMemberCountBeforeDate(String date);