从今天开始我将和大家一起学习D3.js(Data-Driven Documents),由于国内关于D3的学习资料少之又少,所以我觉得很有必要把自己学习过程记录下来,供同学们参考,如果文章有有哪些表达有错误的还希望同学们帮我指出来。当然了, 可以的话我希望大家都可以去看看英文资料(文章后面将列英文资源),毕竟那才是原汁原味的D3。 好了, 废话到此,下面我们开始我们的学习之旅吧!

什么是D3.js?

一句话:D3.js是一个操纵数据的javascript库!

从一个简单的例子开始

学习一个新的东西其实很简单,我们先来一个效果图,然后我们再一条条改它的语句,对比呈现的效果来学习这条属性的作用,好了,下面就是我们要做的:

看上去是不是挺复杂的呢?下面我们来看看他的源码到底是怎样的呢?

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Simple Graph</title>
    <style type = "text/css">
    body{ font: 12px Arial;}
    path{
        stroke: steelblue;
        stroke-width: 2;
        fill: none;
    }
    .axis path,
    .axis line{
        fill: none;
        stroke: grey;
        stroke-width: 1;
        shape-rendering: crispEdges;
    }
    </style>
    <script type="text/javascript" src="script/d3.v3.js"></script>
</head>
<body>

    <script type="text/javascript">
    var margin = {top:30, right:20, bottom: 30, left: 50};
    width = 600 - margin.left -margin.right;
    height = 270 - margin.top - margin.bottom;

    var parseDate = d3.time.format("%d-%b-%y").parse;

    var x = d3.time.scale().range([0, width]);
    var y = d3.scale.linear().range([height, 0]);

    var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(5);
    var yAxis = d3.svg.axis().scale(y).orient("left").ticks(5);

    //?
    var valueline = d3.svg.line()
        .x(function(d){return x(d.date);})
        .y(function(d){return y(d.close);});

    var svg = d3.select("body")
        .append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
        .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    //Get the data
    d3.tsv("data/data.tsv", function(error, data){
        data.forEach(function(d){
            d.date = parseDate(d.date);
            d.close = +d.close;
        });

        //Scale(规模) the range of the data
        x.domain(d3.extent(data, function(d){
            return d.date;
        }));
        y.domain([0, d3.max(data, function(d){
            return d.close;
        })]);

        //Add the valueline path
        svg.append("path")
            .attr("d", valueline(data));

        //Add the X Axis
        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);
        //Add the Y Axis
        svg.append("g")
            .attr("class", "y axis")
            .call(yAxis);
    });

    </script>
</body>
</html>

看上去是不是很复杂的样子,不要怕,下面我们对他进行一块一块的解剖

HTML

上面的代码包括样式和脚本两个部分,他的结构可以简化为:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
    The CSS 部分
</style>
<body>
<script type="text/javascript" src="d3/d3.v3.js"></script>
<script>
    The D3 JavaScript code is here
</script>
</body>

CSS

css部分主要是对元素设定样式,上面图表的CSS样式为

body{ font: 12px Arial;}
path{
    stroke: steelblue;
    stroke-width:;
    fill: none;
}
.axis path,
.axis line{
    fill: none;
    stroke: grey;
    stroke-width:;
    shape-rendering: crispEdges;
}

我们可以改变其中的样式来改变图表的显示效果,比方说设置path{ stroke: red ; …}则效果曲线将变成红色

同样的,如果我更改fill为red,我们将得到红色的填充

其中"shape-rendering”是形状渲染属性,他一共有四个属性,值为“crispEdges”表示该形状将平滑显示。跟多的属性请同学学习SVG教程

