当前位置: 代码迷 >> Web前端 >> Highcharts进阶使用
  详细解决方案

Highcharts进阶使用

热度:814   发布时间:2012-09-14 23:00:49.0
Highcharts进阶应用


?JQuery
插件之-Highcharts在****项目中的应用-进阶篇

WYQ

????? 本文档主要讲Highcharts2个地方的改进之处,1是在柱状图中为每个柱子设置不同的颜色,2是改造highchars自带的图表下载功能。

?

1.???????? 在柱状图中给每块柱子设置七彩斑斓的颜色,做完之后,可以在饼状图,折线图等图表上实现相同的效果:Highcharts自带的例子中如column-basic.htm中,相同属性的柱子只有1种默认的颜色可以设置,在遇到要求同一个柱子使用不同色彩的时候,higchartsdemoexample中没有给出解决办法:

?

如果我们要实现:



?

这种效果,就需要对数据结构做个特殊处理.

首先了解一下highcharts接收的json数据格式:

charts\[\d+\]\.name,

charts\[\d+\]\.data\[\d+\]



?

Charts是一个list类型的结构,data是一个数组,数组中的对象可以是map,也可以是int 或者string类型的,它表示了Y轴对应的一些参数属性。Chartscategories表示图表中的x轴的对应的名称;在java中构造出这个数据结构后,生成json数据发给highcharts就可以在页面上生成图表了。

?

前端页面的代码如下:

function gethighcharts(obj){

?????????????????? var chart;

?????????????????? var options = {

? ????????????????????????????????????????? ??chart: {

?????????????????????????????????????????????? ? renderTo: 'containerdata',

?????????????????????????????????????????????? ? defaultSeriesType: 'column',

?????????????????????????????????????????????? ? marginRight: 100,

?????????????????????????????????????????????? ? marginBottom: 25

?????????????????????????????????????????????? },

?????????????????????????????????????????????? title: {

??????????????????????????????????????????????????????? text: '各科成绩得分比较',

??????????????????????????????????????????????????????? x: -20 //center

?????????????????????????????????????????????? },

?????????????????????????????????????????????? subtitle: {

??????????????????????????????????????????????????????? text: '',

??????????????????????????????????????????????????????? x: -20

?????????????????????????????????????????????? },

?????????????????????????????????????????????? xAxis: {

??????????????????????????????????????????????????????? categories: []

?????????????????????????????????????????????? },

?????????????????????????????????????????????? yAxis: {

??????????????????????????????????????????????????????? minorTickInterval: 'auto',

??????????????????????????????????????????????????????? title: {

???????????????????????????????????????????????????????????????? text: '分数'

??????????????????????????????????????????????????????? },

??????????????????????????????????????????????????????? plotLines: [{

???????????????????????????????????????????????????????????????? value: 0,

???????????????????????????????????????????????????????????????? width: 1,

???????????????????????????????????????????????????????????????? color: '#808080'

??????????????????????????????????????????????????????? }]

?????????????????????????????????????????????? },

?????????????????????????????????????????????? tooltip: {

??????????????????????????????????????????????????????? formatter: function() {

???????????????????????????????????? ??????????????? return '<b>'+this.series.name +'</b><br/>'+

?????????????????????????????????????????????????????????????????????????? this.x +': '+ this.y ;

??????????????????????????????????????????????????????? }

?????????????????????????????????????????????? },

?????????????????????????????????????????????? legend: {

??????????????????????????????????????????????????????? layout: 'vertical',

??????????????????????????????????????????????????????? align: 'right',

??????????????????????????????????????????????????????? verticalAlign: 'top',

??????????????????????????????????????????????????????? x: -10,

??????????????????????????????????????????????????????? y: 100,

??????????????????????????????????????????????????????? borderWidth: 0

?????????????????????????????????????????????? },

?????????????????????????????????????????????? series: []

??????????????????????????? };

?

同时在页面需要引入对应的js库文件:?????????????????????????????????????????????????????????????????????

<script type="text/javascript" src="js/highcharts/highcharts.js"></script>

<script type="text/javascript" src="js/highcharts/exporting.js"></script>

通过测试时发现,在chartsdata结构中,给每个map再加入一个color属性就可以使得每个柱状图有不同的颜色,对应的json数据的格式改为如下就可以:



?

???? 对于每个柱状图的颜色可以预先在一个java对象中定义好,然后每次循环赋值给柱子就行了,比如我在程序中预先定义好了9种颜色,每次生成data数据时候就循环插入color的值就可以了

String[] colors = {"#4572A7", "#AA4643", "#89A54E", "#80699B", "#3D96AE", "#DB843D", "#92A8CD", "#A47D7C", "#B5CA92"};

?

?

2.???????? 改造Highcharts的图表的下载功能:

?

???? 在Highcharts中使用自带的下载功能的时候,它会在下载弹出框中显示来自于export.higcharts.com字样,在图表的右下角也会有显示HightChart.com的超链接字样,在我们****的项目中,很明显需要将这两处地方进行替换,将这两个地址转换为我们自己的域名地址。

???? 于是我们进行尝试,在该插件的JS库文件exporting.js文件中将相关字样转为我们自己的域名,在其第8行的位置,我们将导出功能的英文提示改换为了汉字提示,然后在第10行将highcharts的域名换为了我们自己的域名:如:



?


?????? 但是经过这样一改之后,运行程序后,下载功能完全失效,不能再用了。经过仔细分析,发现http://export.highcharts.com/这个地址不仅仅是一个简单的域名表示,而且它是一段PHP的超链接的URI地址(类似于java中的servlet地址),它的作用是将highcharts图表所用的参数传递给这个URI地址,由该URI来生成指定格式的图片,然后以IO流的形式返回给用户下载该图片,用googllehighcharts的论坛上查找源代码,发现了其处理的步骤,于是参照了之前网上牛人的程序用javaservlet仿写一个对应的处理程序,因为要完全以参数来生成图片,所有用到了很多的开源的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包,都是该包的一些依赖包。那有了这些jar包后,我们就可以开发自己的servlet用来生成higcharts的图表了,代码如下:

?

package cn.tools;

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.image.JPEGTranscoder;

import org.apache.batik.transcoder.image.PNGTranscoder;

import org.apache.fop.svg.PDFTranscoder;

public class HeighChartsExportUtil?? extends HttpServlet{

?

??? /**

???????? ?* highchartsexport功能用到的Java辅助类

???????? ?* 20100617@wyq

???????? ?*/

???????? private static final long serialVersionUID = 2144151124530961067L;

???????? public HeighChartsExportUtil() {

????? super();

?? }?????

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

????? doPost(request,response);

?? }????

??

?? protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{

????? request.setCharacterEncoding("utf-8");//注意编码

????? String type = request.getParameter("type");

????? String svg = request.getParameter("svg");

????? response.setCharacterEncoding("utf-8");

????? ServletOutputStream out = response.getOutputStream();

????? 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 = new PDFTranscoder();

????? } else if (type.equals("image/svg+xml")) {

???????? ext = "svg";??

????? }

??????? response.addHeader("Content-Disposition", "attachment; 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();??

?? }

}

