dygraphs的学习-----------------dygraphs插件(图表插件)

时间:2023-02-03 20:35:29

 

关于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.       可以把首页的内容全部看完(在首页的左边的导航

dygraphs的学习-----------------dygraphs插件(图表插件)

2.直接看例子(在首页的左边的导航

 

dygraphs的学习-----------------dygraphs插件(图表插件)

3.2、第一个例子

结果图:

dygraphs的学习-----------------dygraphs插件(图表插件)

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

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