[D3.js] 综述

D3.js 是操作基于数据文件的JavaScript库。它使用HTML、SVG和CSS让你的数据基情四射。D3在web标准上着重为你提供现代浏览器的全部功能,而且不需要通过使用你自己专门的框架、结合强大的可视化组件和DOM操作的数据驱动方法。

点击下载最新版(3.5.5):

或者,在页面上引用:

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

使用HTTPS的站点应该使用本机下的D3,或者支持HTTPS的CDN,例如 CDNJS  完整的资源和用例 也可以在GitHub上 下载 

 

# 引言

D3允许你将任意的数据绑定到文档对象模型(DOM),然后运用数据驱动转换到文档上。例如,你可以使用D3将一个数组生成一个HTML表格。或者,使用相同的数据来创建一个有平滑过渡和交互的交互式SVG条形图。

D3不是一个旨在提供每一个可能想到的功能的单一框架。相反的,D3所解决的问题的关键是:高效操作基于数据的文档。它提供了显著的灵活性,展现了web标准的全部功能,比如HTML、SVG 和 CSS。D3非常快,它以最小的开销支持大型数据集以及交互与动画的动态行为。D3的函数式风格使代码通过组件插件的多元化集合得以重用。

 

# 选集(选择器?)

使用W3C DOM API来修改文档是很没劲的:方法名冗长,立即执行方法需要手动迭代和登记临时状态。例如,更改段落的文本颜色:

var paragraphs = document.getElementsByTagName("p");
for (var i = 0; i < paragraphs.length; i++) {
  var paragraph = paragraphs.item(i);
  paragraph.style.setProperty("color","white", null);
}

 D3采用已声明好的方法,操作任意的节点集合即选择器。例如,可以将上面的循环改写为:

d3.selectAll("p").style("color", "white");

 当然,你也可以操作所需的单一节点:

d3.select("body").style("background-color", "black");

选择器是W3C Selectors API中定义的一个概念,也受现代浏览器原生支持。SizzlejQuery1.3版以后引进的CSS选择器引擎)为旧版的浏览器提供了向后兼容。上述例子中是通过标签名(分别是“p”和“body”)来选择节点。元素也可以通过各种形式被选择,包括容器,属性值,class 和 id。
D3提供许多方法去操作节点:设置属性或样式;注册事件监听;添加、移除或查找节点;变换HTML或文本内容。这些足以满足绝大部分的需求。直接访问底层的DOM也是可以的,因为D3选择器只是一个简单的节点数组。

# 动态属性
 熟悉 jQuery 或 Prototype 的读者应该马上能意识到D3的相似之处。然而,样式、属性和其他特性在D3中都被认做是数据的方法,而不只是简单的常量。尽管它们表面上看起来很简单,但这些方法却非常强大。例如d3.geo.path这个方法可以将地理坐标工程化为SVG的路径数据。D3提供很多内置可重复使用的方法和方法工厂,比如面积图、折线图、饼图等图的 图像元
例如,给段落随机添加颜色:

d3.selectAll("p").style("color", function() {
  return "hsl(" + Math.random() * 360 + ",100%,50%)";
});

 用灰白将奇偶节点交替着色:

d3.selectAll("p").style("color", function(d, i) {
  return i % 2 ? "#fff" : "#eee";
});

计算属性往往涉及到数据绑定。数据被约定为一个数组,这些值会作为第一个参数(d)传到方法里面。通过默认的按索引加入,数组里的第一个元素会被传给选择器里的第一个节点,第二个元素传给第二个节点,以此类推。举个栗子,将一个数组绑定到段落元素,用这些数据来给段落动态地渲染字体大小:

d3.selectAll("p")
    .data([4, 8, 15, 16, 23, 42])
    .style("font-size", function(d) { return d + "px"; });

一旦数据被绑定到文档上,你就可以省去了对数据的操作;D3将会自动检索之前绑定的数据。这样你就不需要重新绑定然后再去计算属性了。

 

