d3学习之(Data Visualization with d3.js Cookbook )二(第一章)

开始D3.js

       本章我们将要学习:

        1.如何搭建一个简单的d3开发环境。

        2.搭建一个NPM-based开发环境。

        3.理解d3风格的javascript语言。

       

       ok!在此之前,我们先聊聊什么是D3,D3是Data-Driven Document的缩写,从字面上理解就是数据驱动文本。在维基百科中d3是这样定义的:D3.js is a JavaScript library for manipulating documents based on data. D3 helps you bring data to life using HTML, SVG and CSS. D3’s emphasis on web standards gives you the full capabilities of modern browsers without tying yourself to a proprietary framework, combining powerful visualization components and a data-driven approach to DOM manipulation.大概意思就是:d3.js是用来操作基于数据文件的Javascript库,d3帮你使用HTMl,SVG和CSS将数据引入生活,D3所强调的web标准给你不搭售自己的专有框架,结合功能强大的可视化组件和数据驱动的方法来DOM操作的现代浏览器的全部功能

        D3的作者是Mike Bostock(http://bost.ocks.org/mike/)他的个人博客上也有很多他用d3做的数据可视化的例子。想知道D3的构造和原理可以去他的博客或者D3的官网查看,本书将重点讲解如何使用d3。

        首先,在某些方面d3可能让你有些迷惑,如果你写过javascript的话,通过这本书中 基础的和进阶的实例会让你了解熟悉d3,一旦你完全理解了d3会大大提高你开发数据可视化项目的效率。


      1.如何搭建一个简单的d3开发环境。

       想要开始d3可视化,最首要的当然是搭建一个开发环境,由于是基于javascript的前台语言,d3的环境可以说非常简单,几分钟就可以搞定。

       首先,确保你有一个文本编辑器,Editplus之类的。然后我们去d3 的官网下载d3最新的(http://d3js.org/)


       就是这个d3.v3.zip下载解压之后有3个文件d3.v3.js,d3.v3.min.js, 还有一个license文件,开发中建议使用d3.v3.js,便于debug,一旦我们下载了这些文件,接下来使用他们就很简单了,和其他javascript库一样我们要使用他们只有先引入他们就可以了。

可以引入官网的链接

<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>

也可以引入本地的js文件

<script src="d3.v3/d3.v3.js" charset="utf-8"></script>
           接下来准备你自己喜欢的文本编辑器还有浏览器,就可以开始你的d3编程了。

小提示:

         d3库是一个非常自给自足的库,除了浏览器提供的支持外他不依赖任何其他的js库文件,事实上他甚至可以用在非浏览器环境,比如node.js(这个以后的章节会讲到) ,如果你的浏览器环境是IE9,建议去下载兼容库Aight(https://github.com/shawnbot/aight)

         不要忘了这个charset="utf-8"因为d3库使用的是utf-8编码。d3是完全开源的。

      

         本书中的案例都可以在(https://github.com/NickQiZhu/d3-cookbook)这个网上面找到。


          2.搭建一个NPM-based开发环境。

          当你在设计开发一个复杂的数据可视化项目的时候,可能会用到很多的javascript库,这时我们之前介绍的简单的开发环境可能变得不灵活不明智。在这一部分我将介绍一个升级版的开发环境NPM(Node Packaged Modules)Nodejs的包管理系统,nodejs自身提供了基本的模块,NPM上有很多的库或者框架,这些库和框架可以帮助你完成复杂的应用开发。如果你很急切的想学习d3的相关应用可以跳过这部分继续看下面的,当你 接触到复杂的应用的时候再来看这部分的内容。

          在开始之前请确定你正确的安装了NPM,NPM是Node.js的一部分,你可以下载node.js从(http://nodejs.org/download/)这个地址,选择和你系统匹配的node.js,一旦安装了node.js你就可以在你的系统上使用npm指令。(这个安装可以去网上查看相关教程,如果你是windows系统,cmd进入node.js的目录输入npm -v 如果出现版本,我是安装的最新的node-v0.10.24-x86.msi,出现版本是1.3.21。说明npm安装成功。

          当NPM安装好后,就可以自动的添加js库了,首先在你的工程文件下新建一个package.json的文件写入以下内容 :     { 

                "name": "d3-project-template", 

                "version":  "0.1.0", 

                "description":  "Ready to go d3 data visualization project temple",

                "keywords":["data visualization","d3"],

                "homepage": "<project home page>",

                "author": {"name":"your name","url":"your url"},

                "repository":{"type":"git","url":"source repo url"},

                "dependencies":{"d3":"3.x"},

                "devDependencies": {"uglify-js": "2.x" }

              }

         提示:有关npm package.json的详细描述可以查看(https://npmjs.org/doc/json.html)。

        建好该文件后,只要运行>npm install

        如何工作的:package.json中大部分的内容只是描述和信息,比如姓名,描述,主页,作者还有库信息,姓名和版本部分将被用到,当你决定将你的库发布到npm系统中的时候。在这里面我们最需要关心的是最后两项dependencies,devDependencies,dependencies就是依赖的意思,是你的项目依赖的js库,这里是在npm中的d3库,版本3.x表示该项目适用以3开头的所有版本,npm将会取得以3开头的最新版本。

        提示:虽然d3是完全自给自足的库,但是并不代表他不能和其他js库一起使用,通常和其他一起库使用可以使编程更轻松,比如使用jquery.js,zepto.js,Underscore.js还有Backstone.js等。

        devDependencies表示的是开发所依赖的库,意思就是只是用在你开发的时候,而在项目运行的时候并不需要这个库。

        执行npm install命令后npm会自动的从网上下载package.json中定义的库并在你的工程文件下自动创建node_modules文件夹,你要引入库就可以在你的html文件中这样引入了。

<script src="node_modules/ d3/ d3.js" charset="utf-8"></script>

       使用NPM来引入库是一个简单高效的方式,不需要你手动的去下载各种库文件,并且不断的去保持更新。如果只是几个库可能用人工和用NPM方式看不出什么区别,但是如果是很大的工程,需要几十个库甚至上百个库的时候,这个时候NPM的优势就不用说了。

         

       虽然在前面的部分我们已经说到,只需要一个浏览器就可以运行你的D3程序了但是这种方式是有局限性的,当你需要使用本地数据的时候这种方式是行不通的,所以你需要在你的电脑上安装一个服务器环境,我相信你有很多种方式可以安装一个本地服务器,网上也有很多教程,这里就不再重复了。如果你前面装了nodejs,也可以直接去下载nodejs的服务器。

 

         

 3.理解d3风格的javascript语言。

        d3设计和搭建是使用的方法(函数)风格的javascript语句,这可能会让那些熟悉了面向对象或者面向过程的风格的javascript语句的人感觉有点陌生甚至是本质的不同。这里我们将讲解最基本的概念关于d3基于方法风格的编程语句。在未来你也将有能力写出d3风格的程序。

         打开你的编辑器,输入下面的代码。

        

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">

    <title>Functional Javascript</title>
    <link rel="stylesheet" type="text/css" href="https://github.com/NickQiZhu/d3-cookbook/blob/master/css/styles.css"/>
    <script type="text/javascript" src="http://d3js.org/d3.v3.min.js">"></script>
</head>

<body>

<script type="text/javascript">
    function SimpleWidget(spec) {
        var instance = {}; // <-- A

        var headline, description; // <-- B

        instance.render = function () {
            var div = d3.select('body').append("div");

            div.append("h3").text(headline); // <-- C

            div.attr("class", "box")
               .attr("style", "color:" + spec.color) // <-- D
               .append("p")
                   .text(description); // <-- E

            return instance; // <-- F
        };

        instance.headline = function (h) {
            if (!arguments.length) return headline; // <-- G
            headline = h;
            return instance; // <-- H
        };

        instance.description = function (d) {
            if (!arguments.length) return description;
            description = d;
            return instance;
        };

        return instance; // <-- I
    }

    var widget = SimpleWidget({color: "#6495ed"})
            .headline("Simple Widget")
            .description("This is a simple widget demonstrating functional javascript.");
    widget.render();
</script>

</body>
</html> 

      打开浏览器运行该代码你会看到

                                     d3学习之(Data Visualization with d3.js Cookbook )二(第一章)_第1张图片



        尽管这个界面很简单,相信会点html和css的人就可以轻松的写出这个一个界面,但是使用如此风格我相信还是有很多人有疑问的,这种风格就是d3所特有的编程风格,基于方法(函数)的编程风格。我们称它为d3风格,下面我们来详细的分析这个实例,不光让你明白d3的语法,甚至可以让你通过这种风格来编写自己的库。因为d3这种基于方法的风格具有很好的灵活性和可重用性。

        方法即对象

        方法(函数)在javascript中就是对象,和其他对象一样方法就是一个拥有方法名和参数的对象,方法和其他对象唯一不同的就是方法可以被执行,并且可以增加补充,并且可以将两个隐藏的属性连续到一起,那么d3究竟是如何定义使用方法的呢?

         

      var instance = {}; // <-- A

        var headline, description; // <-- B

        instance.render = function () {
            var div = d3.select('body').append("div");

            div.append("h3").text(headline); // <-- C

          在上面几行代码中我们可以看到A,B,C处标注的,instance,headline,description都是方法(函数)对象SimpleWidget的内部私有变量,instance变量被定义为一个对象,紧接着通过render(d3的一个方法以后会讲到)它被增加了一个方法。因为方法对象本身为对象,可以也可以成为某个对象的一部分,而其他的变量比如int,arrays等将被作为方法的传递参数。方法SimpleWidget执行完后返回一个对象instance在标注I处。
          本例中变量的作用范围是如何定义的,在javascript中,变量的作用范围是这样的,javascript有一个变量的规则,如果一个函数中用到的一个变量,首先会在这个函数内部查找这个变量,如果找不到就到这个函数的父对象中去查找这个变量,依次类推,直到找到全局变量,如果这个变量没有被定义过就会报错。这可能和java和c#语言有一定的区别,如果之前是学这种语言的人适应起来会花点时间。而且对于java和C#的开发人员来说有一点更让人困惑,这是因为在C系语言有块级作用域(block-level scope),当进入到一个块时,就像if语句,在这个块级作用域中会声明新的变量,这些变量不会影响到外部作用域。但是JavaScript却不是这样。比如下面这段代码:
        
  for( var i = 0; i < 10; i + +){
                     for( var i = 0; i < 2; i + +){ 
                           console.log(i);
                                                                }
                                                     }

       你可能会认为他会产生20个数字,但实际上在javascript中这是一个无限循环,这是因为在javascript中没有块级作用域这一说,JavaScript是函数级作用域(function-level scope)。这和C系语言是完全不同的。块,就像if语句,并不会创建一个新的作用域。只有函数才会创建新的作用域。所以这段代码中里面for循环的i和外面for循环的i在javascript中被认为是同一个变量。因此i在内部循环中被重置,永远也不可能到达外部循环的停止条件。
         
        通过方法风格创建的对象更具有灵活性和持久性。
       
       那么标注G处的语句
   if (!arguments.length) return headline; // <-- G

        是什么意思呢?arguments在本例中从未被定义过,其实他是一个javascript的变量,表示函数的传递参数,在本行代码的意思就是,如果存在参数那么就将该参数返回给headline,如果不存在参数就执行下面的语句,就是将headline赋值h,
         
var widget = SimpleWidget({color: "#6495ed"}) .headline("Simple Widget")
            在这两行中我们就看到了headline方法同时完成了获取和设置两个功能,他获取到括号中的Simple Wideget字符串,并设置headline的值返回给instance对象。

          方法(函数)链条

                       

           在本例中我们把一个对象需要的属性(参数)全部定义成了方法,这些方法可以直接获取和设置这些属性(参数),然后返回给对象。

var widget = SimpleWidget({color: "#6495ed"})
            .headline("Simple Widget")
            .description("This is a simple widget demonstrating functional javascript.");
    widget.render();

         最后这几行代码其实就是对对象的实现,设置颜色,headline,description,等属性最后通过render方法来实现,也许大家对render方法里面的内容还不是很清楚,这些将在后面的部分讲到,这里主要是理解这种风格,所有这些方法只需要在用一个“.”号就可以连接起来,如果我们需要其他颜色其他标题的简介框的,我们只需要用同样上面的方式,设置不同的值就可以完成,这就是方法(函数)风格的灵活性。

        最后推荐一些其他学习d3的网站。

        d3画廊https://github.com/mbostock/d3/wiki/Gallery

          https://github.com/mbostock/d3/wiki/Tutorials

          https://github.com/d3/d3-plugins

d3api

          https://github.com/mbostock/d3/wiki/API-Reference

       

         第一章的内容就到这里。



你可能感兴趣的:(d3学习之(Data Visualization with d3.js Cookbook )二(第一章))