d3.js之初体验

需求:d3.js之初体验

D3.js 中的所有功能在 JavaScript 中都能实现,它仅仅是一个函数库而已。D3 所做的事就是减轻你的工作量,以及使你的代码十分简单易懂。

1.强大的选择器

使用 d3.select() 或 d3.selectAll() 选择元素后返回的对象,就是选择集

关于 select 和 selectAll 的参数,其实是符合 CSS 选择器的条件的,即用“井号(#)”表示 id,用“点(.)”表示 class。

如何选择元素
在 D3 中,用于选择元素的函数有两个:

  • d3.select():是选择所有指定元素的第一个
  • d3.selectAll():是选择指定元素的全部

2.绑定数据

D3 能将数据绑定到 DOM 上,也就是绑定到文档上

例如网页中有段落元素 p 和一个整数 5,于是可以将整数 5 与 p 绑定到一起。绑定之后,当需要依靠这个数据才操作元素的时候,会很方便。

D3 中是通过以下两个函数来绑定数据的:

  • datum():绑定一个数据到选择集上
  • data():绑定一个数组到选择集上,数组的各项值分别与选择集的各元素绑定(data() 比较常用)
var str = "China";

var body = d3.select("body");
var p = body.selectAll("p");

p.datum(str);

p.text(function(d, i){
    return "第 "+ i + " 个元素绑定的数据是 " + d;
});

在上面的代码中,用到了一个无名函数 function(d, i)。当选择集需要使用被绑定的数据时,常需要这么使用。其包含两个参数,其中:

  • d 代表数据,也就是与某元素绑定的数据。
  • i 代表索引,代表数据的索引号,从 0 开始。

例如,上述例子中:第 0 个元素 apple 绑定的数据是 China

3.插入元素

  • append():在选择集末尾插入元素
  • insert():在选择集前面插入元素

4.删除元素

var p = body.select("#myid");
p.remove();

如此即可删除指定 id 的段落元素。

5.简单柱状图

组成要素:矩形、文字标签、坐标轴组成
HTML 5 提供两种强有力的“画布”:SVG 和 Canvas。

(1)SVG 有如下特点:

  • SVG 绘制的是矢量图,因此对图像进行放大不会失真。
  • 基于 XML,可以为每个元素添加 JavaScript 事件处理器。
  • 每个图形均视为对象,更改对象的属性,图形也会改变。
  • 不适合游戏应用。

(2)Canvas 有如下特点:
- 绘制的是位图,图像放大后会失真。
- 不支持事件处理器。
- 能够以 .png 或 .jpg 格式保存图像
- 适合游戏应用

D3 虽然没有明文规定一定要在 SVG 中绘图,但是 D3 提供了众多的 SVG 图形的生成器,它们都是只支持 SVG 的。因此,建议使用
SVG 画布。

var width = 300;  //画布的宽度
var height = 300;   //画布的高度

var svg = d3.select("body")     //选择文档中的body元素
    .append("svg")          //添加一个svg元素
    .attr("width", width)       //设定宽度
    .attr("height", height);    //设定高度

在 SVG 中,矩形的元素标签是 rect,
x 轴的正方向是水平向右,y 轴的正方向是垂直向下的。

矩形的属性,常用的有四个:

  • x:矩形左上角的 x 坐标
  • y:矩形左上角的 y 坐标
  • width:矩形的宽度
  • height:矩形的高度

有数据,而没有足够图形元素的时候,使用此方法可以添加足够的元素。

svg.selectAll("rect")   //选择svg内所有的矩形
    .data(dataset)  //绑定数组
    .enter()        //指定选择集的enter部分
    .append("rect") //添加足够数量的矩形元素
//demo
//创建画布
    var width = 300;  //画布的宽度
    var height = 300;   //画布的高度

    var svg = d3.select("body")     //选择文档中的body元素
    .append("svg")          //添加一个svg元素
    .attr("width", width)       //设定宽度
    .attr("height", height).style("background","red");    

    var rectHeight = 25;   //每个矩形所占的像素高度(包括空白)

    var dataset = [ 250 , 210 , 170 , 130 , 90 ];  //数据(表示矩形的宽度)
    svg.selectAll("rect")   //选择svg内所有的矩形
        .data(dataset)  //绑定数组
        .enter()        //指定选择集的enter部分
        .append("rect") //添加足够数量的矩形元素
        .attr("x",20)
        .attr("y",function(d,i){
             return i * rectHeight;
        })
        .attr("width",function(d){
             return d;
        })
        .attr("height",rectHeight-2)
        .attr("fill","steelblue");//是给矩形元素设置颜色。一般来说,最好写成外置 CSS 的形式,方便归类和修改

6.比例尺

绘图时,直接使用 250 给矩形的宽度赋值,即矩形的宽度就是 250 个像素。此方式非常具有局限性,如果数值过大或过小,例如:

var dataset_1 = [ 2.5 , 2.1 , 1.7 , 1.3 , 0.9 ];
var dataset_2 = [ 2500, 2100, 1700, 1300, 900 ];

2.5 个像素来代表矩形的宽度,那样根本看不见;也不可能用 2500 个像素来代表矩形的宽度,因为画布没有那么长。

比例尺,很像数学中的函数。例如,对于一个一元二次函数,有 x 和 y 两个未知数,当 x 的值确定时,y 的值也就确定了。在数学中,x 的范围被称为定义域,y 的范围被称为值域。

D3 中的比例尺,也有定义域值域,分别被称为 domainrange。开发者需要指定 domain 和 range 的范围,如此即可得到一个计算关系。

6.1 线性比例尺

能将一个连续的区间,映射到另一区间

//将 dataset 中最小的值,映射成 0;将最大的值,映射成 300。

var dataset = [1.2, 2.3, 0.9, 1.5, 3.3];

var min = d3.min(dataset);//求数组最小值
var max = d3.max(dataset);//求数组最大值

var linear = d3.scale.linear()
        .domain([min, max])
        .range([0, 300]);

linear(0.9);    //返回 0
linear(2.3);    //返回 175
linear(3.3);    //返回 300

其中,d3.scale.linear() 返回一个线性比例尺。domain() 和 range() 分别设定比例尺的定义域和值域

比例尺的定义域 domain 为:[0.9, 3.3]
比例尺的值域 range 为:[0, 300]

d3.scale.linear() 的返回值,是可以当做函数来使用的。因此,才有这样的用法:linear(0.9)。

6.2 序数比例尺

有时候定义域和值域不一定是连续,例如,有两个数组:

var index = [0, 1, 2, 3, 4];
var color = ["red", "blue", "green", "yellow", "black"];

我们希望 0 对应颜色 red,1 对应 blue,依次类推, 但是,这些值都是离散的,线性比例尺不适合,需要用到序数比例尺

var index = [0, 1, 2, 3, 4];
        var color = ["red", "blue", "green", "yellow", "black"];
        var ordinal = d3.scale.ordinal()
                              .domain(index)
                              .range(color);

7.坐标轴

由一些列线段和刻度组成,坐标轴在 SVG 中需要用其他的元素组合构成,D3提供了坐标轴的组件

在 SVG 画布的预定义元素里,有六种基本图形:

  • 矩形 (rect)

x:矩形左上角的x坐标
y:矩形左上角的y坐标
width:矩形的宽度
height:矩形的高度

 <rect x="20" y="20" width="200" height="100" style="fill:steelblue;stroke:blue;stroke-width:4;opactity:0.5"/> 
  • 圆形 (circle )

cx:圆心的x坐标
cy:圆心的y坐标
r:圆的半径

 <circle cx="150" cy="150" r="80" style="fill:yellow;stroke:black;stroke-width:2"/>
  • 椭圆(ellipse )

cx:椭圆圆心的x坐标
cy:椭圆圆心的y坐标
rx:椭圆的x轴半径
ry:椭圆的y轴半径

<ellipse cx="250" cy="150" rx="200" ry="100" style="fill:green;stroke:blue;stroke-width:1"/>
  • 线段(line)两点坐标

x1:起点的x坐标
y1:起点的y坐标
x2:终点的x坐标
y2:重点的y坐标

 <line x1="20" y1="10" x2="200" y2="230" style="stroke:red;stroke-width:3"/>
  • 折线(polyline )

points:折线各个点坐标

<polyline points="100,30, 20,80 60,160 140,160 180,90" style="fill:white;stroke:black;stroke-width:1" transform="translate(200,0)" />
  • 多边形(polygon )

points:多边形各个点的坐标

 <polygon points="100,30, 20,80 60,160 140,160 180,90" style="fill:LawnGreen;stroke:black;stroke-width:1" />
  • 路径(path )

M:起点坐标
L:画直线到指定坐标
H:画水平直线到指定坐标,省略了y轴坐标
V:画垂直直线到指定坐标,省略了x轴坐标
C:三次贝赛尔曲线经两个指定控制点和到达终点坐标
S:与前一条贝塞尔曲线相连,第一个控制点为前一条曲线第二个控制点的对称点,只需要第二个控制点和终点

<svg width="500" height="300" version="1.1">
    <path d="M30,50 L200,200" style="stroke:black;stroke-width:1"/>
    <path d="M30,50 H200" style="stroke:red;stroke-width:1"/>
    <path d="M30,50 V200" style="stroke:blue;stroke-width:1"/>
</svg>

基础图形在演变而来的图形
- 圆角矩形
- x:矩形左上角的x坐标
- y:矩形左上角的y坐标
- width:矩形的宽度
- height:矩形的高度
- rx:对于圆角矩形,圆角对应的椭圆在x方向上的半径
- ry:对于圆角矩形,圆角对应的椭圆在y方向上的半径

 <rect x="20" y="20" rx="30" ry="50" width="200" height="100" style="fill:red;stroke:black;stroke-width:3;opacity: 0.5;">
  • 曲线
    C:三次贝赛尔曲线经两个指定控制点和到达终点坐标
    S:与前一条贝塞尔曲线相连,第一个控制点为前一条曲线第二个控制点的对称点,只需要第二个控制点和终点
<svg width="500" height="300" version="1.1">
   <path d="M30,100 C100,20 190,20 270,100 S400,180 450,100" style="fill:white;stroke:red;stroke-width:2"/>
</svg>
  • 弧线 (没有理解原理)
    A( rx , ry , x-axis-ratation , large-arc-flag , sweep-flag , x , y)

    rx:椭圆x方向的半轴大小

    ry:椭圆y方向的半轴大小

    x-axis-ratation:椭圆的x轴与水平轴顺时针方向夹角

    large-arc-flag:两个值(1:大角度弧线 0:小角度弧线)

    sweep-flag:两个值(1:顺时针至终点 0:逆时针至终点)

    x:终点x坐标

    y:终点y坐标
<svg width="500" height="300" version="1.1">
    <path d="M100,200 A50,30 0 1,0 150,-150 " style="fill:red;stroke:blue;stroke-width:1"/>
</svg>
D3 提供了一个组件:d3.svg.axis(), 坐标轴和比例尺经常一起使用 (1)定义坐标轴
//数据
var dataset = [ 2.5 , 2.1 , 1.7 , 1.3 , 0.9 ];
//定义比例尺
var linear = d3.scale.linear()
      .domain([0, d3.max(dataset)])
      .range([0, 250]);

var axis = d3.svg.axis()
     .scale(linear)      //指定比例尺
     .orient("bottom")   //指定刻度的方向
     .ticks(7);          //指定刻度的数量
  • d3.svg.axis():D3 中坐标轴的组件,能够在 SVG 中生成组成坐标轴的元素。
  • scale():指定比例尺。
  • orient():指定刻度的朝向,bottom 表示在坐标轴的下方显示。
  • ticks():指定刻度的数量。

(2)在 SVG 中添加坐标轴
定义了坐标轴之后,只需要在 SVG 中添加一个分组元素 ,再将坐标轴的其他元素添加到这个 里即可。代码如下:

svg.append("g")
   .call(axis);

call() 函数,其参数是前面定义的坐标轴 axis。在 D3 中,call() 的参数是一个函数。调用之后,将当前的选择集作为参数传递给此函数。

未完成
1、一个完整的柱形图(矩形、文字、坐标轴 )
2、图标添加动画

猜你喜欢

转载自blog.csdn.net/yy493004893/article/details/79391605