jQuery的Flot图表统计插件集成

jQuery的Flot图表统计插件集成
这应该是在这的最后一次写经验分享文档了,一直以来是想从自己做起,影响带动身边的同事的,不过貌似大家都很不喜欢写分享文档,有时候不经感叹中国的技术发展之所以慢也想就是因为这种分享精神不够吧,不伤感也不废话了。这次的场景是需要一个统计比较直观的,上面设计的是grid列表展示,下面是图表统计,先看效果:
jQuery的Flot图表统计插件集成
这里提供了三个维度的饼性统计,需要其他的可以自行扩展。
一、Flot插件目录
从官网下载后解压,你会看到:jQuery的Flot图表统计插件集成
将这个文件下的js全部复制到项目里第三方插件的目录下,如图:
jQuery的Flot图表统计插件集成
js文件、样式文件分别放在不同的目录下。
二、Flot插件引用
这个插件是基于jQuery的,jQuery的引入就不说了。
这里在所有页面需要include的文件里引入Flot插件的主要js
jQuery的Flot图表统计插件集成
为什么这样处理是因为考虑到页面的性能,因为每个页面都要引入这个head.html文件,但是又并不是每个业务页面都需要使用这个组件,所以具体组件js在单个页面自行引入,这里只引入插件的基础js。
三、页面引入饼形插件js
jQuery的Flot图表统计插件集成
这里引入基础头文件head.html,然后再引入饼形插件js,再引入样式。注意例子上面的样式也需要复制直接在写在这个页面,如果觉得不好看可以找UI自行修改或写样式,保证样式名称一致就ok了。
四、饼形统计具体前台代码
这里基本上复制demo例子里的代码就行,我这里上面是grid就不说了,下面才是统计展示区域,我直接复制例子里的div,去掉不需要的div,比如去掉了titile、description,具体如下:
jQuery的Flot图表统计插件集成
统计开始上的div是grid的展示区域,id为content的div是直接复制例子上的,我保留3个按钮,调整了下按钮的逻辑。
然后就是写js了,按照demo先定义数据数组,饼形Flot对象:
var countData = [];
var placeholder;
dom对象需要在页面渲染完后根据id获得:
placeholder = $("#placeholder");
$("#count_1").click();
剩下的就是饼形对象的初始化、数据获取、渲染了。
我这里是点击按钮后,先去获取数据,然后初始化饼形对象:
我这里取数据图通过ajax获取:
jQuery的Flot图表统计插件集成
然后成功的分支里调用饼形渲染showCount方法:
jQuery的Flot图表统计插件集成
里面的2个switch你不一定需要,在后台将编码转为对应中文,前台就不需要处理了。
前台代码就这些了。
五、Flot后台代码
首先通过查看饼形统计的例子,看到的数据结构是数组里放的是一个json对象,有data和label,分析完这个后考虑到以后其他统计的扩展性,所以讲Vo设置为一个包含list的对象,里面暂时只放了一个pieData的list,后面其他统计可以直接扩展这个vo:
public class FlotDataVo extends BusinessResponseVo{
//饼形统计数据
public List<FlotPieVo> pieData;
public List<FlotPieVo> getPieData() {
return pieData;
}
public void setPieData(List<FlotPieVo> pieData) {
this.pieData = pieData;
}
}
这里BusinessResponseVo类是一个对外的包含请求结果msg、code的类,你也可以不继承的,我这里是为了方便页面判断请求是否成功。
public class FlotPieVo {
public String label;
public BigDecimal data;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public BigDecimal getData() {
return data;
}
public void setData(BigDecimal data) {
this.data = data;
}
}
这里为什么用的BigDecimal ?想想
Action
@RequestMapping(value="/getCountData.jspx")
public void getCountData(HttpServletRequest request,HttpServletResponse response,String dataType) {
FlotDataVo flotData = new FlotDataVo();
flotData.setStatus("1");
if(StringUtils.isNotBlank(dataType)) {
//统计依赖于sql查询,逻辑就写到dao里
flotData = couponViewMng.getCountData(dataType,FlotPieVo.class,flotData);
flotData.setCode(BusinessConstant.ReMsg.SUCCESS.getCode());
flotData.setMsg(BusinessConstant.ReMsg.SUCCESS.getMsg());
}else {
flotData.setCode(BusinessConstant.ReMsg.COUPON_PARAM_DATA_TYPE_NULL.getCode()); flotData.setMsg(BusinessConstant.ReMsg.COUPON_PARAM_DATA_TYPE_NULL.getMsg());
}
JSONObject json = JSONObject.fromObject(flotData);
ResponseUtils.renderJson(response, json.toString());
}
service这里就省略不写了,因为统计数据是基于sql查询的,所以service里没有任何逻辑,唯一就是维度不一样,使用的sql语句不一样,所以直接看dao的实现类:
@Override
public FlotDataVo getCountData(String dataType, Class<FlotPieVo> listClass,FlotDataVo flotData) {
StringBuffer sbf = new StringBuffer();
sbf.append("SELECT COUNT(1)/(SELECT COUNT(1) FROM t_coupon_view) as data,");
//这里就设置了3类统计,如果有其他需要可以自行扩展,根据3张表的任何字段都可以
switch(dataType) {
case "1": //劵名称
sbf.append("cv.coupon_name");
break;
case "2": //劵来源
sbf.append("cv.coupon_origin");
break;
case "3": //劵状态
sbf.append("cv.use_statu");
break;
}
sbf.append(" as label FROM (SELECT cvv.coupon_origin,cvv.coupon_name,cvv.own_user,CASE WHEN NOW() > cvv.ok_end_date THEN 3 else cvv.use_statu end AS use_statu FROM t_coupon_view cvv ) cv ");
sbf.append(" LEFT JOIN jc_user u on cv.own_user = u.user_id LEFT JOIN jc_user_ext ue ON u.user_id = ue.user_id where 1=1 ");
sbf.append(" GROUP BY ");
switch(dataType) {
case "1": //劵名称
sbf.append("cv.coupon_name");
break;
case "2": //劵来源
sbf.append("cv.coupon_origin");
break;
case "3": //劵状态
sbf.append("cv.use_statu");
break;
}
SQLQuery query = getSession().createSQLQuery(sbf.toString());
//query.addEntity(listClass); //为什么这里要用下面的,这是个秘密,我不告诉你,呵呵。hibernate的基础知识,在之前的经验文档hibernate的map属性过滤里提到过,hibernate实体类用addEntity ,不受Hibernate管理的实体类用setResultTransformer
query.setResultTransformer(Transformers.aliasToBean(listClass));
List list = query.list();
flotData.setPieData(list);
return flotData;
}
好了,基本上后台代码就完了,这个sql大家看明白大致意思就行,实际上维度就是sql的group by分组条件,如果你自己拼sql也按照这个思路拼就行。另外这里使用的是hibernate执行原生sql,中间没有用addEntity也标红说明 了,然后之前问大家为什么使用BigDecimal ,原因是sql执行的结果集这里的转换会按照最高精度对象转,使用float、double都会报argument type mismatch类型不匹配
好了,到这里就全部ok了,剩下的大家就可以*发挥了,期待我的下一次分享吧。