dygraphs的學習-----------------dygraphs插件(圖表插件)

 

關於dygraphs JavaScript Visualization Library的學習筆記

主要內容

1.    筆者留言

2.    什麼是dygraphs?

3.    Dygraphs原理的簡單說明

4.    Dygraphs的使用

5.    IE兼容性、常見問題和建議

6.    自己寫的一個例子mydemo(主要是爲了說明Options的使用)

筆者留言

如果讀者的英文很好,可以直接無視這個筆記的大部分內容(除了注意點,IE兼容性和常見問題和建議)。

這個筆記,只是描述怎麼使用dygraphs。對其底層的原理,由於個人技術水平有限,沒有做太多的敘述。

文中的加紅部分的內容都是注意點。

如果發現文中有什麼地方有誤,請及時提出(回覆)。

本文原創,轉載請註明URL。

       感想:

1.  開源的框架,源碼可以適當地修改,以符合我們的需求。

2.  多看看JS基礎知識

3.  多用度娘,Google。要注意分辨,多問人

4.  多做筆記

一、什麼是dygraphs?

Dygraphs是一個開源的JS庫;用於生成可與用戶交互的、可縮放的時間圖表。主要用於顯示密集的數據集合,用戶能夠很好的瀏覽和查看數據。

下面是相關的URL:

dygraphs JavaScript charting library
Copyright (c) 2006-, Dan Vanderkam.(感謝這個人)
Documentation(使用指南,demo位置等等): http://dygraphs.com/
Support: http://groups.google.com/group/dygraphs-users
Source(源碼發佈狀態): http://github.com/danvk/dygraphs
Issues: http://code.google.com/p/dygraphs/
源文件下載地址:https://github.com/danvk/dygraphs/downloads/

兩種格式:對應不同的操作系統

Zip    (window xp)

tar.gz    (linux )

我用的是window xp ,下了zip的

注意點:dygraph-combined.js This is not the file you're looking for. Please use http://dygraphs.com/dygraph-combined.js instead   <1KB

下載的zip中的dygraph-combined.js文件相當於是空的,要用下載這個地址的JS替換:

http://dygraphs.com/dygraph-combined.js

另下載的文件是js壓縮格式的 (compressed)

二、Dygraphs原理的簡單說明

JavaScript and the HTML canvas tag:  js + <canvas>實現(在一個畫布上畫東東)

1.利用JS動態生成一個<canvas>添加到JS動態生成的DIV元素標籤(graphDiv包含了解12的所有內容)中,然後在<canvas></canvas>顯示數據(圖表);

<canvas></canvas>會用DIV包含加入graphDiv

2.       利用JS動態生成一個多個DIV元素標籤,分別包含X,Y軸,圖表標題的內容。加到第1步中DIV元素(graphDiv)中;

3.         在html, jsp等頁面中準備一個DIV元素標籤,來包含graphDiv。

當然還有其他的一些事件處理機制等等。

Ctrl + F   graphDiv   可以在dygraph-combined.js找到相應的代碼

三、Dygraphs的使用

3.1、學習的兩種方式

進入dygraphs的首頁:http://dygraphs.com/