D3 JavaScript

  • 设置边距和图表大小。 我们设定画布的大小为:width:600,height:270,用一个margin对象来存储图表的边距信息,计算出图表的宽度和高度

    var margin = {top: 30, right: 20, bottom: 30, left: 50},
    width = 600 - margin.left - margin.right,
    height = 270 - margin.top - margin.bottom;
  • 下面我们先来看获取数据的方法
    //Get the data
        d3.tsv("data/data.tsv", function(error, data){
            data.forEach(function(d){
                d.date = parseDate(d.date);
                d.close = +d.close;
            });
 这里我们是从data.tsv这个文件中获取数据的,所谓tsv文件,简单来说就是用tab空格把数据分割开来的一种数据格式,比方说我们的data.tsv文件的部分数据就是这样的
date    close
1-May-12    58.13
30-Apr-12    53.98
27-Apr-12    67.00
当然了,D3允许导入的数据不仅仅只是这一种文件格式,他支持的数据格式可以为:

text: A plain old piece of text that has options to be encoded in a particular way

json: This is the afore mentioned JavaScript Object Notation.
xml: Extensible Markup Language is a language that is widely used for encoding documents in a human readable forrm.
html: HyperText Markup Language is the language used for displaying web pages.
csv: Comma Separated Values is a widely used format for storing data where plain text
information is separated by (wait for it) commas.
tsv: Tab Separated Values is a widely used format for storing data where plain text
information is separated by a tab-stop character.

data.forEach(function(d){

上面这一行代码可以看做把数据分成了一行一行的形式,其中,每一行当中都有一个date和close值,并对没一行数据执行下面的处理:

d.date = parseDate(d.date); --将d.date数据用前面定义的parseDate方法来格式化,将结果返回给d.date

d.close = +d.close; --将d.close转化为一个数字

var parseDate = d3.time.format("%d-%b-%y").parse;
format()的格式有很多,我们可以根据自己的需要来设定自己的个格式,当然这里的格式要与文档数据中的格式对应哦,不过现在我遇到的问题是,如何让时间显示为中文?如果有同学知道,请告诉我,我将非常感谢!
  • 设置横轴方向和纵轴方向的区域(Domains)和范围(Ranges)
var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
这段代码是为了让我们导入的数据与图表的大小相适应,range知道是图表范围的大小,他是一个尺寸大小。这段代码告诉D3我们要画些东西在x轴上,这些东西是时间/日期的一个实体。
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.close; })]);
而domain指的是数据的区域,extent返回的是最小的date到最大的date这样一个跨度,所以,最小的date就对应于上面range的最小值0,我们可以用一幅图来形象的表达:

 
  • 设置坐标轴
下面我们来分析这里几行代码:
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").ticks(5);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(5);
坐标轴axis初始化方法通过d3.svg.axis()来调用,然后调用.scale(x)用前面定义的x来给坐标轴设定刻度, .orient()设定刻度相对坐标轴的位置,.ticks()告诉D3在坐标轴上设定差不多几个刻度就够了,比方说你要D3给你的X轴设定大概10个刻度:var xAxis = d3.svg.axis().scale(x).orient(“bottom”).ticks(10),效果如下
  • 为line()画线函数添加数据
var valueline = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
关于Line函数的使用可以参照这里
  • 添加画布
var svg = d3.select("body")
.append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
.append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"
);
d3.select(“body”)选择body元素,然后在body里面增加一个子元素”svg”,给这个svg设定一些属性,再往“svg”中添加一个”g”元素并设定一些属性。
 
  • 开始画东西啦
svg.append("path") // Add the valueline path.
    .attr("d", valueline(data));
我们再刚才创建的svg中添加一个path路径,让后用前面的定义的 valueline来绘制一条路径。然后我们再来绘制x轴和y轴
svg.append("g") // Add the X Axis
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);
svg.append("g") // Add the Y Axis
    .attr("class", "y axis")
    .call(yAxis);
两个部分最后的.call()函数来定义前面的坐标轴初始化的方法来绘制坐标轴。

OK!,到目前为止我们的目标已经达到了,最开始要达到的效果我们已经实现,但是还有很多东西我们还没有学会,比方说坐标轴的标签? 好吧,下一节我们再来给坐标轴添加标签!

 

相关资料:

http://d3js.org/
http://bost.ocks.org/mike/
https://github.com/mbostock/d3/wiki
https://groups.google.com/forum/?fromgroups#!forum/d3-js
http://stackoverflow.com/questions/tagged/d3.js
https://github.com/mbostock/d3/wiki/Gallery