????? 详细代码可以参考cn.tools. HeighChartsExportUtil该类,说明一点,其中用到了request.setCharacterEncoding("utf-8");这句代码,如果去掉该句代码,那么在生成的图表图片中如果有汉字的话,就会成为乱码,所以一定要加这句,之前用highcharts自带的URI的时候,我们图标图片中的汉字乱码没法解决,现在通过该servlet就可以解决了。然后在web.xml配置文件中加入该servlet的映射:

?

<!--highcharts SVG 图像导出辅助类-->

?????? <servlet>

????????????? <servlet-name>HighChartsServlet</servlet-name>

???????????????????? <servlet-class>cn.tools.HeighChartsExportUtil</servlet-class>

????????????? <load-on-startup>10</load-on-startup>

????????????? </servlet>

????????????? <servlet-mapping>

???????????????????? <servlet-name>HighChartsServlet</servlet-name>

????????????? <url-pattern>/getHighchartServlet</url-pattern>

?????? </servlet-mapping>

<!--highcharts SVG 图像导出辅助类-->

?

?????? 然后现在在exporting.js中放心的将http://export.highcharts.com/改为我们自己的地址了,我这里改为了http://localhost:8080/SchoolManageSystem/getHighchartServlet这个地址:然后就可以在图表中显示我们自己的地址了,如下图所示:



?

通过这个例子发现:在开发工作中,很小的一个地方的变动,或者页面上一个很细微效果的改变,都需要我们在后台做出很多的准备工作才能实现的,或许这就是我们开发工作的特点吧,后台做的再多,给别人留下印象的,也就是前台页面上的那一瞥而已。


?

?

?

1 楼 heppytt 2012-01-11  
如何加入后台数据呢~~!!
2 楼 ssy341 2012-02-29  
是不是pdf的功能不行呢?
3 楼 ssy341 2012-02-29  
加了转码 但是打印出来的图片还是有乱码 怎么解决呢?
4 楼 LaxLee 2012-04-12  
大喊学习了  加个标记,慢慢学习