本节书摘来异步社区《D3.js数据可视化实战手册》一书中的第2章,第2.6节,作者: 【加拿大】Nick Qi Zhu,更多章节内容可以访问云栖社区“异步社区”公众号查看。
2.6 函数级联调用
到现在为止,我们看到的D3 API都体现了函数级联调用的思想。因此它接近于形成了一个可以动态构建HTML/SVG的领域特定语言(Domain Specific Language)。在接下来的例子中,我们将看到如何只使用D3来生成前一个例子的页面结构。
提示.tif 如果对DSL不熟悉,推荐阅读Martin Fowler在领域特定语言(Domain-Specific Languages)一书中的相关解释,参见http://www.informit.com/articles/article.aspx?p=1592379
。
2.6.1 准备阶段
在浏览器中打开如下文件的本地副本。
https://github.com/NickQiZhu/d3-cookbook/blob/master/src/chapter2/function-chain.html
2.6.2 开始编程
接下来我们将展示如何用简洁可读的函数级联调用生成动态图形。
<script type="text/javascript">
var body = d3.select("body"); // <-- A
body.append("section") // <-- B
.attr("id", "section1") // <-- C
.append("div") // <-- D
.attr("class", "blue box") // <-- E
.append("p") // <-- F
.text("dynamic blue box"); // <-- G
body.append("section")
.attr("id", "section2")
.append("div")
.attr("class", "red box")
.append("p")
.text("dynamic red box");
</script>
上述代码生成如下视觉效果(和之前章节效果类似)。
2.6.3 工作原理
尽管和之前的效果很类似,但本例中对DOM元素的构造过程却完全不同。如代码所示,本例中页面上并没有任何静态HTML元素,而之前的例子中,section和div元素都是事先存在的。
让我们进一步研究一下这些元素是如何被动态创建的。在行A中,我们先选取了顶层的body元素。然后用一个临时变量body来缓存该选集结果。而后行B在body元素内追加一个新的元素section。由于append函数返回了一个包含新添加元素的选集,因此在行C中就可以为这个新创建的section元素的id属性赋值,这里它的值为section1。行D为#section1附加了一个新创建的div元素,并且在行E中设置css class为blue box。随后,类似地,我们在行F中往这个div元素上附加一个段落元素,并在行G中设置其文本内容为dynamic blue box。
如上所述,这种级联处理可以继续生成任意复杂的结构。事实上,典型的基于D3的数据可视化结构正是这样创建的。许多可视化项目都只简单包含一个HTML骨架,然后用D3来创建剩余部分。如果想要熟练运用D3库,掌握这种函数级联调用的方式是必不可少的。
技巧.tif 部分D3修饰函数会返回一个新的选集,例如select、append、insert函数。建议用缩进来区别应用于不同选集上的级联函数,这是个不错的实践方式。