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 XML Graphics Project currently consists of the following sub-projects, each focused on a different aspect of XML Graphics:
Apache Batik - A toolkit for Scalable Vector Graphics (SVG), based in Java
Apache FOP - A print formatter & renderer for XSL-FO (FO=formatting objects), based in Java
Apache XML Graphics Commons - A library with various components used by Apache Batik and Apache FOP, written in Java
具体是啥意思就有劳各位大神自己去翻译了,所以java通过xml(json)等格式的数据转换为可以收缩大小的矢量图片的功能,当然,其中也有不少依赖的jar包,打开batik-all-1.6.jar我们就可以看到,如下),fop.jar,xerces.jar,这些jar包的来源请自己百度(谷歌被墙了,百度就凑合着用吧),当然我尽量在附件中上传这些jar包,highcharts-3.0.1的的js文件请自行下载,现在需要用到的js文件修改完成,jar包也齐全了。现在来看具体的jsp页面代码(此代参照别人的代码,自己手动加入了下载的功能)。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script type="text/javascript" src="<%=basePath%>Highcharts-3.0.1/jquery-1.8.0.min.js"></script>
<script type="text/javascript" src="<%=basePath%>Highcharts-3.0.1/highcharts.js"></script>
<script type="text/javascript" src="<%=basePath%>Highcharts-3.0.1/modules/exporting.js"></script>
<script type="text/javascript" src="<%=basePath%>js/chart.js"></script>
<script type="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: 'Tokyo hot',
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>
<div id="container" ></div>
</body>
</html>
实现颜色渐变的chart.js代码
//定义一个全局颜色数组(浅蓝色,深蓝色,浅绿色,沙棕色,深卡布色,天蓝色,沙***,宝蓝色,马棕色,灰色,闪光绿色,深灰色)
var colorArr = [
'#7CB5EC',
'#7171C6',
'#90ED7D',
'#F7A35C',
'#BDB76B',
'#87CEEB',
'#E4D354',
'#436EEE',
'#8D4653',
'#8B8B83',
'#00EE00',
'#B0B0B0'
];
//设置每一个数据点的颜色值
function SetEveryOnePointColor(chart) {
//获得第一个序列的所有数据点
var pointsList = chart.series[0].points;
//遍历设置每一个数据点颜色
for (var i = 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代码
package com.servlet;
import java.io.IOException;
import java.io.StringReader;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.batik.transcoder.Transcoder;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.p_w_picpath.JPEGTranscoder;
import org.apache.batik.transcoder.p_w_picpath.PNGTranscoder;
import org.apache.fop.svg.PDFTranscoder;
public class SaveAsImage extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public SaveAsImage() {
super();
}
public void destroy() {
super.destroy();
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");// 设置编码
String type = request.getParameter("type");
String svg = request.getParameter("svg");
String filename = request.getParameter("filename");
// String scale = request.getParameter("scale");
filename = filename == null ? "chart" : filename;
ServletOutputStream out = response.getOutputStream();
if (null != type && null != svg) {
svg = svg.replaceAll(":rect", "rect");
// 定义文件后缀名
String ext = "";
Transcoder t = null;
if (type.equals("p_w_picpath/png")) {
ext = "png";
t = new PNGTranscoder();
} else if (type.equals("p_w_picpath/jpeg")) {
ext = "jpg";
t = new JPEGTranscoder();
} else if (type.equals("p_w_picpath/svg+xml")) {
ext = "svg";
} else if (type.equals("application/pdf")) {
ext = "pdf";
t = (Transcoder) new PDFTranscoder();
}
response.addHeader("Content-Disposition", "p_w_upload; filename=chart." + 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("编码流错误.");
e.printStackTrace();
}
} else if (ext == "svg") {
svg = svg.replace("http://www.w3.org/2000/svg", "http://www.w3.org/TR/SVG11/");
out.print(svg);
} else {
out.print("Invalid type: " + type);
}
} else {
response.addHeader("Content-Type", "text/html");
}
out.flush();
out.close();
}
public void init() throws ServletException {
}
}
web.xml配置代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="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/javaee
http://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图表
var chart;
var time;
var z;
var q;
function showCharts(){
$.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 = new Highcharts.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() {
return this.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的属性要相同,
<div id="container" ></div>
到这里,highcharts结合json显示图表已经完成,如果想要实现柱状图渐变的图标效果,请自己加上实现颜色渐变的js代码去实现。需要用的js文件与jar包请到http://down.51cto.com/data/1890578自行下载。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。