D3 API详解(txt+pdf+epub+mobi电子书下载)


发布时间:2020-07-11 22:52:08

点击下载

作者:张天旭

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

D3 API详解

D3 API详解试读:

前言

数据可视化是用图形图像等方式表现数据内涵的技术。俗话说“一图胜千言”,数据可视化最重要的意义在于让数据变得简单直观。它有效利用了人眼的感知能力和大脑的处理能力,让数据中蕴含的规律一目了然。尤其是在大数据时代,数据可视化已成为一座桥梁,跨越了数据和使用者之间的鸿沟,减少了在数据分析、交流和传播中的障碍。它使得人们对海量、复杂数据的阐释和理解变得事半功倍。在很多情况下,数据可视化是理解和表达数据的有效手段,有时甚至是唯一的手段。

数据可视化的强大魅力还源于它是美而生动的。只有一堆数据难免枯燥乏味,可视化技术给数据穿上了华丽的外衣,丰富的交互功能增添了数据的灵动性。数据可视化绽放了数据之美。它让数据变得生动鲜活,有效地吸引了人们的注意力,能大大激发人们的好奇心和求知欲。让人们在与数据的交互过程中不仅探索到了知识还收获了乐趣。正因为如此,数据可视化技术蓬勃发展,在互联网、生物、金融、医学、建筑、教育、国防等需要展现数据的行业都有广泛的应用。

工欲善其事必先利其器。D3是当今最流行的数据可视化工具之一。D3是一个JavaScript库,擅长绘制交互式矢量图表,底层使用了SVG绘图技术并通过数据驱动创建文档。D3提供的API主要包括对HTML和SVG文档的操作、处理多种格式的数据、为特定的可视化布局生成数据,以及提供丰富的交互和动画功能等。通过这些编程接口,我们既不用太关心底层实现,也不会因为封装程度太高而很难修改,[1][2]所以D3比Processing这样的底层绘图库更简单,比Echarts这样高度封装的图表库更自由,是一个灵活轻量的前端数据可视化库。而且D3不依赖其他的库,你可以充分发挥想象,仅用D3就可以创造绚丽多彩的数据可视化作品。当然,到底要不要使用D3还需要根据具体情况进行选择,表0.1可以作为一个技术选型的参考。表0.1 D3的适用范围考虑因素适用范围[3],可以免费D3基于开源协议BSD-3-Clause[4],截至用于商业项目。源码托管在GitHub上开源2015年9月26日star数已达41869次,fork数达11021次,有大量用户和丰富友好的案例支持Firefox、Chrome、Safari、Opera、兼容性IE9+等现代浏览器。支持Android和iOS平台D3擅长于绘制二维Web数据可视化矢量图表,支持丰富的交互功能,支持创建自定义可视化方案。但不支持3D可视化,并且加载功能到浏览器的数据量不能太大(10MB以内较合适)。D3不是现成的图表库,相比于封装好的图表库学习和开发成本都较高

目前D3的官方文档已经十分全面了,涵盖了600多个函数,全文接近6万个单词。然而,D3参考文档中的专业术语较多,很多地方表述十分晦涩艰深,原文中的示例代码较少,况且对于初学者来说直接看英文也很吃力。本书笔者为了方便D3学习者更好地理解和使用D3,[5]对D3官方API(应用程序编程接口)进行了详细介绍,还为大部分函数都编写了简单的示例代码。下面,我们先来看看本书涉及的D3官方文档主要包含哪些内容,D3 API总览如表0.2所示。表0.2 D3 API总览

本书覆盖了绝大部分的API,为方便使用,本书尽量保持与官方文档结构一致,对表0.2的每个部分单独成章介绍。本书所用的D3版本是3.5.5,全文案例在Chrome浏览器中调试通过。一些简单的函数直接使用浏览器的控制台演示,少部分案例需要使用服务器运行,大部分案例都可以直接打开HTML文档来查看效果。对于本书的使用,强烈建议读者朋友们边看文字表述边参考示例代码动手实践。本书的随书源码可在https://github.com/tianxuzhang/d3-api-demo/archive/master.zip和http://www.broadview.com.cn/27899下载使用,通过量的积累最终一定会有质的改变。大家要保持对新技术的兴趣和对理想的热情,在自学的同时多分享多讨论。D3的学习会是很有成就感的,希望读者可以通过本书感受到数据可视化的魅力,能从中收获快乐。致谢