1.       可以把首頁的內容全部看完(在首頁的左邊的導航

2.直接看例子(在首頁的左邊的導航

 

3.2、第一個例子

結果圖:

圖1

可以在首頁的圖表中操作:在圖表中:

雙擊:還原;

按住左鍵,拖動選擇的圖表內容會放大;

在圖表上移動,高亮點 並 右上角會顯示相應時間點的數據。

在html,jsp 頁面中導入dygraph-combined.js和實例化一個Dygraph對象。

HTML

----------------------------------------------------------------------------------------------------------------

<html>
<head>
<script type="text/javascript"   src="dygraph-combined.js"></script><!—用這一個jsOK,封裝了這個框架所有基本的JS,不包括後面的excanvas.js  interaction.js-->
</head>
<body>
<div id="graphdiv2" style="width:500px; height:300px;"></div>
<script type="text/javascript">
  g2 = new Dygraph(
document.getElementById("graphdiv2"),//圖表顯示的位置
"temperatures.csv", // 數據的所在位置
    {}          // options 可選配置參數
  );
</script>
</body>
</html>

---------------------------------------------------------------------------------------------------

321代碼說明

這是一個最簡單,最基本的例子。這裏主要講Dygraph對象的實例化:

構造函數有三個參數:

第一參數:圖表要顯示的位置(好像都是DIV元素)

第二參數:要顯示的數據

第三參數:可選配置參數

這裏最需要說明的是第二和第三個參數。

3.2.1.1第二參數:要顯示的數據

數據有5種表現形式:

3.2.1.1.1 CSV data

CSV data又有三種表現形式:本質一樣

(1) csv文件:這個有專門的軟件可以生成,沒有用過,不過我無意發現SQL Server數據庫查詢的結果可以保存成CSV文件。也可以直接TXT保存成CSV文件(應該可以,格式OK就行)。

(2)  TXT文件 記事本文件(這個很容易得到,從數據庫中讀到數據,再用IO流寫到TXT)

(3)字符串

共同點:內容都必須符合一定的CSV格式

每條數據只佔一行,第一行一般是用來確定每一列的含義,每行中每個數據值用逗號分隔,如下:

Date,High,Low

20070101,62,39

20070102,62,44

20070103,62,42

20070104,57,45

從上面的數據可以看出:

第一列表示時間,第二列和第三列分別是High,Low在相應時間的數值

在圖表顯示如上圖1所示。如果沒有第一行(Date,High,Low),就要用可選參數labels來指定每列數據的含義。如:

new Dygraph(el,

                  "2009/07/12,100,200\n" +

                  "2009/07/19,150,201\n",

                  { labels: [ "Date", "Series1", "Series2" ] });

而"Date", "Series1", "Series2"分別對應圖表的X軸,Y1軸,Y2軸。(Y軸數據一般是number,其他沒有什麼要求)。

而X軸一般用來表示時間。它有兩種類型:

(1)日期格式字符串,支持以下幾種:

l  2009-07-12

l  2009/07/12

l  2009/07/12 12

l  2009/07/12 12:34

l  2009/07/12 12:34:56

上面的數據格式字符串,會被自動解析成相應的時間

(2)數值格式(number)則是一個長整型(long),單位爲ms 。不能直接解析成一個時間對象,要作相應的配置。如:

   new Dygraph(el,

                  "Date,Series1,Series2\n" +

                  "1247382000,100,200\n" +

                  "1247986800,150,201\n",

                  {//long型轉換成Date

                    xValueFormatter: Dygraph.dateString_,

                    xValueParser: function(x) { return 1000*parseInt(x); },

                    xTicker: Dygraph.dateTicker

                  });

3.2.1.1.2  URL

 通過一個URL訪問遠程的數據。

3.2.1.1.3  array (native format)  

一個js中的Array對象;如:

[

        [ new Date("2009/07/12"), 100, 200 ],

        [ new Date("2009/07/19"), 150, 220 ]

      ]

這種數據格式,可以看到沒有指定(如:“Date,High,Low”)每列的含義。所以Array數據格式需要可選參數labels來指定每列的含義。例如:

new Dygraph(document.getElementById("graphdiv2"),

                  [

                    [1,10,100],

                         [2,20,80],

                    [3,50,60],

                    [4,70,80]

                 ],

                  {

                    labels: [ "x", "A", "B" ]

                  });

3.2.1.1.4   function

Functions can return strings, arrays, data tables, URLs, or any other data type.

一個函數:返回字符串,Array對象,DataTable ,URL 和其他符合CSV 數據格式的數據類型。

3.2.1.1.5  DataTable

Google Visualization Library DataTable object: 谷歌可視化庫的數據表對象

3.2.1.2第三個參數:可選配置參數

第三個參數:框架中已經有相應的默認值,不過一般爲了達到自己的需求,都會配置一些參數。由於參數太多,這裏不做翻譯了。用的時候,可以結合相應的例子和Options reference來學習。文章最後是我寫的一個例子Mydemo(裏面對我用到的可選配置參數的作了一些註釋)。

3.3、Dygraph常用方法

g: 表示Dygraph對象實例

1.   g.updateOptions({可選配置參數}) 

生成g對象後,用來更新可選配置參數,來改變圖表的某些狀態。下面是幾個函數,幫助理解:

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

/**

 * 右擊,縮小圖表

 *

 */

function zoomGraph() {

  var minDate = g.xAxisRange()[0]*(1.0000001); //x軸的最大和最小值(顯示出來的部分):long

  var maxDate = g.xAxisRange()[1]*(0.9999999);

    g.updateOptions({    //更新可選配置參數

      dateWindow: [minDate, maxDate]

    });

  }

  /**

   * 鼠標的滾輪的縮小圖表

   *

   */

function zoomOutGraph() {

  var minDate = g.xAxisRange()[0]*(0.9999999);

  var maxDate = g.xAxisRange()[1]*(1.0000001);

    g.updateOptions({

      dateWindow: [minDate, maxDate]

    }); 

  }

/**

 * 鼠標的滾輪的放大圖表

 */

function zoomInGraph() {

  var minDate = g.xAxisRange()[0]*(1.0000001);

  var maxDate = g.xAxisRange()[1]*(0.9999999);

 // var minValue = g.yAxisRange()[0]*(1.01);//y軸的最大和最小值(顯示部分的)

  //var maxValue = g.yAxisRange()[1]*(1.01);

    g.updateOptions({

      dateWindow: [minDate, maxDate]

     // valueRange: [minValue, maxValue]

    })

  }

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

2.       g.setSelection(row)

定位圖表上的一點:參數row:將要選擇點的數據在CSV文件(如果第一行是:Date,series1,series2,則不包括這一行)的第幾行,從0開始。

(也就是圖表數據中第幾行(最小行爲0))

如下所示:

Date,High,Low     (labels)

20070101,62,39     (row=0)

20070102,62,44     (row=1)

20070103,62,42     (row=2)

20070104,57,45   (row=3)

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

/**

 *:通過地圖定位圖表上的一點

 * @param time

 * @param row

 */

function update(time,row){

         var minDate = dygraphTime-300000;// x軸是long類型,這裏保持該點的左右各5分鐘

         var maxDate = dygraphTime+300000;// 這個就是X軸的時間的long類型

         g.updateOptions( {

                    dateWindow: [minDate, maxDate]// 這裏只能用鍵值對,不用函數。

          });

         var annotations = []; //清除所有點的註釋

         g.setAnnotations(annotations);

         g.setSelection(row);

}      

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

四、IE的兼容性、常見問題和建議

對於IE兼容性問題:

最簡單的辦法:把http://dygraphs.com/tests/ 中隨便一個例子的<body>前面的內容複製就行。

一般要加:

<!DOCTYPE html> <!—IE本身不支持HTML5<canvas>;  這個是爲了在IE9中用微軟自己實現的canvas  -->

<html>

  <head>

    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9"> <!—兼容IE6-IE8 -->

    <!--[if IE]><script src="path/to/excanvas.js"></script><![endif]-->   <!--微軟自己實現的canvas -->

  </head>

注意點:即使加了上面的內容;IE8可能會不支持HTML5<canvas>。(原因: <!DOCTYPE html>會破壞excanvas)

 

3.       在實例Dygraph對象的第三個參數(options)中

最後一個 name : value不要加” , ”。因爲IE不支持,會報錯(其他瀏覽器OK)。

如:

new Dygraph(el, data, {
  rollPeriod: 5,
  showRoller: true, // 最後一個配置,不要加逗號
})

4.       如果圖表不顯示,可以查看JS錯誤控制檯,dygraph本身封裝了日誌記錄功能:如error warning等

5.       CSV文件必須是可讀的,否則XMLHttpRequest會取不到CSV文件。

6.       CSV文件內容的格式正確。當用到errorBars時的CSV內容格式要注意。

7.       不要把要顯示圖表的DIV放到一個<center>標籤中,也不用CSS的樣式:text-align:center來使圖表居中。而是要用<table align=”center”><table>居中。

8.        dateWindow屬性是一個Array對象,它的元素是long類型的,單位是ms

dateWindow不要直接使用符合Date對象的字符串或Date對象賦值,要做相應的處理得到日期的ms值:Date.pase(string str)可以搞定)如:

g1 = new Dygraph(

             document.getElementById("div_g1"),

             data, {

               dateWindow: [ Date.parse("2009/09/29 12:00:00"),

                             Date.parse("2009/10/10 12:00:00") ],

               labels: [ 'Date', 'Y1', 'Y2' ]

             }

           );

五、Mydemo

使用:把下面的代碼複製到一個HTML頁面中,然後放到下載的ZIP解壓後的danvk-dygraphs-681a215\tests文件夾,就可以使用了。

這個例子的特點是:

1.  交互:與百度地圖的操作相似

2.  在上面移動實時顯示數據註釋

測試:在IE firefox中測試OK

 

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

<!DOCTYPE html>

<html>

  <head>

    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9">

    <title>mydemo</title>

    <!--[if IE]>

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

    <![endif]-->

    <!--

    For production (minified) code, use:壓縮格式的dygraphsJS

    <script type="text/javascript" src="dygraph-combined.js"></script>

    -->

 

    <script type="text/javascript" src="../dygraph-dev.js"></script><!--要注意加載JS的順序,excanvas.js要在dygraph-dev.js的前面-->

       <script type="text/javascript" src="interaction.js"></script> <!--用戶與圖表交互方式:如放大,縮小圖表的方式-->

  </head>

  <body>

    <h2>mydemo</h2>

   <div id="my_chart"   style="height:400px; border:1px solid black;"></div>

 

 <script type="text/javascript">

 

/**

 * 判斷系列名是series1還是series2,用不同的單位

 * @param name

 * @returns {String}

 */

function checkSerialName(name)

  {

     if(name=='series2')

     {

            return ' R/M';

     }

     else

     {

            return ' km/h';

     }

  }

     var data = [];//這裏定義了一個Array對象,這裏只顯示3個數據

        data.push([1351571661000,0.0,678

                  ]);

       data.push([1351571672500,3.8,697

                  ]);

       data.push([1351571722500,31.0,1224

                  ]);

var g = new Dygraph(

                    document.getElementById("my_chart"),//圖表顯示位置

                 data,   //'dygraphs/dygraphs.txt',

                  {

                      rollPeriod: 5,//放大的倍數,不知道放大什麼,線看起來更圓滑

                      showRoller: true,//顯示原點旁邊的小文本框:rollPeriod的值//legend:'always',//總是顯示右上角的數據

                      title:'title',//標題

                         titleHeight:50,//標題高度

                         avoidMinZero: true,//y軸的最小值不爲0,相當於y=0那條線上升了。

                   axisLabelWidth:100,//X Y軸的標題的寬度

                width : 1500,//圖表的寬度

               height: 350,//圖表的寬度和高度

                         xValueFormatter: Dygraph.dateString_,//x軸的long類型數據進行格式化成日期

                        xValueParser: function(x) { return parseInt(x); },

                          xTicker: Dygraph.dateTicker,

                        axisTickSize: 10,//與時間軸的時間高度有關//pixelsPerLabel:50,//指定每個x y軸的label的顯示大小              

                          axisLabelColor:'green',//座標軸的刻度值顏色

                   highlightCircleSize: 6,//高亮點顯示的大小

                   axisLineWidth:1,//太小會看不到Y軸,默認爲0.3,以爲沒有畫出來

                   labels: [ 'Date', 'series1','series2'],//這裏確定每列數據的含義

                         'series1': {//用兩個y軸,這裏是指定用哪一個y

                                          axis: {}

                                 },

                          axes: {

                                                  y: {

                                               valueRange: [500, 2600]//Y軸的值範圍

                                                 },

                                          y2: {

                                             //set axis-related properties here 設置與Y1軸上每段值的相應的值(labelsKMB

                                             axisLabelFormatter: function(y2){//Y軸的刻度取整

                                             return y2.toFixed(0);},

                                             valueRange: [0, 100],

                                                       labelsKMB: true  //設置與Y1軸上每段值的相應的值(labelsKMB

                                         },

                                              x: {       //顯示時分秒,不用也行,如果顯示MS,有個demo中,有d.getMilliSeconds();

                                              axisLabelFormatter: function(d, gran) {

                                                return Dygraph.zeropad(d.getHours()) + ":"

                                                    + Dygraph.zeropad(d.getMinutes()) + ":"

                                                    + Dygraph.zeropad(d.getSeconds());

                                             }

                                     }

                                 },

                                 ylabel: 'series2',//y1軸的標題

                              y2label: 'series1', //y2軸的標題 //rightGap:0,//這裏把y軸的名稱,頂沒了。

                              yLabelWidth:30,        //Y軸標題的寬度,可以作用所有Y                           

                              yAxisLabelWidth: 60,  //這個是Y軸刻度的寬度。

                      interactionModel : {  //用戶與圖表的交互方式,第一個例子中的方式是默認方式,

                                   //而現在配置這種是跟百度地圖等的操作方式相似的。

                                    'mousedown' : downV3,  //注意這些事件的大小寫都不能寫錯。格式:'事件名稱':事件發生時調用的函數

                                    'mousemove' : moveV3,  //這些函數在interaction.js

                                    'mouseup' : upV3,

                                    'click' : clickV3,

                                    'mousewheel' : scrollV3,  //IE

                                    'DOMMouseScroll' : scrollV3,//這個是FireFox的鼠標滑輪事件名稱,上面的是IE,兩個都要

                                    'dblclick' : dblClickV3

                             },

                           highlightCallback: function(e, x, pts, row){          //除了高亮回調,

                              //還有drawCallback clickCallback dblclickCallback用到時,可以去看

                              //,形式是一樣的

                                      addAnnotations(e, x, pts, row);//加註釋

                               selectMapPoint(pts[0]);//聚焦地圖的相應點

                           }

                                          }//end of dygraphs options

                          );//end of dygraphs

                         

 

 

/**

 * 爲圖表中的線添加註釋

 * @param e 鼠標移動事件

 * @param x 高亮點對應的x的值(這個不確定)

 * @param pts 高亮的點,有幾條線,就有幾個點

 * @param row 該點數據在CSV文件(如果第一行是:Date,series1,series2,則不包括這一行)的第幾行,從0開始(也就是圖表數據中第幾行(最小行爲0))

 */

function addAnnotations(e, x, pts, row) {

          annotations = [];

           annotations.push( {

              series: 'series2',//在哪條線上加註釋

              x: x,

              width: 60,//註釋的寬

              height: 20,//註釋的高

              tickHeight: 5,//線與註釋之間的距離,大的話,可以看到他們之間有條線連接

              text:Math.round(pts[1].yval)+checkSerialName(pts[1].name),//相當於一個DIVtitle(源碼如此),鼠標在上,顯示這個

              shortText: Math.round(pts[1].yval)+checkSerialName(pts[1].name)//這個小文本直接顯示在註釋框內

 

               } );

           annotations.push( {

              series: 'series1',

              x: x,

              width: 60,

              height: 20,

              tickHeight: 5,//註釋框和線之前的線長

              text:Math.round(pts[0].yval)+checkSerialName(pts[0].name),//註釋的title

              shortText: Math.round(pts[0].yval)+checkSerialName(pts[0].name)

             

               } );

              g.setAnnotations(annotations); //設置註釋

}

 

                  

             

    </script>

</body>

</html>

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

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