D3.js学习(一)的更多相关文章

  1. 数据可视化的优秀入门书籍有哪些,D3.js 学习资源汇总

    习·D3.js 学习资源汇总 除了D3.js自身以外,许多可视化工具包都是基于D3开发的,所以对D3的学习就显得很重要了,当然如果已经有了Javascript的经验,学起来也会不费力些. Github ...

  2. D3.js学习记录【转】【新】

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. D3.js学习(七)

    上一节中我们学会了如何旋转x轴标签以及自定义标签内容,在这一节中,我们将接触动画(transition) 首先,我们要在页面上添加一个按钮,当我们点击这个按钮时,调用我们的动画.所以,我们还需要在原来 ...

  4. D3.js学习记录

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. D3.js学习(六)

    上节我们学习了如何绘制多条曲线, 以及给不同的曲线指定不同的坐标系.在这节当中,我们会对坐标轴标签相关的处理进行学习.首先,我们来想一个问题, 如何我们的x轴上的各个标签的距离比较近,但是标签名又比较 ...

  6. D3.js学习(五)

    上一节我们已经学习了如何设置填充区域,其实理解了他的实现原理还是非常简单了.这一节中, 我们主要学习多条曲线的绘制,以及给不同的曲线指定不同的纵坐标. 新的数据 由于我们要画两条曲线,所以我们要在原来 ...

  7. D3.js学习(四)

    上一节我们已经学习了线条样式和格栅的绘制,在这一节中我们将要根据之前绘制的线条对图表进行填充,首先来看一下我们的目标吧 在这个图表中,我们对位于线条下面的空间进行了填充,那么,如何改做到呢? 设置填充 ...

  8. D3.js学习(三)

    上一节中,我们已经画出了图表,并且给图表添加了坐标轴的标签和标题,在这一节中,我们将要学习几个绘制线条不同特性的几个函数,以及给图表添加格栅.ok,进入话题! 如何给线条设置绘制的样式? 这个其实非常 ...

  9. D3.js 学习( 一)

    <html> <head> <meta charset="utf-8"> <title>第三课:为柱形图添加坐标轴</titl ...

随机推荐

  1. jQuery+CSS3文字跑马灯特效

    jQuery+CSS3文字跑马灯特效是一款将跑马灯背景制作为3D立方体效果,文字在上面移动时,就像是文字投影到墙壁上,在转角出会改变运动方向. 效果展示 http://hovertree.com/te ...

  2. java基础知识(十一)java反射机制(下)

    1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...

  3. java 内存观察

    总结一下上周的工作. 主要就是用到了 jmap jvisualvm jmap 用来生成jvm堆内存的bin文件 jvisualvm则更强大. 待续.

  4. TFS 2012 在IE11和Chrome (Windows 8.1) 显示英文的解决方案

    1.如果使用IE11浏览TFS Web显示英文,请执行以下操作: 控制面板——>语言——>高级设置 将“替代Windows显示语言”改为“中文(中华人民共和国)”,同时勾选“Web语言”下 ...

  5. eclipse中运行项目时报Class not found的错误

    环境:Groovy/Grails Tool Suite 3.1.0.RELEASE(BASED ON ECLIPSE JUNO 3.8.1).JDK1.6 运行class的main方法,或启动juni ...

  6. 文件_ _android从资源文件中读取文件流并显示的方法

    ======== 1   android从资源文件中读取文件流并显示的方法. 在android中,假如有的文本文件,比如TXT放在raw下,要直接读取出来,放到屏幕中显示,可以这样: private ...

  7. JavaBean与Jsp

    这一节我们总结一下JavaBean和Jsp的关系. 1. JavaBean javaBean是一个遵循特定写法的Java类,它通常具有如下特点:        1)这个java类必须具有一个无参构造函 ...

  8. Asp.Net 配置IISExpress允许外部访问

    1.找到IISExpress的配置文件,或位于(文档/IISExpress/config)文件夹下,打开applicationhost.config,找到如下代码:<site name=&quo ...

  9. 思科产品选型pdf

    以前做工程时候想起了设备选型时候用过的一份文档. 有个小伙伴今天问起思科设备选型,恰好google到了这份文档 https://www.cisco.com/web/CN/products/pdf/04 ...

  10. slf4j提示Class path contains multiple SLF4J bindings

    报错: SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding .jar!/org/slf4j/impl/St ...