首先要感谢章成志教授的启蒙教育,是他让我了解到D3这门技术。并且,在学习和生活中给予了我足够的信任和支持。可以说,章老师是我真正的良师益友。

其次,感谢Mike Bostock以及其他D3贡献者,是他们开发了D3这个优秀的数据可视化库,并且提供了大量简单实用的案例。正因为如此,才能让我们有机会领略数据可视化的奇妙。

还要感谢CSDN这个平台,CSDN是中国程序员最常使用的技术网站。通过CSDN让我能够与更多数据可视化爱好者相识并共同探讨D3相关技术。

感谢电子工业出版社的付睿编辑,没有伯乐就没有千里马,谢谢她给予我这个机会编写本书。感谢顾慧芳编辑,谢谢她为本书辛勤校对和编辑,这有效地保障了本书的质量。

最重要的是要感谢参与D3参考文档翻译以及对本书提供帮助的人,他们是:崔博敏、何凯琳、张玉杰、季国亮、张烁、边城、卫学士、翟琰琦、路明非、何丽、谁浮、马语者、现明涟漪、Carry on、陶凜然、李琛婧、赵荣和宋墩江以及其他关心和支持我的人,和你们的讨论和交流是我最温暖的回忆。

最后,也是最应该感谢的是一直与我并肩奋斗的魏飞,感谢那些安静得只剩下键盘声的夜晚,每一个奋斗的日子都值得深深铭记。

由于作者水平有限,书中难免有错误之处,我们渴望得到您的反馈,如果发现问题请发送邮件至zhang_tianxu@sina.com,或者在新浪微博上@D3数据可视化给我们批评指正。张天旭2015年9月

[1]https://processing.org/.

[2]http://echarts.baidu.com/index.html.

[3]http://opensource.org/licenses/BSD-3-Clause.

[4]https://github.com/mbostock/d3.

[5]https://github.com/mbostock/d3/wiki/API-Reference.第1章 核心(Core)[1]

本章介绍D3的核心API函数。D3的核心API主要包含一些常用的文档操作和数据处理等方面的函数。在文档操作方面,D3的核心函数可以选取DOM元素,改变元素的属性、样式和内容。还可以追加、插入和删除元素。通过数据绑定可以创建数据驱动的文档。对元素使用过渡函数可以编写生动的动画效果。另一方面,很多针对数据的函数便于获取外部数据,对数据进行格式化、本地化等处理。有一些函数可以用来生成随机数,操作二维仿射变换。还有大量函数便于操作数组、映射、集合、嵌套等不同结构的数据。1.1 选择[2]

一个选择就是从当前文档中选中的一组元素。D3使用CSS3选择器来选择页面元素。如果浏览器不支持CSS3选择器,则可以在D3[3]前引入Sizzle来向后兼容。1.1.1 d3.select(selector)

选择第一个与指定字符串selector相匹配的元素,选择器字符串通常是CSS选择器。如果没有匹配的元素,则返回一个空的选择对象。

例如,对如下结构的两个表格:

苹果 香蕉 西瓜
桃子 草莓 菠萝
可乐 牛奶
绿茶 啤酒

下列选择器的选择结果分别是:d3.select('td') //选择第一个td标签d3.select('#test') //选择第一个ID名为"test"的元素d3.select('.test') //选择第一个类名为"test"的元素

例如,我们把选中的元素的背景色设置为橘黄色,字体颜色设置为白色(详见参考案例),设置前后的效果如图1.1所示。图1.1 d3.select(selector)选择单个匹配的元素

参考案例:demo/core/selection/d3.select_selector.html。1.1.2 d3.select(node)

