Highcharts進階應用

JQuery插件之-Highcharts在****項目中的應用-進階篇

WYQ

      本文檔主要講Highcharts的2個地方的改進之處,1是在柱狀圖中爲每個柱子設置不同的顏色,2是改造highchars自帶的圖表下載功能。

 

1.         在柱狀圖中給每塊柱子設置七彩斑斕的顏色,做完之後,可以在餅狀圖,折線圖等圖表上實現相同的效果:在Highcharts自帶的例子中如column-basic.htm中,相同屬性的柱子只有1種默認的顏色可以設置,在遇到要求同一個柱子使用不同色彩的時候,higcharts的demo和example中沒有給出解決辦法:

 

如果我們要實現:



 

這種效果,就需要對數據結構做個特殊處理.

首先了解一下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>

通過測試時發現,在charts的data結構中,給每個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流的形式返回給用戶下載該圖片,用googlle在highcharts的論壇上查找源代碼,發現了其處理的步驟,於是參照了之前網上牛人的程序用java的servlet仿寫一個對應的處理程序,因爲要完全以參數來生成圖片,所有用到了很多的開源的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{

 

    /**

          * highcharts的export功能用到的Java輔助類

          * 20100617@wyq

          */

         private static final long serialVersionUID = 2144151124530961067L;

         public HeighChartsExportUtil() {

      super();

   }     

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

      doPost(request,response);

   }    

  

   protected void doPost(HttpServletRequest request, HttpServletResponse response) throwsServletException, 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這個地址:然後就可以在圖表中顯示我們自己的地址了,如下圖所示:



 

通過這個例子發現:在開發工作中,很小的一個地方的變動,或者頁面上一個很細微效果的改變,都需要我們在後臺做出很多的準備工作才能實現的,或許這就是我們開發工作的特點吧,後臺做的再多,給別人留下印象的,也就是前臺頁面上的那一瞥而已。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章