highcharts结合JSON实现柱状图
highcharts是基于javascript的图表库,可以很简单快捷的在web应用程序中添加交互性很强的图表,可以免费提供给个人,非商业用途使用,支持的图表类型有曲线图、区域图、柱状图、饼状图、散状点图和综合图表。
highcharts图表的界面美观,因为是通过javascript编写的,所以不需要安装插件即可运行,且运行的速度极快,兼容性好。本人亲测在IE8(需要将IE8的浏览器模式设置成IE8(B),文本模式设置为IE8标准),firefox33.0,Chrome28.0下图表显示良好,图表导出PNG,JPEG,PDF,SVG位图功能完全正常。附上在IE8上显示的图表截图一张。
以上图表的显示请参照http://www.stepday.com/topic/?951上的示例。如果要实现图表导出png或者jpeg等的功能的话,页面除了引用highcharts的核心js文件highcharts.js之外,还需要引用modules/exporting.js,除此之外,还需要修改下exporting.js,如果要鼠标悬浮出现中文的提示,将printChart ,downloadPNG ,downloadJPEG ,downloadPDF ,downloadSVG,contextButtonTitle 换成中文提示即可,如下所示:
printChart : "打印图表",downloadPNG : "导出 PNG 图像",
downloadJPEG : "导出 JPEG 图像",downloadPDF : "导出 PDF 文档",
downloadSVG : "Download SVG vector p_w_picpath",contextButtonTitle : "图表导出"
还需要将enctype : "multipart/form-data"这行代码注释或者去掉,如果不将这行代码注释或者去掉的话,通过servlet或者action是无法通过提取svg的xml,通过fop将图表转为jpeg格式的图片的。原因在于highcharts的exporting.js中采用的form是mulipart/form类型,使servlet或者action通过request的request.getParemeter获取到的svg的xml字符串为空(具体可以通过控制台输出查看),因此无法输出jpeg格式的图片。我们要输出图片,pdf,SVG位图还需要用到batik-all-1.6.jar(此jar包中集成了很多开源的jar包核心的处理jar包为batik-codec.jar,它是apache项目组下面的一个专门用来处理图形生成技术的开源产品:
The Apache XMLGraphics Project currently consists of the followingsub-projects, each focused on a different aspect of XMLGraphics:
ApacheBatik - A toolkit for Scalable VectorGraphics (SVG), based in Java
ApacheFOP - A print formatter & rendererfor XSL-FO (FO=formatting objects), based in Java
Apache XMLGraphics Commons - A library withvarious components used by Apache Batik and Apache FOP, written inJava
具体是啥意思就有劳各位大神自己去翻译了,所以java通过xml(json)等格式的数据转换为可以收缩大小的矢量图片的功能,当然,其中也有不少依赖的jar包,打开batik-all-1.6.jar我们就可以看到,如下),fop.jar,xerces.jar,这些jar包的来源请自己百度(谷歌被墙了,百度就凑合着用吧),当然我尽量在附件中上传这些jar包,highcharts-3.0.1的的js文件请自行下载,现在需要用到的js文件修改完成,jar包也齐全了。现在来看具体的jsp页面代码(此代参照别人的代码,自己手动加入了下载的功能)。
<%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%><%Stringpath=request.getContextPath();StringbasePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"><html><head><basehref="<%=basePath%>"><title>MyJSP'index.jsp'startingpage</title><metahttp-equiv="pragma"content="no-cache"><metahttp-equiv="cache-control"content="no-cache"><metahttp-equiv="expires"content="0"><metahttp-equiv="keywords"content="keyword1,keyword2,keyword3"><metahttp-equiv="description"content="Thisismypage"><scripttype="text/javascript"src="<%=basePath%>Highcharts-3.0.1/jquery-1.8.0.min.js"></script><scripttype="text/javascript"src="<%=basePath%>Highcharts-3.0.1/highcharts.js"></script><scripttype="text/javascript"src="<%=basePath%>Highcharts-3.0.1/modules/exporting.js"></script><scripttype="text/javascript"src="<%=basePath%>js/chart.js"></script><scripttype="text/javascript"charset="UTF-8">$(function(){$('#container').highcharts({chart:{type:'column'},title:{text:'数据点线性颜色渐变效果'},xAxis:{categories:['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']},yAxis:{min:0,title:{text:'雨量值(mm)'}},tooltip:{headerFormat:'<span>{point.key}</span><table>',pointFormat:'<tr><td>{series.name}:</td>'+'<td><b>{point.y:.1f}mm</b></td></tr>',footerFormat:'</table>',shared:true,useHTML:true},plotOptions:{column:{pointPadding:0.2,borderWidth:0,dataLabels:{enabled:true,//是否显示数据标签}}},credits:{//去掉右下角显示的Highcharts.com声明enabled:false},exporting:{filename:'chart',url:'http://localhost:8080/chart/saveAsImage',//可以修改exporting.js中对应的url,这里的url会让exporting.js中的无效},series:[{name:'Tokyohot',data:[49.9,71.5,106.4,129.2,144.0,176.0,135.6,148.5,216.4,194.1,95.6,54.4]}]},function(chart){SetEveryOnePointColor(chart);});});</script></head><body><divid="container"></div></body></html>
实现颜色渐变的chart.js代码
//定义一个全局颜色数组(浅蓝色,深蓝色,浅绿色,沙棕色,深卡布色,天蓝色,沙***,宝蓝色,马棕色,灰色,闪光绿色,深灰色)varcolorArr=['#7CB5EC','#7171C6','#90ED7D','#F7A35C','#BDB76B','#87CEEB','#E4D354','#436EEE','#8D4653','#8B8B83','#00EE00','#B0B0B0'];//设置每一个数据点的颜色值functionSetEveryOnePointColor(chart){//获得第一个序列的所有数据点varpointsList=chart.series[0].points;//遍历设置每一个数据点颜色for(vari=0;i<pointsList.length;i++){chart.series[0].points[i].update({color:{linearGradient:{x1:0,y1:0,x2:1,y2:0},//横向渐变效果如果将x2和y2值交换将会变成纵向渐变效果stops:[[0,Highcharts.Color(colorArr[i]).setOpacity(1).get('rgba')],[0.5,'rgb(255,255,230)'],[1,Highcharts.Color(colorArr[i]).setOpacity(1).get('rgba')]]}});}}
servlet代码
packagecom.servlet;importjava.io.IOException;importjava.io.StringReader;importjavax.servlet.ServletException;importjavax.servlet.ServletOutputStream;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importorg.apache.batik.transcoder.Transcoder;importorg.apache.batik.transcoder.TranscoderException;importorg.apache.batik.transcoder.TranscoderInput;importorg.apache.batik.transcoder.TranscoderOutput;importorg.apache.batik.transcoder.p_w_picpath.JPEGTranscoder;importorg.apache.batik.transcoder.p_w_picpath.PNGTranscoder;importorg.apache.fop.svg.PDFTranscoder;publicclassSaveAsImageextendsHttpServlet{/****/privatestaticfinallongserialVersionUID=1L;publicSaveAsImage(){super();}publicvoiddestroy(){super.destroy();}publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{doPost(request,response);}publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{request.setCharacterEncoding("UTF-8");//设置编码Stringtype=request.getParameter("type");Stringsvg=request.getParameter("svg");Stringfilename=request.getParameter("filename");//Stringscale=request.getParameter("scale");filename=filename==null?"chart":filename;ServletOutputStreamout=response.getOutputStream();if(null!=type&&null!=svg){svg=svg.replaceAll(":rect","rect");//定义文件后缀名Stringext="";Transcodert=null;if(type.equals("p_w_picpath/png")){ext="png";t=newPNGTranscoder();}elseif(type.equals("p_w_picpath/jpeg")){ext="jpg";t=newJPEGTranscoder();}elseif(type.equals("p_w_picpath/svg+xml")){ext="svg";}elseif(type.equals("application/pdf")){ext="pdf";t=(Transcoder)newPDFTranscoder();}response.addHeader("Content-Disposition","p_w_upload;filename=chart."+ext);response.addHeader("Content-Type",type);if(null!=t){TranscoderInputinput=newTranscoderInput(newStringReader(svg));TranscoderOutputoutput=newTranscoderOutput(out);try{t.transcode(input,output);}catch(TranscoderExceptione){out.print("编码流错误.");e.printStackTrace();}}elseif(ext=="svg"){svg=svg.replace("http://www.w3.org/2000/svg","http://www.w3.org/TR/SVG11/");out.print(svg);}else{out.print("Invalidtype:"+type);}}else{response.addHeader("Content-Type","text/html");}out.flush();out.close();}publicvoidinit()throwsServletException{}}
web.xml配置代码
<?xmlversion="1.0"encoding="UTF-8"?><web-appversion="2.5"xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><servlet><servlet-name>saveAsImage</servlet-name><servlet-class>com.servlet.SaveAsImage</servlet-class></servlet><servlet-mapping><servlet-name>saveAsImage</servlet-name><url-pattern>/saveAsImage</url-pattern></servlet-mapping><welcome-file-list><welcome-file>aa.jsp</welcome-file></welcome-file-list></web-app>
图表的显示与下载功能到此就OK了。
现在来进入本文的重点,结合json实现图表的展示。由于本人的项目中用到了struts2,所以实现图表导出为png,jpeg也是采用的action来实现了,将上面的servlet改写为struts2的action来说应该没啥难度,这里就请广大程序猿自己动手一试吧。既然用到了JSON,就需要用到相关的jar包,我这里用的是json-lib-2.1-jdk15.jar(当然,你也可以使用StringBuffer去手动拼接来实现JSON的格式,前提是你不怕麻烦,不嫌繁琐,不怕出错),在action中,只需要简单的几句代码就能将List集合转换成JSON格式的数据,并通过out.print输出到jsp页面,具体代码如下:
HttpServletResponse response = ServletActionContext.getResponse();
PrintWriter out = response.getWriter();
JSONArray json = JSONArray.fromObject(list);
//输出json,去验证json的格式是否正确
//System.out.println(json.toString());
out.print(json.toString());
控制台输出的json数据为:
[{"STLC":"枝江善溪冲 ","MX":2,"Q":1.45,"WPTN":"4","STCD":"00000001","WZ":null,"TM":"2014-01-02","ADMAUTH":"信息管理单位","RVNM":null,"LOCALITY":null,"STNM":"雨量站","Z":1.45}]
当页面访问该action的时候,JSON格式的数据已经输出到jsp页面了。现在我们可以通过jquery的ajax方式访问action,并且在成功的回调函数返回数据,并进行解析,具体代码如下:
//显示higthcharts图表varchart;vartime;varz;varq;functionshowCharts(){$.ajax({type:'POST',dataType:'json',async:false,url:'/water/water!getDayList.action',data:{tm:$("#w_d_l_tm").val()},success:function(data){//遍历$.each(data,function(i,t){stlc=t.STLC.trim();time=t.TM;z=t.Z;q=t.Q;//初始化highcharts图表chart=newHighcharts.Chart({chart:{renderTo:'container',//制定图标显示的层的id//defaultSeriesType:'column'//柱状图line直线图,spline折线图,pie饼状图,area区域图,more综合图type:'column'//zoomType:'xy',},credits:{//去掉右下角显示的Highcharts.com声明enabled:false},title:{text:stlc+'水情日报表',x:-20},//X坐标xAxis:{categories:['水位','流量']},//Y坐标(分别有水位与流量两个)yAxis:[{title:{text:'水位(m)'},style:{color:'#89A54E'},opposite:false},{gridLineWidth:0,title:{text:'流量(m3/s)'},style:{color:'#4572A7'},opposite:true}],exporting:{filename:'chart',url:'/chartImage!chart.action'},//此处是关键点,也可以修改exporting.js中对应的url,如果不需要此功能,不写exporting即可/*如果只需要将图表导出为指定格式的图片请使用下面的方法,即重写exporting中的一些东西exporting:{type:'p_w_picpath/png',url:'http://127.0.0.1:8080/yeqh/chartImg/',buttons:{contextButton:{menuItems:[,{text:'导出PNG图片文件',onclick:function(){this.exportChart();},separator:false}]}}}*///鼠标悬浮提示tooltip:{formatter:function(){returnthis.x+':'+this.y;}},//设置图例/*legend:{layout:'vertical',//水平排列//线条说明停靠位置align:'right',verticalAlign:'middle',x:10,y:100,shadow:true,//设置阴影borderWidth:0,floating:true,},*/plotOptions:{column:{pointPadding:0.5,borderWidth:0,pointWidth:30,//这种柱状的宽度dataLabels:{enabled:true,//是否显示数据标签}}},series:[{name:'水位',data:[z,q]}]});});}});}
jsp需要定义一个div,此div的id与上面js中的renderTo的属性要相同,
<divid="container"></div>
到这里,highcharts结合json显示图表已经完成,如果想要实现柱状图渐变的图标效果,请自己加上实现颜色渐变的js代码去实现。需要用的js文件与jar包请到http://down.51cto.com/data/1890578自行下载。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。