选择指定的节点。这通常用于在事件监听器中使用d3.select(this)选择当前节点或者与其他第三方库(如JQuery)整合,例如d3.select($("body")[0][0])。这个选择器不会去遍历文档结构。

例如,对1.1.1节中的表格,想要在单击body区域时设置选中元素的字体颜色变为绿色可以这样写:d3.select(document.body) //选择body节点.on("click",function(){ d3.select(this) //选择当前节点,即body节点 .style("color","green");});

效果如图1.2所示。图1.2 d3.select(node)选择单个匹配的节点

参考案例:demo/core/selection/d3.select_node.html。1.1.3 d3.selectAll(selector)

选择所有与指定字符串selector相匹配的元素,选择的结果是一个数组,这些元素会按照文档的遍历顺序(从上到下)存入数组。如果当前文档中没有匹配的元素则返回空的选择。

例如,对1.1.1节中的表格:d3.selectAll("td") //选择文档中所有的td标签

然后,设置所有匹配元素的背景色为橘黄色,字体颜色为白色(详见参考案例),可得到如图1.3所示的效果。图1.3 d3.selectAll(selector)选择所有匹配的元素

参考案例:demo/core/selection/d3.selectAll_selector.html。1.1.4 d3.selectAll(nodes)

选择指定的节点数组。例如,可以这样使用:d3.selectAll(this.childNodes); //在一个事件监听器中,选择当前元素的所有子元素d3.selectAll(document.links); //选择文档中所有的超链接

选择的结果是一个元素数组。D3在这个数组上绑定了额外的方法可以操作这些元素,例如:为所有选中的元素设置属性值。选择结果是分组的,而不是一个一维数组,元素数组中的每个值都是一个子数组。这保留了子选择的层次结构,所以当selectAll只选中一个元素时返回的选择结果看起来像[[node]]而不是[node]。1.1.5 selection.attr(name[, value])

如果指定了value参数,则用来设置所有选中元素中指定属性的值,否则返回选择集中第一个非空元素中指定属性的值。value参数可以是常数,也可以是一个函数。如果是函数,则这个函数会有两个参数:d代表当前元素绑定的数据,i代表当前元素在选中元素集中的索引。函数返回值用来为每个元素设置属性值,在函数内部可以使用this关键字引用当前元素。如果value参数的值为null则移除指定的属性。D3中元素的大多数操作都支持多属性设置,即:一次设置多个属性。

