项目要求做一个从汇总数据跳转到柱状图分项展示的功能,设计到两部分数据,一个是后台数据库分项统计,一个是统计结果封装成前端echarts要求的格式。
echarts文档示例都很齐全,可以直接上官网查询。第一次用,对于我的难点在于数据封装。
1、后台数据
比如 findByAcceptpolicy(按承保政策统计),返回List<Map<String, String>>格式的数据,其中ermtotalrequire.acceptpolicy就是要统计的结果,为了方便service层的处理,统一用countresult别名。
<sql id="report_sql" >
countresult, t2.* from ermtotalrequire join
(
select ermuser.realname, t1.* from ermuser join (
select ermusersheet.sheetid, ermusersheet.userid, ermuserproject.projectname
from ermusersheet join ermuserproject on (ermusersheet.userprojectid = ermuserproject.userprojectid)
) t1 on (ermuser.userid = t1.userid)
) t2 on (ermtotalrequire.sheetid = t2.sheetid) order by countresult desc
</sql>
<select id="findByAcceptpolicy" resultType="java.util.HashMap">
select ermtotalrequire.acceptpolicy
<include refid="report_sql" />
</select>
<select id="findByNotaccept" resultType="java.util.HashMap">
select ermtotalrequire.notaccept
<include refid="report_sql" />
</select>
重点是service层的处理
// 组装echarts图标需要的数据对象Option
public Option makeChartObjectByParam(String param) {
// 根据姓名,项目统计结果(1)
List<Map<String, String>> resultList = new ArrayList<Map<String, String>>();
Method[] methods = totalRequireDao.getClass().getMethods();(2)
for(Method method : methods) {
if(method.getName().startsWith("findBy")) {
String methodName = "findBy" + param.substring(0, 1).toUpperCase() + param.substring(1);
logger.info("methodName:" + methodName);
if(methodName.equals(method.getName())) {
// 调用 findBy方法
try {
resultList = (List<Map<String, String>>) method.invoke(totalRequireDao);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
logger.info("统计结果resultList为:" + resultList);
Option option = new Option();(3)
List<String> nameProjectList = new ArrayList<String>();
Serie serie = new Serie();
serie.setName("数量");
serie.setType("bar");
serie.setBarWidth("30");
for(int i=0; i<resultList.size(); i++) {
nameProjectList.add(resultList.get(i).get("REALNAME") + "-" + resultList.get(i).get("PROJECTNAME"));
Object countObj = resultList.get(i).get("COUNTRESULT");
// 设置柱状图每一项的高度(4)
serie.getData().add(Integer.parseInt(countObj.toString()));
}
option.getSeries().add(serie);
// 设置参数的X轴坐标
option.getxAxis().setData(nameProjectList);
return option;
}
说明:(1)返回数据无法映射到一个model对象,映射成为map是一个很好的选择,我很喜欢用这种方式。
resultList对应的查询结果长这样:
(2)这里用反射获取查询方法,原因是统计项达到20个左右,如果用if或switch,会有很多类似的分支,代码重复
(3)echarts用到的对象封装如下:
public class Option {
private XAxis xAxis; //x轴
private List<Serie> series; //柱状图集合
public Option() {
this.xAxis = new XAxis();
this.series = new ArrayList<>();
}
}
public class Serie {
private String name;
private String type;
private String barWidth;
private List<Integer> data;
public Serie() {
this.data = new ArrayList<>();
}
}
public class XAxis {
private List<String> data;
public XAxis() {
this.data = new ArrayList<>();
}
}
(4)获取list中的数据,给柱状图每一项设置高度,给x轴设置文字说明
2、前端数据
js 整合静态数据和动态数据
<script type="text/javascript">
$(function() {
var myChart = echarts.init(document.getElementById('chart'));
// 获取查询参数
var param = $('#param').val();
console.log('param:' + param);
common.ajax({
url: '<%=basePath %>data/showChartByParam/' + param,
success : function(data) {
var option = {
title: {
text: '分图表'
},
tooltip: {},
legend: {
data:['数量']
},
xAxis: {},
yAxis: {},
series : [
{
barWidth : 30
}
]
};
console.log('data:' + data);
console.log('option.xAxis:' + option.xAxis + ", option.series:" + option.series);
// 对象拷贝
$.extend(true, option, data);
// 给整个图表赋值
myChart.setOption(option);
console.log('option.xAxis:' + option.xAxis + ", option.series:" + option.series);
},
type : 'GET'
});
});
/**
* 对jQuery的ajax方法的二次封装
*/
var common = window.common || {};
common.ajax = function(param) {
var mergeParam = $.extend({
timeout : 10000
} , param , {
complete : function(response) {
var url = response.getResponseHeader("url");
if(url) {
location.href = url;
} else {
if(param.complete && typeof param.complete == "function") {
param.complete();
}
}
}
});
$.ajax(mergeParam);
}
</script>
引入官网提供的echarts文件,设置div
<script src="<%=basePath %>js/echarts.js"></script>
<!--图表所在的div-->
<div id="chart" style="width: 800px;height:400px;"></div>
最终生成效果图:
网友评论