# Enter & Exit

使用D3的 enter 和 exit,可以为传入的数据创建新节点以及移除一些不再需要了的节点。

当数据绑定到选择器上时,每个数据元素将会与选择器里的相应节点配对。如果节点比数据少,使用enter来append节点,那些多出来的数据就可以作为它的参数。例如:

d3.select("body").selectAll("p")
    .data([4, 8, 15, 16, 23, 42])
    .enter().append("p")
    .text(function(d) { return "I’m number " + d + "!"; });

 

 数据操作的默认结果是更新节点。因此,如果没有enter和exit,则只是自动选择那些与已有节点匹配的元素。data操作符返回的是三个部分(虚拟选集):enter, updata, exit.

====================== P.S. 分割线 begin =========================

PS:关于selections 的一篇美文

enter选集:对所有缺失的元素以占位符placeholder替代。

update选集:包含现有的元素,并绑定到数据

剩下的元素最终都会出现在exit选集中,并被移除。

===================== P.S. 分割线 end ===========================

// Update…
var p = d3.select("body").selectAll("p")
    .data([4, 8, 15, 16, 23, 42])
    .text(String);

// Enter…
p.enter().append("p")
    .text(String);

// Exit…
p.exit().remove();

 

 通过单独处理这三种情形,你可以清晰地看出哪些操作是运行在哪些节点上的。这提高了性能也为一些过渡提供了更好的控制。例如,一个条形图,你可以先用一些旧的数据初始化它,然后在更新的过程中再用新的数据过渡转换一下,最后把多余的元素移除。

D3使你能够根据数据去变换文档,其中包括创建和删除元素。它可以通过响应用户交互、一段时间内的动画或者第三方的异步通知来改变已有的文档。在服务端将文档初始渲染好,然后在客户端通过D3去更新它,这种混合的方法通常也是ok的。

 

# 转换(Transformation)而不是表示( Representation)

D3不是一个新的图形表示库。不像ProcessingRaphaël, 或者 Protovis,D3的标记词汇都是直接来自web标准:HTML、SVG 和 CSS。比如说,你可以用D3来创建一个SVG元素然后用外部的层叠样式表来渲染它。你可以使用综合的过滤效果,dashed strokes 和 clipping。假设将来浏览器厂商推出了新的功能,你就能马上使用它们——不需要更新工具包。而且,如果你以后要使用D3以外的工具包,你也已经形成了这些标准的知识。

最厉害的是,D3可以简便地用浏览器的审查元素来调试:那些你用D3操作的节点实际上也是浏览器本身已知道的节点。

 

# Transitions

D3在变换上的重点自然延伸到了过渡动画。过渡是随时间逐渐插补一些样式和属性。渐变动画可以通过easing方法来控制效果,例如“elastic”, “cubic-in-out” 和 “linear”。D3的插补器既支持原语,例如数字还有字符串中的数字(字体大小,路径数据,等),也支持复合值。甚至你可以自己拓展D3插补器的注册表去支持复杂的属性和数据结构。

例,将页面背景褪化为黑色:

d3.select("body").transition()
    .style("background-color", "black");

Or,有延迟地调整一个圆的大小:

d3.selectAll("circle").transition()
    .duration(750)
    .delay(function(d, i) { return i * 10; })
    .attr("r", function(d) { return Math.sqrt(d * scale); });

 实际上D3仅通过修改属性,减少了开销,并且能够处理高帧速的大型复杂图形。D3也可以通过事件处理完成一系列复杂的过渡。而且,你还能使用css3过渡;D3不会替代浏览器的工具箱,但会让它使用起来更为简便。

 

====================== 终于翻译完毕之分割线 ==========================

 原文 :

欲知后事如何,且听下回分解

 

posted @ 2015-03-11 17:38  Ann Tseng  阅读(2386)  评论(0编辑  收藏  举报