highcharts插件使用總結和開發中遇到的問題及解決辦法

這裏使用的highchart是2014-01-09從官網下載的版本,版本號是3.0.8,html

當過了幾天後,發現版本號變成了3.0.9,不禁得的感嘆highchart的版本更新之快。java

在jsp中使用highchart的步驟:jquery

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

<! -- 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

開發過程遇到的問題:sql

1)  Js的引入順序錯了,致使highchart的圖表出不來,json

Highchart插件中用到了jquery,當時jquery-1.8.3.js引入順序放到了highchart插件js的下面,數組

致使當加載highchart插件用到的js時,找不到jquery的js,報出某個js的函數不合法瀏覽器

所以 jqueryjs要在引入highchartjs以前引入網絡

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

要顯示中文,這裏採用的方法是修改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="<%=basePath%>shop/newOrder/orderPre/orderSearch4HighCharts.do?viewType=1"
   }
      
    function showLineView(){
           window.document.location.href="<%=basePath%>shop/newOrder/orderPre/orderSearch4HighCharts.do?viewType=3"
   }
   </script>
   
   
</head>
    
<body>

<span onclick="showAreaView();" style="cursor: pointer">區域圖顯示</span>&nbsp;&nbsp;|&nbsp;&nbsp;
<span onclick="showLineView();" style="cursor: pointer">曲線圖顯示</span>&nbsp;&nbsp;|&nbsp;&nbsp;
<span  style="font-weight: 900;color: red;cursor: default">柱狀圖</span>
   <div id="container" style="min-width:90%;height:90%;"></div>
<input type="hidden" id="totalRecordLJ" value="${totalRecordLJ}"></input>
<input type="hidden" id="totalRecordHY" value="${totalRecordHY}"></input>
<input type="hidden" id="totalRecord" value="${totalRecord}"></input>
<input type="hidden" id="xAxisTime" value="${highChartXAxisInfo}"></input>
</body>
</html>
View Code

歡迎轉載,轉載務必請註明出處,謝謝。

相關文章
相關標籤/搜索