項目要求做一個從匯總數(shù)據(jù)跳轉(zhuǎn)到柱狀圖分項展示的功能倍靡,設(shè)計到兩部分數(shù)據(jù)眠冈,一個是后臺數(shù)據(jù)庫分項統(tǒng)計,一個是統(tǒng)計結(jié)果封裝成前端echarts要求的格式菌瘫。
echarts文檔示例都很齊全蜗顽,可以直接上官網(wǎng)查詢。第一次用雨让,對于我的難點在于數(shù)據(jù)封裝雇盖。
1、后臺數(shù)據(jù)
比如 findByAcceptpolicy(按承保政策統(tǒng)計)栖忠,返回List<Map<String, String>>格式的數(shù)據(jù)崔挖,其中ermtotalrequire.acceptpolicy就是要統(tǒng)計的結(jié)果贸街,為了方便service層的處理,統(tǒng)一用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圖標(biāo)需要的數(shù)據(jù)對象Option
public Option makeChartObjectByParam(String param) {
// 根據(jù)姓名薛匪,項目統(tǒng)計結(jié)果(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())) {
// 調(diào)用 findBy方法
try {
resultList = (List<Map<String, String>>) method.invoke(totalRequireDao);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
logger.info("統(tǒng)計結(jié)果resultList為:" + resultList);
Option option = new Option();(3)
List<String> nameProjectList = new ArrayList<String>();
Serie serie = new Serie();
serie.setName("數(shù)量");
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");
// 設(shè)置柱狀圖每一項的高度(4)
serie.getData().add(Integer.parseInt(countObj.toString()));
}
option.getSeries().add(serie);
// 設(shè)置參數(shù)的X軸坐標(biāo)
option.getxAxis().setData(nameProjectList);
return option;
}
說明:(1)返回數(shù)據(jù)無法映射到一個model對象,映射成為map是一個很好的選擇脓鹃,我很喜歡用這種方式逸尖。
resultList對應(yīng)的查詢結(jié)果長這樣:
(2)這里用反射獲取查詢方法,原因是統(tǒng)計項達到20個左右瘸右,如果用if或switch娇跟,會有很多類似的分支,代碼重復(fù)
(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中的數(shù)據(jù)太颤,給柱狀圖每一項設(shè)置高度苞俘,給x軸設(shè)置文字說明
2、前端數(shù)據(jù)
js 整合靜態(tài)數(shù)據(jù)和動態(tài)數(shù)據(jù)
<script type="text/javascript">
$(function() {
var myChart = echarts.init(document.getElementById('chart'));
// 獲取查詢參數(shù)
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:['數(shù)量']
},
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>
引入官網(wǎng)提供的echarts文件龄章,設(shè)置div
<script src="<%=basePath %>js/echarts.js"></script>
<!--圖表所在的div-->
<div id="chart" style="width: 800px;height:400px;"></div>
最終生成效果圖: