这里使用的highchart是2014-01-09从官网下载的版本,版本号是3.0.8,

当过了几天后,发现版本号变成了3.0.9,不由得的感叹highchart的版本更新之快。

在jsp中使用highchart的步骤:

第一步:引入highchart必需的js文件

<! -- jquery的js要在引入highchart插件的js之前引入 -->
<script
src="<%=basePath%>js/Highcharts3.0.8/jquery-1.8.3.js"> </script> <!-- 实现highchart核心功能的js --> <script src="<%=basePath%>js/Highcharts3.0.8/highcharts.js"> </script> <!-- 导出和打印相关的js ,因为这里修改过的exporting.js包含中文,使用 charset="UTF-8" 进行指定 --> <script src="<%=basePath%>js/Highcharts3.0.8/exporting.js" charset="UTF-8"> </script>

View Code

开发过程遇到的问题:

1)  Js的引入顺序错了,导致highchart的图表出不来,

Highchart插件中用到了jquery,当时jquery-1.8.3.js引入顺序放到了highchart插件js的下面,

导致当加载highchart插件用到的js时,找不到jquery的js,报出某个js的函数不合法

因此 jqueryjs要在引入highchartjs之前引入

2)  exporting.js 打印下载的js中,提示的都是英文,

要显示中文,这里采用的方法是修改exporting.js

p(s.lang,{printChart:"打印报表",downloadPNG:"下载为PNG格式图片",downloadJPEG:"下载为JPEG格式图片",

downloadPDF:"下载为PDF格式文档",downloadSVG:"下载为SVG格式矢量图片",contextButtonTitle:"打印 下载"});

修改后的效果:

                    

当修改了exporting.js后,当保存时,没法保存js,提示编码问题

解决方法是:

window>>preferences>>general>>content types  在右边的窗口中打开列表,选中"JavaScript",在下面的"default encoding"右边的输入框中输入"utf-8",再点"update"按钮

单击打印下载时,显示的下拉框在大部分的ie浏览器中显示的很难看,火狐下正常

原因: 上面的下拉框显示很长,是由于hr标签的原因,导致hr的宽度按照 100%进行了显示

解决方法:

在显示highchart图标的jsp页面中,添加hr的样式

<style>

hr{height: 0;margin: 0;padding: 0;width: 0;}

</style>

第二步:组装添加显示highchart图表所用的数据

显示highchart图标的js代码$(function () {//填充数据使用,使用jquery来获取隐藏域的值var xAxisTimeInfo = $("#xAxisTime").val();var totalRecordInfo = $("#totalRecord").val();var totalRecordHYInfo = $("#totalRecordHY").val();var totalRecordLJInfo = $("#totalRecordLJ").val();$('#container').highcharts({chart: {type: 'spline'},title: {text: '每月订单数量统计'},subtitle: {text: ''},exporting:{ filename:"订单统计", //下载显示的文件名称sourceWidth: 1000,     //下载图片的宽度sourceHeight: 550,  //下载图片的高度//指定下载图片的url,这里使用的本地的java代码,没有使用官网的代码(那//样会受到highchart官网的网络限制,这里的java代码是结合的struts1来//实现的,在java代码解决了导出图片中中文乱码的问题以及下载文件名乱码//的问题,详见java代码中说明)               url:'<%=basePath%>shop/newOrder/orderPre/exportImage.do'//这里是一个重点哦,也可以修改exporting.js中对应的url }, /** * 去掉图标的右下角HightCharts.com 的图标 */ credits: { enabled : false, //设置false就不会显示右下角的官网链接 //右下角连接的显示位置 position:{ align: 'right',x: -8, verticalAlign: 'bottom',y: -390 }, //右下角链接的地址href:'<%=basePath%>shop/newOrder/orderPre/orderSearch4HighCharts.do?type=1', text:'区域图表',//右下角连接的名字 style : {cursor:'pointer',color:'#909090',fontSize:'20px'} }, xAxis: { categories: eval(xAxisTimeInfo) }, yAxis: { min: 0, title: { text: '单位 (个)' } }, //鼠标旁边的提示框的样式 //1. point.y:.0f 提示框中显示的y轴单位的小数点位数 //2. style="width:160px;height:50px" 提示框的宽高 //3. point.key 坐标的x轴的值 tooltip: { headerFormat: '<span style="font-size:20px;">{point.key}</span><table style="width:160px;height:50px">', pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' + '<td style="padding:0"><b>{point.y:.0f} </b></td></tr>', footerFormat: '</table>', shared: true, useHTML: true }, plotOptions: { column: { pointPadding: 0.2, borderWidth: 0 } }, //图例的显示名称和数据 //这里使用了eval函数处理一下,使用jquery获取到的隐藏域的值 //否则不会显示 series: [{ name: '裸机数量', data: eval(totalRecordLJInfo) }, { name: '订单总量', data: eval(totalRecordInfo) }, { name: '合约机数量', data: eval(totalRecordHYInfo) }] }); }); 

View Code

基本的highchart显示的数据格式是:

X轴数据信息

图例和显示数据的格式:

因此我们要做的就是根据需求,在java后台组装好上面的数据,填充到highchart的js代码中即可

导出的Java后台代码    (使用的是struts1)没有在struts的配置文件中配置,直接是在jspurl请求

struts1版的结合highchart导出图片的java代码

使用highchart调用本地的java类导出图片时,用到的jar

batik-all-1.6.jar  fop.jar     xerces-2.9.0.jar

/*** 配合highchart插件导出图片* @param mapping* @param form * @param request * @param response * @return * @throws Exception */ public ActionForward exportImage (ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { log.info("图片导出................"); request.setCharacterEncoding("gb2312");//设置编码,解决乱码问题 String type = request.getParameter("type"); String svg = request.getParameter("svg"); response.setCharacterEncoding("gb2312");//设置编码,解决乱码问题 String filename = request.getParameter("filename"); filename = filename==null?"chart":filename; ServletOutputStream out = response.getOutputStream(); log.info("type :"+type+" filename:"+filename); if (null != type && null != svg) { svg = svg.replaceAll(":rect", "rect"); String ext = ""; Transcoder t = null; if (type.equals("image/png")) { ext = "png"; t = new PNGTranscoder(); } else if (type.equals("image/jpeg")) { ext = "jpg"; t = new JPEGTranscoder(); }else if (type.equals("application/pdf")) { ext = "pdf"; t =(Transcoder) new PDFTranscoder(); }else if(type.equals("image/svg+xml")) ext = "svg"; //解决下载文件的文件名的乱码 response.addHeader("Content-Disposition", "attachment; filename="+ new String (filename.getBytes("gb2312"),"iso-8859-1") + "."+ext); response.addHeader("Content-Type", type); if (null != t) { TranscoderInput input = new TranscoderInput(new StringReader(svg)); TranscoderOutput output = new TranscoderOutput(out); try { t.transcode(input, output); } catch (TranscoderException e) { out.print("Problem transcoding stream. See the web logs for more details."); e.printStackTrace(); } } else if (ext.equals("svg")) { OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8"); writer.append(svg); writer.close(); } else out.print("Invalid type: " + type); } else { response.addHeader("Content-Type", "text/html"); out.println("Usage:\n\tParameter [svg]: The DOM Element to be converted." + "\n\tParameter [type]: The destination MIME type for the elment to be transcoded."); } out.flush(); out.close(); return null; } 

View Code

使用highchart生成报表信息的部分后台java代码

开发中遇到的问题

  1. 在开发中使用了webservice,在dao层的java代码中使用了Map,但是Map在webservice中并不支持,
  2. 解决方法就是,在dao层的java代码中把Map中的数据使用json-lib插件转换成了Json
  3. 然后在action层中再使用json-lib插件转换成Map

java代码片段

Dao层的代码片段,查询数据封装成map,然后把map数据放到List中,然后在把list放到map中,调用json-lib插件转换成json数据List ltHY = findSQL(dto, sqlHY.toString(), list.toArray());
List adminSqlTotalHY = new ArrayList();//使用的LinkedHashMap,放到map中的数据使用顺序的 Map<String ,String> totalRecordHYMap = new LinkedHashMap<String ,String>(); for (int i = 0; ltHY!=null && i < ltHY.size(); i++) { Object[] obj = (Object[]) ltHY.get(i); totalRecordHYMap.put(obj[0]!=null?String.valueOf(obj[0]):"" ,obj[1]!=null? String.valueOf(obj[1]):""); } adminSqlTotalHY.add(totalRecordHYMap); //保存到map中 Map recordInfo = new LinkedHashMap(); recordInfo.put("Record_total", adminSqlTotalList); recordInfo.put("Record_LJ", adminSqlTotalLJ); recordInfo.put("Record_HY", adminSqlTotalHY); //把map数据转化为json数据 JSONObject jsonObjectFromMap =JSONObject.fromObject(recordInfo); dto.setAddress(jsonObjectFromMap.toString()); 

View Code

action层代码
/*** 1. 构造HighChart的x轴用到的每月时间数据信息 (月份不足两位的没有补0,直接放在request中)<P/>* 2. 返回值map中月份不足2位的,进行了补0,该map在构造每月订单数量统计时使用* @throws ParseException*/ private Map extractHighChartXAxisInfo(HttpServletRequest request) throws ParseException { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); Calendar curr = Calendar.getInstance(); Calendar curr2 = curr; Date beginPayDate = curr.getTime(); // 传进来的当前时间 curr2.add(Calendar.YEAR, -1); curr2.add(Calendar.MONTH, 1); Date endPayDate = curr2.getTime(); // 上一年的时间  GregorianCalendar[] ga=getDate(simpleDateFormat.format(endPayDate), simpleDateFormat.format(beginPayDate)); //循环数组 StringBuffer stringBuffer = new StringBuffer(); Map initMap = new LinkedHashMap(); stringBuffer.append("["); for(GregorianCalendar e:ga) { stringBuffer.append("'"+modifyTimeAnthor(e)+"',"); initMap.put(modifyTime(e), 0); } //当ga数组中有数据时才删除末尾的 逗号 if(stringBuffer.length()>1){ stringBuffer.deleteCharAt(stringBuffer.length()-1); } stringBuffer.append("]"); log.info("x轴用到的每月时间数据信息 (月份不足两位的没有补0) "+stringBuffer.toString()); request.setAttribute("highChartXAxisInfo", stringBuffer.toString()); return initMap; }

View Code

/*** * @param startTime* @param endTime * @return 返回开始时间和结束时间之间的每一个月 * 如:2013.1 2013.2 2013.3 2013.4 2013.5 2013.6 2013.7 * @throws ParseException */ public static GregorianCalendar[] getDate(String startTime,String endTime) throws ParseException { Vector<GregorianCalendar> v=new Vector<GregorianCalendar>(); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM"); GregorianCalendar gc1=new GregorianCalendar(),gc2=new GregorianCalendar(); gc1.setTime(sdf.parse(startTime)); gc2.setTime(sdf.parse(endTime)); do{ GregorianCalendar gc3=(GregorianCalendar)gc1.clone(); v.add(gc3); gc1.add(Calendar.MONTH, 1); }while(!gc1.after(gc2)); return v.toArray(new GregorianCalendar[v.size()]); } //按格式获取时间,月份不足两位的补0 public static String modifyTime(GregorianCalendar e){ String curdate = e.get(Calendar.YEAR)+""; if((e.get(Calendar.MONTH)+1)<10){ curdate = curdate+".0" +(e.get(Calendar.MONTH)+1); }else { curdate = curdate+"."+(e.get(Calendar.MONTH)+1); } return curdate; } //按格式获取时间,月份不足两位的没有补0 public static String modifyTimeAnthor(GregorianCalendar e){ String curdate = e.get(Calendar.YEAR)+""; curdate = curdate+"."+(e.get(Calendar.MONTH)+1); return curdate; } /** * 1. 传递查询时间段的日期信息<p/> * 2. 要求查询当月以及向前倒推11个月(总共12的月)的数据<p/> * 3. 如当前日期是 2014.01,则构造开始时间2013.02,结束时间2014.02,都是由于oracle的between and * @param mulOrderDTO */ private void passDateInfo(TMulOrderCountDTO mulOrderDTO) { //传递月份信息 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM"); Calendar curr = Calendar.getInstance(); //注意这里把curr变量的引用赋值给了curr2,当curr的值变化时,会影响到curr2的值 Calendar curr2 = curr; curr.add(Calendar.MONTH, 1); Date beginPayDate = curr.getTime(); // 传进来的当前时间 curr2.add(Calendar.YEAR, -1); Date endPayDate = curr2.getTime(); // 上一年的时间  mulOrderDTO.setBeginPayDate(simpleDateFormat.format(endPayDate)); mulOrderDTO.setEndPayDate(simpleDateFormat.format(beginPayDate)); } 

View Code

/*** 构造每个月  订单总量、合约机总量、裸机总量的字符串信息,用于填充highChart插件 * @param request* @param str */ @SuppressWarnings("unchecked") private void extractHighChartRecordInfo(HttpServletRequest request, String str,Map initMap) { //接受最初传进来的map,使用了LinkedHashMap的构造方法,参数为map //由于数据的显示问题,这里构造了初始化的LinkedHashMap(带顺序) Map originalTotalMap = new LinkedHashMap(initMap); Map originalTotalLJMap = new LinkedHashMap(initMap); Map originalTotalHYMap = new LinkedHashMap(initMap); //把json数据重新转换为Map数据 Map<String, Object> m = parseJSON2Map(str); //遍历map,拿到map的key的集合的迭代对象 Iterator<Map.Entry<String,Object>> iterator = m.entrySet().iterator(); while(iterator.hasNext()){ //拿到当前的迭代对象 Map.Entry<String, Object> me = iterator.next(); //拿到当前迭代对象的key(可以看做map的key) String key = me.getKey(); String keyW = key.substring(key.indexOf("_")+1); if("LJ".equals(keyW)){ //拿到当前迭代对象的value,是List对象,取第一个元素拿到map List li = (List) me.getValue(); //拿到map Map map = (Map) li.get(0); //覆盖一下初始化map的数据  originalTotalLJMap.putAll(map); //拿到实际上保存数据的Map集合,如保存每月裸机订单数据的map Iterator<Map.Entry<String,Object>> iterator1 = originalTotalLJMap.entrySet().iterator(); StringBuffer stringBufferLJ = new StringBuffer(); stringBufferLJ.append("["); log.info("解析每月裸机数据.................................................."); while(iterator1.hasNext()){ Map.Entry<String, Object> mea = iterator1.next(); //这里的getKey获取到是月份 如:2013.1 String keya = mea.getKey(); log.info(keya+" "+mea.getValue()); // getValue()是获取当月的订单数量,保存到StringBuffer中,并处理//StringBuffer数据使得满足highchart插件的要求 stringBufferLJ.append(mea.getValue()+","); } //当iterator1中有数据时才删除掉末尾的逗号 if(stringBufferLJ.length()>1){ stringBufferLJ.deleteCharAt(stringBufferLJ.length()-1); } stringBufferLJ.append("]"); log.info("裸机订单数量 :"+stringBufferLJ.toString()); request.setAttribute("totalRecordLJ", stringBufferLJ.toString()); } if("HY".equals(keyW)){ List li = (List) me.getValue(); //拿到map Map map = (Map) li.get(0); originalTotalHYMap.putAll(map); Iterator<Map.Entry<String,Object>> iterator1 = originalTotalHYMap.entrySet().iterator(); StringBuffer stringBufferHY = new StringBuffer(); stringBufferHY.append("["); log.info("解析每月合约机数据.................................................."); while(iterator1.hasNext()){ Map.Entry<String, Object> mea = iterator1.next(); String keya = mea.getKey(); stringBufferHY.append(mea.getValue()+","); log.info(keya+" "+mea.getValue()); } //当iterator1中有数据时才删除掉末尾的逗号 if(stringBufferHY.length()>1){ stringBufferHY.deleteCharAt(stringBufferHY.length()-1); } stringBufferHY.append("]"); log.info("合约机订单数量 :"+stringBufferHY.toString()); request.setAttribute("totalRecordHY", stringBufferHY.toString()); } if("total".equals(keyW)){ List li = (List) me.getValue(); //拿到map Map map = (Map) li.get(0); originalTotalMap.putAll(map); Iterator<Map.Entry<String,Object>> iterator1 = originalTotalMap.entrySet().iterator(); StringBuffer stringBufferTotal = new StringBuffer(); stringBufferTotal.append("["); log.info("解析每月订单总量数据.................................................."); while(iterator1.hasNext()){ Map.Entry<String, Object> mea = iterator1.next(); String keya = mea.getKey(); stringBufferTotal.append(mea.getValue()+","); log.info(keya+" "+mea.getValue()); } //当iterator1中有数据时才删除掉末尾的逗号 if(stringBufferTotal.length()>1){ stringBufferTotal.deleteCharAt(stringBufferTotal.length()-1); } stringBufferTotal.append("]"); log.info("总订单数量 :"+stringBufferTotal.toString()); request.setAttribute("totalRecord", stringBufferTotal.toString()); } } } 

View Code

highcharts效果图

附上jsp的代码

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <head> <script src="<%=basePath%>js/Highcharts3.0.8/jquery-1.8.3.js"></script> <script src="<%=basePath%>js/Highcharts3.0.8/highcharts.js"></script> <script src="<%=basePath%>js/Highcharts3.0.8/exporting.js" charset="UTF-8"></script> <style> hr{height: 0;margin: 0;padding: 0;width: 0;} </style> <script> $(function () { var xAxisTimeInfo = $("#xAxisTime").val(); var totalRecordInfo = $("#totalRecord").val(); var totalRecordHYInfo = $("#totalRecordHY").val(); var totalRecordLJInfo = $("#totalRecordLJ").val(); $('#container').highcharts({ chart: { type: 'column' }, title: { text: '每月订单数量统计' }, subtitle: { text: '' }, exporting:{ filename:"订单统计", sourceWidth: 1000, sourceHeight: 550, url:'<%=basePath%>shop/newOrder/orderPre/exportImage.do'//这里是一个重点哦,也可以修改exporting.js中对应的url  }, /** * 去掉图标的右下角HightCharts.com 的图标 */ credits: { enabled : false, position:{ align: 'right',x: -8, verticalAlign: 'bottom',y: -390 }, href:'<%=basePath%>shop/newOrder/orderPre/orderSearch4HighCharts.do?type=1', text:'区域图表', style : {cursor:'pointer',color:'#909090',fontSize:'20px'} }, xAxis: { categories: eval(xAxisTimeInfo) }, yAxis: { min: 0, title: { text: '单位 (个)' } }, tooltip: { headerFormat: '<span style="font-size:20px;">{point.key}</span><table style="width:160px;height:50px">', pointFormat: '<tr><td style="padding:0">{series.name}: </td>' + '<td style="padding:0"><b>{point.y:.0f} </b></td></tr>', footerFormat: '</table>', shared: true, useHTML: true }, plotOptions: { column: { pointPadding: 0.2, borderWidth: 0 } }, series: [{ name: '裸机数量', data: eval(totalRecordLJInfo) }, { name: '订单总量', data: eval(totalRecordInfo) }, { name: '合约机数量', data: eval(totalRecordHYInfo) }] }); }); function showAreaView(){ window.document.location.href

highcharts插件使用总结和开发中遇到的问题及解决办法相关推荐

  1. java开发报错怎么处理_Java开发中常见报错及解决办法

    前言: 在项目开发中,往往会遇到很多错误,有些是代码有误,而有些则是其他原因.接下来一起看看常见的报错及解决办法(小白整理,大牛勿喷). 一.找不到Xxx.Xxx.entity.Xxx.java 最近 ...

  2. [PyQt4]项目开发中遇到的错误与解决办法

    1假如将ui文件py化以后产生的关于界面的类是继承object的ui_dialog,方法是setupui,则在主程序中应: app = QtGui.QApplication(sys.argv) dia ...

  3. vue中使用海康插件实现视频监控-流不稳定导致视频断开前端解决办法

    vue中使用海康插件实现视频监控-流不稳定导致视频断开前端解决办法 配置和启用海康插件详情看本人博客 链接:https://blog.csdn.net/jinglianglove/article/de ...

  4. java开发中遇到的问题及解决方法(持续更新)

    java开发中遇到的问题及解决方法(持续更新) 参考文章: (1)java开发中遇到的问题及解决方法(持续更新) (2)https://www.cnblogs.com/LiuYanYGZ/p/6112 ...

  5. 开发中内存溢出问题及解决

    开发中内存溢出问题及解决 参考文章: (1)开发中内存溢出问题及解决 (2)https://www.cnblogs.com/yangyi1024/p/6417874.html 备忘一下.

  6. 微信小程序在开发中遇到的问题与解决方法

    微信小程序在开发中遇到的问题与解决方法 参考文章: (1)微信小程序在开发中遇到的问题与解决方法 (2)https://www.cnblogs.com/zjjDaily/p/8032142.html ...

  7. web开发中目录路径问题的解决

    web开发中目录路径问题的解决 参考文章: (1)web开发中目录路径问题的解决 (2)https://www.cnblogs.com/freeweb/p/4751403.html 备忘一下.

  8. Android实际开发中的bug总结与解决方法(一)

    Android实际开发中的bug总结与解决方法(一) 参考文章: (1)Android实际开发中的bug总结与解决方法(一) (2)https://www.cnblogs.com/ywq-come/p ...

  9. 前端开发中遇到的问题及解决方法

    前端开发中遇到的问题及解决方法 1,何为MVVM? view层: 视觉层:在前端开发中,通常是DOM层:主要作用是给用户展示各种信息: Model层: 数据层:数据可能是我们固定的死数据,更多的是来自 ...

最新文章

  1. eslint vscode 自动格式化_配置VSCode编辑器适配VUE3开发
  2. 成功解决attrs = config.__dict__['__flags'] KeyError: '__flags
  3. linux--select
  4. c++ 使用nacos_Nacos配置的多环境管理
  5. 机器学习和AI的区别是什么?| 今日吐槽
  6. Python基础篇:常见常用且要常记得的数据类型--列表
  7. jar文件打不开,用什么打开
  8. 看完这一篇,智能家居的坑你至少避开80%(上)
  9. unity中eulerAngles和rotation的区别
  10. cmake + googletest 之一 入门
  11. Silverlight实用窍门系列:29.Silverlight碰撞测试、检测自定义控件碰撞,雷达扫描图之扫描雷达点状态【附带源码实例】...
  12. win10系统服务器错误怎么解决方法,分享win10系统提示内部服务器错误的解决方案...
  13. 新一代人工智能:从“感知智能”向“认知智能”转化
  14. 那些坚持买彩票想中500万的人,都是一些什么心态?分析一下
  15. Redis学习 master/slave(主从)、sentinel(哨兵)、Cluster简单总结
  16. 恭喜 李志强 成为 Layotto committer!
  17. 2018年江苏大学885代码题(含答案)
  18. sql语句学习与使用
  19. matlab对直方图分类,matlab根据直方图进行图片分类
  20. 近红外光谱建模之光谱预处理python实现(一)

热门文章

  1. python3 验证用户名密码
  2. Bzoj4542--Hnoi2016大数
  3. 【bzoj 3531】 [Sdoi2014]旅行(树链剖分+树套树)
  4. 面向对象下计算器的编码实现
  5. Python for和if的连写
  6. python自动化测试难不难_我从功能测试进阶到自动化测试工程师的经验总结~|Atstudy...
  7. python爬取贴吧图片_Python爬取贴吧多页图片
  8. html如何与js链接,链接index.html client.js和server.js
  9. python学习模型_python学习笔记(IO模型)
  10. 局域网即时通讯软件java_如何选择企业即时通讯软件?