例如,下面的代码演示了如何创建矩形,其中使用多种设置属性值的方法:rects=svg.selectAll("rect") .data(dataset) .enter() .append("rect") .attr({ //一次设置多个属性值 "x":function(d,i){ return 20+i*160/dataset.length;}, //使用函数设置属性值 "y":function(d){ return 20;}, "width":20, "height":100 }) .attr("fill","steelblue"); //一次设置一个属性值

效果如图1.4所示。图1.4 使用多种设置属性值的方法设置矩形的属性

参考案例:demo/core/selection/selection.attr.html。【小提示】指定name参数的值有时也会含有一个前缀,例如xlink:href是用来指定Xlink命名空间中href属性的。默认情况下,D3支持svg、xhtml、xlink、xml和xmlns命名空间。1.1.6 selection.classed(name[, value])

如果没有指定value参数,则返回与name参数匹配的第一个非空元素是否绑定了指定的CSS类,true表示绑定,false表示未绑定;如果指定了value参数,则值为true时绑定name参数指定的CSS类;为false时移除这个CSS类。该函数主要用来添加、移除或切换CSS类;value参数可以是一个布尔值或者函数,如果是函数,则这个函数会有两个参数:d代表当前元素绑定的数据,i代表当前元素在选择结果集中的索引。在函数内部可以使用this关键字引用当前元素,函数将返回布尔类型的值。

例如:有5个矩形,我们将元素索引为奇数的矩形填充为紫色,偶数的填充为番茄红色:rects.classed({ //根据索引给元素添加不同的CSS类 "even":function(d,i){ return i%2==0?true:false;}, "odd":function(d,i){ return i%2==0?false:true;}});

然后,给这些矩形绑定点击事件。在点击鼠标时判断这个矩形绑定的CSS类,根据这个判断结果给这个矩形添加描边外框并设置为半透明,或者移除描边外框并恢复为不透明。rects.on("click",function(){ //点击时切换CSS类 var rect=d3.select(this); if(rect.classed("stroke")){ //取得元素是否绑定指定名称的CSS类 rect.classed("stroke",false); //移除元素绑定的CSS类 }else{ rect.classed("stroke",true); //给元素绑定CSS类,可以绑定多个类 }});

这样就可以使用类操作符添加、移除和切换CSS类了,效果如图1.5左右两图所示。图1.5 使用类操作符添加、移除和切换CSS类

参考案例:demo/core/selection/selection.classed.html。1.1.7 selection.style(name[, value[, priority]])

返回选择集中第一个非空元素中名为name的样式值,或设置选择集中所有元素中名为name的样式值为value参数指定的值。参数priority用来设置优先级,默认为null。value参数可以是常数或函数。如果是函数,那么这个函数有两个参数:d代表当前元素已绑定的数据,i代表当前元素在元素集中的索引。在函数内部也可以使用this关键字引用当前元素。如果value参数的值为null,则会删除name参数指定的样式。例如://获取第一个非空元素描边属性的值selection.style("stroke");//设置矩形元素的样式为宽度5像素的绿色描边rects.style("stroke", "green").style("stroke-width", 5);

D3中元素的大多数操作都支持多属性设置,即一次设置多个属性,如://设置元素的描边属性值为函数的返回值、stroke-width属性值为5selection.style({ "stroke-width": 5, "stroke": function(d,i){ return "rgb("+10*d+","+10*(25-d)+","+d+")"; }});

效果如图1.6所示。图1.6 使用样式操作符操作样式

参考案例:demo/core/selection/selection.style.html。1.1.8 selection.property(name[, value])

一些HTML元素具有特殊的内置属性,使用标准的属性或样式操作符是访问不到的。例如,表单中文本字段(text)的value字符串属性、复选框(checkboxes)的checked布尔型属性。可以使用property操作符来获取或设置。

如果指定了value参数,就为所有选中的元素指定name参数指定的属性的值为value参数指定的值。如果value参数是常数,那么为所有被选中元素赋予相同的属性值;如果value参数是函数,则该函数为每个选中的元素(按顺序)计算name参数指定的属性的值。value函数有两个参数:d代表当前元素已绑定的数据,i代表当前元素在元素集中的索引。在value函数内部也可以使用this关键字引用当前元素。如果value参数的值为null,则会删除name参数指定的属性。

D3中元素的大多数操作都支持多属性设置,即一次设置多个属性,如:selection.property({'foo': 'bar', 'baz': 'qux'}) //同时设置元素的foo和baz属性

如果未指定value,则返回选中元素中第一个非空元素中name参数指定的属性的值。

例如,使用下面的代码操作元素的property属性:d3.select('#text-id') .property('value', function(){ return d3.select(this).property('id'); //获取id属性的值 }); //设置文本的value属性为此元素的id值d3.select('#checkbox-id') .property('checked', true); //设置复选框的checked属性

效果如图1.7所示。图1.7 使用property操作符操作元素的属性

参考案例:demo/core/selection/ selection.property.html。1.1.9 selection.text([value])

返回第一个非空元素的文本内容,或设置选择集中所有元素的文本内容为指定的值。value参数可以被指定为常数或函数,如果是函数,则这个函数有两个参数:d代表当前元素已绑定的数据,i代表当前元素在元素集中的索引。在函数内部也可以使用this关键字引用当[4]前元素。文本操作符基于textContent属性。设置文本内容将取代任何现有的子元素。

例如,使用下面的代码操作元素的文本:d3.select('body').text("selection.text([value])"); //设置元素的文本d3.select('body') .text(function(){ return "new text: "+d3.select(this).text(); }); //设置元素的文本

效果如图1.8所示。图1.8 用文本操作符操作文本

参考案例:demo/core/selection/selection.text.html。1.1.10 selection.html([value])[5]

html操作符基于innerHTML属性,设置内部HTML的内容为value参数指定的值并取代任何已有的子元素。value参数可以被指定为常数或函数,如果是常数,那么所有的元素被给予相同的内部HTML内容;如果是函数,则这个函数有两个参数:d代表当前元素已绑定的数据,i代表当前元素在元素集中的索引。在value函数内部也可以使用this关键字引用当前元素。如果value参数的值为null值则会清除元素的HTML内容。如果未指定value参数,则返回在选择集中第一个非空元素的内部HTML内容。

例如,使用下面的代码操作元素的innerHTML的内容:d3.select('body').html("

大家好,我是H1!

");//设置innerHTML的内容d3.select('body') .html(function (d, i) {//用函数设置innerHTML的内容 var old = d3.select(this).html();//获取innerHTML的内容 var newHtml = old + "

大家好,我是H2!

"; return newHtml; });

效果如图1.9所示。图1.9 用html操作符操作元素的innerHTML

参考案例:demo/core/selection/selection.html.html。【小提示】selection.html仅支持HTML元素。SVG元素和其他非HTML元素不支持innerHTML属性,因此与selection.html不相容。请[6]考虑使用XMLSerializer转换DOM树为文本。1.1.11 selection.append(name)

在当前选择集的最后追加指定名称的子元素,返回的新选择集包含这个新追加的子元素。每个新元素都继承了元素集已绑定的数据。这个name参数可以被指定为一个常量字符串或一个函数,如果是函数的话,则返回追加的DOM元素。

例如,使用下面的代码添加一个矩形。//向body标签追加子元素svgvar svg = d3.select("body").append("svg");//向svg元素追加有svg命名空间的rect子元素svg.append("svg:rect");//这里省略.attr设置

效果如图1.10所示。图1.10 添加元素

参考案例:demo/core/selection/selection.append.html。1.1.12 selection.insert(name[, before])

如果指定了before参数,则在选择集中的before参数指定的元素前添加name参数指定的元素;如果未指定before参数或没有子元素匹配before参数,则直接使用selection.append的规则追加name参数指定的元素。这里,参数name和before都可以被指定为字符串或函数,使用方法同selection.append。//在svg中追加子元素rect,具体设置请参照源码svg.insert("rect");//在svg中的rect子元素前增加circle元素svg.insert("circle", "rect");//同上,但是before是一个函数svg.insert("circle", function (d, i) { return "rect"; });

效果如图1.11所示。图1.11 在矩形之前插入圆元素

参考案例:demo/core/selection/selection.insert.html。【小提示】注意:before参数不可以是用D3选择的对象,也就是说上例中before参数不可以是svg.select('rect')。1.1.13 selection.remove()

从当前文档删除选择中所有的元素,并将这些元素返回。//在上例的基础上移除circle元素var removed=d3.select("circle").remove();console.log(removed);

效果如图1.12所示。图1.12 移除圆元素,并返回

参考案例:demo/core/selection/selection.remove.html。1.1.14 selection.data([values[, key]])

给当前选定的所有元素依次绑定values数组中的数据。指定的values参数是一组数据值(例如:数字或对象)或返回一组值的函数。如果没有指定key函数,则values数组的第一个数据值被分配给选择集中的第一个元素,第二个数据值分配给选择集的第二个元素,依次类推。当数据被分配给一个元素之后,就被存储在元素的“__data__”属性中,从而使数据可以重用。

.data()操作的结果是更新选择,即选择的DOM元素已成功和数据元素绑定。enter和exit操作符也会更新选择,分别对应于添加和删除数据节点。

key函数用来控制数据是如何连接元素的,它被新数据数组中的每个数据元素调用一次,并再次被选择中的每个DOM元素调用一次。在这两种情况下的key函数都有两个入参:数据d与索引i。当key函数用于数据元素时,key函数中的this关键字代表数据数组中的当前数据;当key函数用于选择中的元素时,this关键字代表当前DOM元素。key函数基于之前绑定的数据返回一个字符串,用来连接数据和DOM元素。例如:假设每个数据都有一个唯一的字段name,则数据连接可以被指定为.data(data, function(d) { return d.name; })。

values数组也可以给选择集中的每个组指定数据,即values可以是多维数组。因此,如果选择集具有多个组(例如:d3.selectAll之后再接一个selection.selectAll),可以指定values参数为函数,返回值是一个子数组。这个函数有两个参数:d代表当前元素已绑定的数据,i代表当前元素在元素集中的索引。在函数内部用this关键字指向当前元素。

例如,可以给初始选择绑定一个二维数组,然后再给每个子选择绑定子数组。参见下例(该案例源自官方API文档:https://github.com/mbostock/d3/wiki/Selections#data)://定义一个二维数组var matrix = [ [ 11975, 5871, 8916, 2868], [ 1951, 10048, 2060, 6171], [ 8010, 16145, 8090, 8045], [ 1013, 990, 940, 6907]];var tr = d3.select("body").append("table").selectAll("tr") .data(matrix) //绑定二维数组,给表格的每行传递一个子数组 .enter() .append("tr");var td = tr.selectAll("td") .data(function(d) { return d; }) //绑定子数组,给每行的每列传递子数组中的数字 .enter() .append("td") .text(function(d) { return d; });

效果如图1.13和图1.14所示。图1.13 给表格绑定二维数组图1.14 绑定的数据存储在元素的“__data__”属性中

如果未指定values参数,则此方法返回选择中的第一组元素已绑定数据所组成的数组。返回的数组的长度,将与第一组元素的长度匹配,并且在返回的数组中的每个数据的索引将匹配选择中相应的索引。如果选择的某些元素为null,或者如果它们没有绑定过数据,则数组中的相应元素将是undefined。【小提示】注意:数据方法不能用于清除先前绑定的数据,要实现此功能可以使用selection.datum代替。//获取selection元素已绑定的数据selection.data()

绑定的数据结构如图1.15所示。图1.15 获取元素绑定的数据

参考案例:demo/core/selection/selection.data.html。1.1.15 selection.enter()

返回输入选择。也就是每个数据元素的占位节点。这个占位节点在当前DOM元素中还不存在。这个操作符只在由data操作符返回的更新选择中定义。此外,enter选择只定义了追加(append)、插入(insert)、选择(select)和调用(call)这四个可用的操作符。在修改元素内容之前必须使用这些操作符实例化输入元素。输入选择也支持empty和size操作符。

举一个简单的例子(该案例参照官方API文档https://github.com/mbostock/d3/wiki/selections#enter),请使用Chrome打开demo/core/selection/selection.enter.html,这个代码中已经使用数组创建了四个text元素,即:var data = [ "text1","text2","text3","text4"];

效果如图1.16所示。图1.16 使用数组数据创建的四个text元素

现在我们通过浏览器的控制台的交互式操作理解enter操作符,打开浏览器的控制台(按F12键),输入一个新的数组,并使用data操作符与元素绑定。var data = [ "text1","text2","text3","text4","text5"];var update_selection = d3.select("svg").selectAll('text') .data(data)

这个时候选择已经被更新了,即数据元素已经和选择中的元素绑定了,但是选择中的元素还是原来的元素,设置选择集的属性影响的是原来的元素属性,效果如图1.17所示。图1.17 操作旧有元素的属性

接下来,我们使用enter操作符给新加入的元素返回一个占位节点,效果如图1.18所示。图1.18 使用enter操作符得到新元素的占位节点

通过这个占位节点可以使用append操作符追加新的元素,并设置这个元素的属性,效果如图1.19所示。update_selection.enter().append("text").attr({ x: '20', y: function (d, i) { return 20 + 20 * i; }, fill:"green" }).text(function (d, i) { return d; });

追加元素之后,选择集就多了一个元素,这个时候可以给所有的元素统一设置属性,效果如图1.20所示。update_selection.attr("fill","orange")图1.19 追加新元素,并设置新元素的属性图1.20 设置旧有元素和新加元素的属性1.1.16 selection.exit()

返回需要移除的元素选择。执行后元素在当前选择中不存在,但是在当前DOM文档中存在。此方法只在由data操作符返回的更新选择中定义。exit选择定义了所有的正常操作符,但通常使用的是.remove()方法;其他操作符存在的主要目的是可以根据需要定义一个退出的过渡动画。需要注意的是,exit操作符只是返回一个退出选择的引用,需要手动调用.remove()方法来删除选择的节点。

例如(该案例参照官方API文档:https://github.com/mbostock/d3/wiki/Selections#exit)我们先生成六个div标签,内容是1, 2, 3, 4, 5, 6,效果如图1.21所示。d3.select("body").selectAll("div") .data([1, 2, 3, 4, 5, 6]) .enter() .append("div") .text(function(d) { return d; });图1.21 用数组[1, 2, 3, 4, 5, 6]生成六个div标签

接下来,更新绑定的数组,并用新数组生成div标签,效果如图1.22所示。var divs=d3.select("body").selectAll("div") .data([7, 8, 9, 4, 5, 6], function(d) { return d; })divs.enter() .append("div") .text(function(d) { return d; });

然后,将第一个数组中退出数据对应的元素删除,现在,元素body下的子元素就如图1.23所示。divs.exit().remove()图1.22 用新数组[7, 图1.23 删除退出的元素8, 9, 4, 5, 6]追加新增div标签

参考案例:demo/core/selection/selection.exit.html。1.1.17 selection.filter(selector)

过滤选择,返回一个新的选择只包含参数selector是true的元素。selector可以是一个函数或选择字符串。和其他操作符一样,函数有两个参数:d代表当前元素已绑定的数据,i代表当前元素在元素集中的索引。在函数内部可以使用this关键字引用当前元素。过滤器只能被绑定了DOM元素的选择调用,例如:由append或insert返回的选择。如果只需要将元素和数据的子集绑定,可以在data操作符中调用数组的内置数组过滤器。D3的过滤器在返回选择中不会保留原来选择的索引,它只返回移除元素的副本;如果需要保留索引,请用.select()函数。

例如,选出索引为偶数的text,并设置其文本填充色为宝蓝色,效果如图1.24所示。svg.selectAll('text').filter(function(d, i) { return i % 2 == 0;//i从0开始}).style("fill", "royalblue");图1.24 使用过滤器设置文本的颜色

参考案例:demo/core/selection/selection.filter.html。1.1.18 selection.datum([value])

获取或设置每个选定的元素绑定的数据。与selection.data方法不同的是,这个方法不计算连接(join),因此不能使用enter和exit来选择。

如果指定了value参数,则设置元素的绑定数据为指定的value值。如果value是一个常数,则所有的元素被赋予相同的数据;如果value是一个函数,那么这个函数会为每个选中的元素(按顺序)计算属性值。value函数有两个参数:d代表当前元素已绑定的数据,i代表当前元素在元素集中的索引。在value函数内部可以使用this关键字引用当前元素。这个函数需要有返回值来设置当前元素要绑定的数据值。如果value值为null,则移除绑定的数据。该操作符对索引没有影响。

如果没有指定value参数,则返回第一个非空元素绑定的数据值。

.datum()方法可用来访问HTML5自定义数据属性。例如(该案例参照官方API文档:https://github.com/mbostock/d3/wiki/Selections#datum),给定下列元素:

使用下面的方法就可以取得元素的内含数据,并用来设置元素的其他属性,效果如图1.25所示。d3.selectAll("div").datum(function() { return this.dataset; }) //获取HTML5自定义数据属性.text(function(d){ return d.username;}); //使用获取的数据设置文本的值图1.25 使用datum操作符获取或设置元素的数据

参考案例:demo/core/selection/selection.datum.html。1.1.19 selection.sort(comparator)

用指定的比较函数对当前选择的元素排序,默认为d3.ascending(升序排序)。比较器函数是通过传入两个数据元素(如a和b)进行比较的。若返回值为负,则a应该在b之前;如果为正,则a应该在b之后;否则a和b被认为是相等的。需要注意的是,这种排序不能保证是稳定的。但是,可以保证与浏览器内置的数组排序方法具有相同的行为。

例如,按照绑定数据的value属性进行升序排序,效果如图1.26所示。svg.selectAll('text').sort(function (a, b) { return a.value–b.value;});图1.26 对当前选择的元素排序前和排序后对比

参考案例:demo/core/selection/selection.sort.html。1.1.20 selection.on(type[, listener[, capture]])

给当前选择的每个元素,绑定或移除指定类型的事件监听器。type是一个字符串类型的事件名称,如:“click”、“mouseover”和“submit”等任何支持的DOM事件。指定的listener是一个函数,有两个入参:d代表当前元素已绑定的数据,i代表当前元素在元素集中的索引。在函数内部可以使用this关键字引用当前DOM元素。使用全局事件对象d3.event可以在监听器内访问当前事件,事件监听器的返回值将被忽略。

如果元素已绑定了相同类型的事件监听器,则先移除现有监听器再添加新的监听器。如果要为相同类型的事件注册多个监听器,类型后跟一个可选的命名空间,如“click.foo”和“click.bar”。

当listener值为null时可以删除一个监听器。要删除特定事件类型的所有监听器,可以使用这样形式的事件名称:selection.on(".foo", null)。[7]

可选参数capture对应于W3C的useCapture标志,事件是沿着树向上冒泡的。

如果未指定监听器,仅仅指定类型,则返回当前分配的监听器(如果有的话)。

例如,下面的例子演示了单击按钮更改文本内容,效果如图1.27所示。d3.select("button").on("click",function(){ d3.select('svg').selectAll('text') .text(function (d, i) { return "new:"+d*3; });});图1.27 单击按钮更改文本内容

参考案例:demo/core/selection/selection.on.html。1.1.21 d3.event

存储当前事件(如果有的话)的全局对象。这个全局对象是通过on操作符在事件监听器回调中注册的。当监听器在finally块被通知后当前事件便被重置。监听器函数与其他操作符函数具有相同的形式,入参有:当前数据d和索引i。

d3.event对象是一个DOM事件,并实现了标准事件字段,比如:时间戳(timeStamp)、键代码(keyCode),以及preventDefault()方法和stopPropagation()方法。当然也可以使用原生事件的pageX和pageY属性,它们往往更方便将事件位置转变为接收该事件容器的局部坐标系中的坐标。例如,如果在网页中嵌入SVG,可能希望得到相对于SVG图像原点的事件位置。如果SVG包含变换,也可能需要知道事件相对于那些变换的位置。特别地,d3.mouse操作符用于标准鼠标事件中,d3.touches用在iOS多点触控事件中。

下面比较了用d3.mouse和d3.event捕获当前鼠标位置相对于父容器(这里是body元素)的偏移坐标,如图1.28所示。var pos1 = "d3.mouse pos:"+d3.mouse(d3.select("body")[0][0]);//取得鼠标位置相对于body元素的偏移坐标var pos2 = "d3.event pos:"+d3.event.offsetX+","+d3.event.offsetY;//取得鼠标悬浮事件的偏移坐标图1.28 比较d3.mouse和d3.event的坐标

参考案例:demo/core/selection/d3.event.html。1.1.22 d3.mouse(container)

返回当前d3.event相对于指定容器container的x和y坐标。该容器可以是一个HTML或SVG容器元素,如:svg:g或svg:svg。返回的坐标是一个包含两个元素的数组[x, y]。

参考上例。1.1.23 selection.transition()

为当前选择集开启一段过渡动画。过渡的行为和选择类似,只是属性的变化会更平滑地随时间推移,而不是瞬间完成。

例如,为选中的圆元素开启动画,将颜色由橘黄色过渡为蓝色,效果如图1.29所示。d3.select('svg').append('circle') .attr({ cx: 100, cy: 100, r: 40, fill: 'orange' });//开启动画,并设置动画结束时填充色为blued3.select('svg').select('circle')

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载