[svg] D3.js
选择元素
D3提供了两种高级方法来选择元素:select和selectAll。
这些方法接收选择器字符串。
前者只返回第一个匹配的元素,
后者选择在文档遍历次序中所有匹配的元素。
这个方法也可以接受节点,
这可以用来和第三方库例如JQuery或者开发工具($0)整合。
d3.select(selector)
选中与指定选择器字符串匹配的第一个元素,
返回单元素选择结果。如果当前文档中没有匹配的元素则返回空的选择。
如果有多个元素被选中,只有第一个匹配的元素(在文档遍历次序中)被选中。
d3.select(node)
选择指定的节点。如果你已经有一个节点的引用这将是很有用的。
例如事件监听器中的d3.select(this) 或者一个全局对象例如document.body。
这个函数不会遍历DOM树。
d3.selectAll(selector)
选中匹配指定选择器的所有的元素。
这些元素会按照文档的遍历顺序(从上到下)选择。
如果当前文档中没有匹配的元素则返回空的选择。
d3.selectAll(nodes)
选择指定的元素数组。
如果你已经有了一些元素的引用这将是很有用的,
例如事件监听器中的d3.selectAll(this.childNodes),
或者一个全局对象例如document.links。
节点的参数不用恰好是数组;
任何可以转化为一个数组的伪数组(例一个NodeList或者 arguments)都可以,
这个函数不会遍历DOM树。
内容
selection.attr(name[, value])
如果指定了value参数,将为所有选中的元素通过指定的name为指定的value设置属性。
如果value是一个常数,那么所有的元素都将设置为相同的属性值;
如果value是一个函数,那么这个函数会为每个选中的元素(按顺序)计算。
入参是当前数据元素d和当前索引i,以及代表当前DOM元素的this上下文。
这个函数的返回值接下来用来设置每个元素的属性。null值将移除指定的属性。
如果value参数没有指定,就会返回为选择中第一个非空(null)元素所指定的属性值。
一般来说,只有当你知道选择中恰好包含一个元素时才有用。
指定的name参数也会含有一个前缀,例如xlink:href是用来指定Xlink命名空间中href属性的。
默认情况下,D3支持svg、xhtml、xlink、xml和 xmlns命名空间。
可以添加d3.ns.prefix来注册其他的命名空间。
name也可以是一个name和value属性对象。
selection.append(name)
在当前选择的每个元素最后追加具有指定名称的新元素,
返回包含追加元素的新选择。
每个新的元素继承当前元素的数据(如果有的话)和select相同的方式使用子选择。
这个name可以被指定为一个常量字符串或一个函数,返回追加的DOM元素。
当name被指定为一个字符串,它可能有以下形式的命名空间前缀“namespace:tag”。
例如,“svg:text”将在svg命名空间创建“text”元素。
默认情况下,D3支持svg,xhtml,xlink的,xml和xmlns命名空间。
其他的命名空间可以通过添加到d3.ns.prefix注册。
如果没有指定命名空间,那么命名空间会从封闭的元素继承;
或者,如果该名称是已知的前缀之一,相应的命名空间将被使用(例如,“svg”表示“svg:svg”)。
selection.text([value])
文本操作符是基于textContent属性;设置文本内容将取代任何现有的子元素。
如果指定了value时,设置所有选择元素的文本内容为指定的值。
如果value是一个常数,那么所有的元素被赋予相同的文本内容;
如果value是一个函数,则该函数被每个选定的元素(按顺序)计算,
入参是当前数据元素d和当前索引i,以及代表当前DOM元素的this上下文。
该函数的返回值被用于设置每个元素的文本内容。null值会清除内容。
如果未指定value,则返回在选择中第一个非空元素的文本内容。
只有当你知道选择只包含一个元素时这通常是很有用的。
selection.html([value])
html的操作基于innerHTML属性;
设置内部HTML内容将取代任何现有的子元素。
此外,使用数据驱动的方式append或insert操作创建HTML内容;
该操作符的目的是,适用于想用少量但有丰富格式的HTML。
如果指定了value,为所有选择的元素设置在内部的HTML内容为指定的值。
如果value是一个常数,那么所有的元素被给予相同的内部HTML内容;
如果value是一个函数,则该函数为每个选定的元素(按顺序)计算,
入参是当前数据元素d和当前索引i,以及代表当前DOM元素的this上下文。
该函数的返回值被用于设置每个单元的内部的HTML内容。
null值会清除内容。
如果未指定value,则返回在选择中第一个非空元素的内部HTML内容。
只有知道选择只包含一个元素时这通常是很有用的。
注:正如它的名字所暗示的,selection.html仅支持HTML元素。
SVG元素和其它非HTML元素不支持innerHTML属性,因此与selection.html不相容。
请考虑使用XMLSerializer转换DOM树为文本。
selection.classed(name[, value])
这个操作是用来设置class属性值得便捷程序。
它能识别class属性是一个按照空格分隔的标记集合。
这样它就能使用classList(如果有的话)来方便地添加、移除和切换CSS类。
如果value属性被指定,不论是否指定类都会与选定元素相结合。
如果value是一个常量且其值为真true,那么所有的元素都会被分配指定的类(还没分配的话)。
如果其值为假false,那么就会移除选中元素的class(已经分配过)。
如果value是一个函数,那么这个函数会为每个选中的元素(按顺序)计算。
入参是当前数据元素d和当前索引i,以及代表当前DOM元素的this上下文。
这个函数的返回值接下来用来分配或者不分配每个元素的class。
如果想一次设置多个class可以使用一个对象,
文字如同:selection.classed({'foo': true, 'bar': false})
,
或者使用以空格分隔的class列表形如:selection.classed('foo bar', true)
。
如果value没有被指定,当且仅当选择中首个非空值有指定的class就会返回true。
一般来说,只有当你知道选择中恰好包含一个元素时才有用。
可以用 .attr('class','xx')
替代。
selection.style(name[, value[, priority]])
如果value参数被指定,通过指定名称和指定的值为所有选中的元素设置CSS样式属性。
如果value是一个常数,那么所有的元素都设置相同的样式值;
否则,如果值是一个函数,则该函数为每个选定的元件(按顺序)计算,
入参是当前数据元素d和当前索引i,以及代表当前DOM元素的this上下文。
该函数的返回值被用来设置每个元素的样式属性。
null值将删除样式属性。
可选参数priority也可以指定,无论是null空或字符串“important”(不带感叹号)。
如果你想一次设置多个样式属性,使用对象文本,如下所示:
selection.style({'stroke': 'black', 'stroke-width': 2})
如果未指定值,则返回在选择中的第一个非空元素指定样式属性的当前计算值。
只有当你知道选择只包含一个元素时是很有用的。
需要注意的是计算的值可能与先前设置的值不同,
尤其是当样式属性使用了简写属性(如“font”样式,这是简写为"font-size","font-face",“等)。
selection.property(name[, value])
一些HTML元素具有特殊的属性使用标准的属性或样式是不可寻址的。
例如,表单文本(text)字段有一个value字符串属性,
复选框(checkboxes)有一个checked布尔型属性。
可以使用property操作符来获取或设置这些属性,
或任何其他基本元素的可寻址字段,例如className。
如果指定了value,就为所有选中的元素指定名称的属性设置指定的值(value)。
如果值是一个常数,那么所有的元素被给予相同的属性值;
如果value是一个函数,则该函数为每个选定的元素(按顺序)计算,
入参是当前数据元素d和当前索引i,以及代表当前DOM元素的this上下文。
该函数的返回值被用于设置每个元素的属性。空值将删除指定的属性。
如果你想一次设置多个属性,可以使用对象文本,如下所示:
selection.property({'foo': 'bar', 'baz': 'qux'})。
如果未指定值,则返回在选择中第一个非空元素指定属性的值。
选择只包含一个元素时通常是很有用的。
selection.remove()
删除从当前文档当前选择中的元素。
返回“屏幕外(off-screen)”的当前选择(除去了相同的元素),从DOM分离。
需要注意的是目前还没有一个专门的API来重新添加删除的元素到文档;
然而可以通过一个函数来selection.append或selection.insert重新添加元素。
selection.node()
返回当前选择的第一个非空的元素。如果选择为空,则返回null。
动画和交互
selection.transition([name])
开始为当前选择的过渡。
转换的行为很像选择,除了操作符动画平滑的随着时间的推移,而不是瞬间完成。
d3.event
存储当前的事件(如果有的话)。
这个全局函数是在事件侦听器回调过程中使用on操作符注册的。
当监听器在finally块被通知后当前事件被重置。
这使侦听器函数与其他操作符函数具有相同的形式,传递当前数据d和索引i。
d3.event对象是DOM事件,并实现了标准事件字段,
像时间戳timeStamp和键代码keyCode,
以及 preventDefault()
方法和的 stopPropagation()
方法。
当然你可以使用原生事件的pageX and pageY,它往往更方便转变事件位置为接收该事件容器的局部坐标系。
例如,如果你在网页的正常流程嵌入SVG,你可能想事件的位置是相对于SVG图像的左上角的。
如果SVG包含转换,你也可能想知道事件的相对于那些变换的位置。
标准鼠标指针使用d3.mouse运算符,d3.touches用在iOS多点触控事件上。
d3.mouse(container)
返回当前d3.event相对于指定的容器的x和y坐标。
该容器可以是一个HTML或SVG容器元素,如svg:g或svg:svg。
该坐标返回为一个包含两个元素的数组[x, y]。
d3.touch(container[, touches], identifier)
返回指定标识符触摸当前d3.event相应的x和y坐标,相对于指定容器。
如果未指定touches时,默认为当前事件的changedTouches。
该容器可以是一个HTML或SVG容器元件,如一个的svg:g或svg:svg。
坐标被返回为两元素数组的数组[ [ x1, y1], [ x2, y2], … ]。
如果在指定的标识符touches没有接触,则返回null;
这对于忽略touchmove那些只是touches移动了的事件是很有用的。
d3.touches(container[, touches])
返回与当前d3.event相关联的每个触摸x和y坐标,基于touches属性,相对于指定的容器中。
该容器可以是一个HTML或SVG容器元素,如svg:g 或 svg:svg。
坐标返回两个元素的数组的数组[ [ x1, y1], [ x2, y2], … ]。
如果指定了触摸,返回指定触摸的位置,如果没有指定touches时,
则默认为当前事件的touches属性。
控制
selection.each(function)
为当前选择的每个元素,调用指定的函数,传递当前数据d和索引i,
与当前的DOM元素的this上下文。这个操作符几乎被所有的其他操作符内部使用,
并可以用于调用任意代码为每个选定的元素。each操作符可以用来处理递归的选择,
通过在回调函数内使用d3.select(this)。
selection.call(function[, arguments…])
调用指定的函数一次,通过在当前的选择以及任何可选参数。无
论指定函数的返回值是什么,call操作符总是返回当前的选择。
通过call调用函数与手动调用函数是完全一样的;
但它可以更容易地使用方法链。
例如,假设我们要在许多不同的地方以同样的方式设置一些属性。
我们采取的代码,把它包在一个可重复使用的功能:
function foo(selection) {
selection
.attr("name1", "value1")
.attr("name2", "value2");
}
现在我们可以这样写:
foo(d3.selectAll("div"));
或者等价的方式:
d3.selectAll("div").call(foo);
被调用函数的this上下文也是当前的选择。
第一个参数是略显多余的,这我们可能在未来解决。
如果使用的selection.call的对象,方法和需要this指向该对象创建之前调用绑定到对象的函数。
function Foo(text) {
this.text = text;
}
Foo.prototype.setText = function(selection) {
selection.text(this.text);
}
var bar = new Foo("Bar");
d3.selectAll("span").call(bar.setText.bind(bar));
// Or
d3.selectAll("span").call(Foo.prototype.setText.bind(bar));
数据
selection.data([values[, key]])
连接指定的一组数据的和当前选择。
指定的values是一组数据值(例如,数字或对象)或一个函数返回一组值。
如果没有指定key函数,则values的第一数据被分配到当前选择中第一元素,
第二数据分配给当前选择的第二个元素,依此类推。当数据被分配给一个元素,
它被存储在属性__data__中,从而使数据“沾粘”,从而使数据可以再选择。
data操作的结果是update选择;这表示选择的DOM元素已成功绑定到指定的数据元素。
update选择还包含对enter和exit的选择,对应于添加和删除数据节点。
有关详细信息,请参阅简短的教程关于连接的思考
key函数可以被指定为控制数据是如何连接元素。
这取代默认的by-index行为;
key函数被新数据数组中的每个元素调用一次,并再次用于选择中的每个元素。
在这两种情况下的key函数是通过传递数据d与索引i。
当key 函数上被新的数据元素评价时,this上下文是数据数组;
当key 函数被现有选择评估时,this上下文是相关的DOM元素。
key函数,基于先前结合的数据返回一个用于连接数据和相关的元素的字符串。
例如,如果每个数据都有一个唯一的字段name,
该连接可以被指定为 .data(data, function(d) { return d.name; })
。
如果指定了key函数,data操作符也影响节点的索引;
该索引被作为第二个参数i作为任何运算符函数的参数。
然而,请注意,现有的DOM元素不自动重新排序;
根据需要使用sort或order函数。
这个values选择中的每组数据。
因此,如果选择具有多个组(例如,一个d3.selectAll后跟一个selection.selectAll)),
然后data应该被指定为一个函数,该函数返回一个数组(假设你对每个组想要不同的数据)。
该函数将被传递的当前组数据(或undefined)和索引,组的this上下文。
例如,可以将一个二维数组和初始选择绑定,然后将包含的内部数组和每个子选择绑定。
在这种情况下,values函数是标识函数:它被每个组中的子元素调用,
被传递绑定到父元素的数据,并且返回这个数据数组。
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; });
如果未指定values,则此方法返回选择中的第一组数据的数组。
返回的数组的长度,将与第一组的长度匹配,
并且在返回的数组中的每个数据的索引将匹配选择中相应的索引。
如果选择的某些元素为null,或者如果他们有没有相关的数据,
则数组中的相应元素将是undefined。
注意:data方法不能用于清除先前结合数据;可以使用selection.datum代替。
selection.datum([value])
获取或设置每个选定的元素绑定的数据。
不像selection.data方法,这种方法不计算一个连接(并因此不计算enter和exit的选择)。
此方法在selection.property之上实现:
d3.selection.prototype.datum = function(value) {
return arguments.length < 1
? this.property("__data__")
: this.property("__data__", value);
};
如果指定value,就为所有选中的元素设置元素的绑定数据为指定的值。
如果value是一个常数,所有的元素被给予相同的数据;
否则,如果value是一个函数,则该函数为每个选定的元素计算,
被传递以前的数据d与当前索引i,使用this上下文作为当前的DOM元素。
该函数之后被用来确定每个元素的数据。
null值将删除绑定的数据。
该操作数对索引没有影响。
如果未指定value,则返回在选择中绑定第一个非空的元素的数据。
只有当你知道选择只包含一个元素这通常是很有用的。
注意:此方法是以前所谓的“map”。旧名已被弃用。
datum 方法用D3访问HTML5自定义数据属性非常有用。例如,给定下列元素:
<ul id="list">
<li data-username="shawnbot">Shawn Allen</li>
<li data-username="mbostock">Mike Bostock</li>
</ul>
可以公开通过设置每个元素的数据作为内置的dataset属性自定义数据属性D3:
selection.datum(function() { return this.dataset; })
selection.enter()
返回输入(enter)选择:当前选择中存在但是当前DOM元素中还不存在的每个数据元素的占位符节点。此方法只在由data运算符返回的更新选择中定义。此外,输入选择只定义了append(append),insert(insert),select(select)和call(call)操作符;您必须使用这些操作符在修改任何内容之前实例化输入元素。当你传递函数的参数给这些插入的元素的操作符时,index参数将反映新的位置,而不一定从零开始或者是连续的。 (输入选择也支持empty和size。)
举一个简单的例子,考虑现有的选择是空的情况下,我们希望创建新的节点来匹配我们的数据:
d3.select("body").selectAll("div")
.data([4, 8, 15, 16, 23, 42])
.enter().append("div")
.text(function(d) { return d; });
假设body最初是空的,上面的代码将创建六个新的div元素,
将它们按顺序追加到body,并指定其文本内容为相应的(强制转为字符串)号码:
<div>4</div>
<div>8</div>
<div>15</div>
<div>16</div>
<div>23</div>
<div>42</div>
另一种方式考虑进入的占位符的节点是,
它们是指向父节点(在该示例中,就是文档的body);然而,他们只支持追加和插入。
当你追加或插入时输入选择并入到更新选择。
而不是对enter和update选择单独采用同样的操作符,现在你可以一次添加节点后,将其应用到更新选择。
如果你发现自己移除整个选择的元素才重新插入其中大部分,用这个来替代。例如:
var update_sel = svg.selectAll("circle").data(data)
update_sel.attr(/* operate on old elements only */)
update_sel.enter().append("circle").attr(/* operate on new elements only */)
update_sel.attr(/* operate on old and new elements */)
update_sel.exit().remove() /* complete the enter-update-exit pattern */
selection.exit()
返回退出(exit)选择:找出在当前选择存在的DOM元素中没有新的数据元素时。
此方法只被定义在data运算符返回的更新选择。
exit选择定义了所有的正常操作符,但通常你主要使用的是remove;
其他操作符存在的主要目的是让您可以根据需要定义一个退出的过渡。
请注意,exit操作符只是返回一个exit选择引用,由你来删除新节点。
一个简单的例子,考虑更新在上面的例子中的enter操作符创建的六个DIV元素。
在这里,我们把这些元素和一个含有一些新的,一些旧数据的新数组绑定:
var div = d3.select("body").selectAll("div")
.data([1, 2, 4, 8, 16, 32], function(d) { return d; });
现在div--data操作符的结果--指的是更新的选择。
因为我们指定的key函数使用标识函数,并且将新数据数组包含数字[4,8,16],
它也存在旧的数据数组中,这个更新选择包含3 个DIV元素。
比方说,我们离开这些元素原样。我们可以实例化并使用enter选择添加新的元素
[1,2,32]:
div.enter().append("div")
.text(function(d) { return d; });
同样,我们可以删除退出的元素[15, 23, 42]:
div.exit().remove();
现在,文档body如下:
<div>4</div>
<div>8</div>
<div>16</div>
<div>1</div>
<div>2</div>
<div>32</div>
注意,DOM元素现在是乱序。然而,选择索引i(操作函数的第二个参数),
将正确地与新数据数组相匹配。例如,我们可以指定一个索引属性:
d3.selectAll("div").attr("index", function(d, i) { return i; });
结果是:
<div index="2">4</div>
<div index="3">8</div>
<div index="4">16</div>
<div index="0">1</div>
<div index="1">2</div>
<div index="5">32</div>
如果你想在文档遍历,以匹配选择数据顺序,可以使用sort或者order。
selection.filter(selector)
过滤选择,返回一个新的选择只包含其指定的selector是true的元素。
selector可以被指定为一个函数或作为选择的字符串,如“.foo”。
和其他操作符一样,该函数被传递当前数据d和索引i,以及this上下文作为当前的DOM元素。
过滤器应该只在选择与DOM元素绑定的时候。
例如:从append或insert。
只绑定的元素和数据的一个子集,可以在data参数中调用内置的数组过滤器filter。
像内置函数一样,D3的过滤器不会在返回选择中保留原来的选择的索引;
返回移除元素的副本。如果您想保留的索引,使用select代替。
例如,要选择奇数索引(相对于从零开始的索引)的每一个元素:
var odds = selection.select(function(d, i) { return i & 1 ? this : null; });
等价地,使用的过滤器函数:
var odds = selection.filter(function(d, i) { return i & 1; });
或过滤选择器(注意:nth-child伪类是一开始的索引,而不是从零开始的索引):
var odds = selection.filter(":nth-child(even)");
selection.sort([comparator])
根据指定的comparator函数对当前选择的元素排序。
比较器函数默认为d3.ascending,通过传递两个数据元素a和b进行比较,
并返回任一负的,正的,或零值。
如果为负,则a应该在b之前;如果为正,则a应该为b后;
否则a和b被认为是相等的顺序是任意的。
需要注意的是,这种排序是不保证是稳定的;
然而,它保证与浏览器内置的数组排序方法具有相同的行为。
数组
d3.range([start, ]stop[, step])
生成一个包含算数级数的数组,类似于Python的内置函数range。
这个方法常用来遍历一个数字序列或者整型数值。
例如数组中的索引。
不同于Python版本,这个参数不必是整形。
尽管如果它们是浮点精度类型时这个结果更加可预测。
如果省略step,默认值是1。
如果省略start参数,默认值就是0。
结果中不包含stop值。
完整的形式是返回一个数字数组[start,start+step,start+2 step,…]。
如果step是正的,则最后一个元素是小于stop的start+ istep中的最大数值;
如果step是负的,最后一个元素是大于stop的start + i*step中的最小数值。
如果返回的数组将包含值无限多数字,就会抛出一个错误,而不是造成无限循环。
//就是制造一个步长的数组
d3.ascending(a, b)
升序
如果a < b返回-1,a > b返回1,a = b返回0。
这是固有的比较器方法,也可用于关联内置数组排序的方法来给元素升序排序:
function ascending(a, b) {
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}
如果没有给数组的内置排序方法没有指定比较器函数,那默认的排序是字典排序(按字母顺序排序),
而非自然排列!
所以当以数组的数字来排序时会导致bug。
d3.descending(a, b)
降序
如果a > b返回-1,a < b返回1,a = b返回0。
这是固有的比较器方法,也可用于关联内置数组排序的方法来给元素降序排序:
function descending(a, b) {
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}
如果没有给数组的内置排序方法没有指定比较器函数,那默认的排序是字典排序(按字母顺序排序),
而非自然排列!
所以当以数组的数字来排序时会导致bug。
d3.min(array[, accessor])
返回给定数组(array)中自然排序最小的值。
如果数组为空,返回undefined。
如果指定了accessor 参数,等同与在计算最小值之前调用了array.map(accessor)方法。
不同于内置的Math.min,这个方法会忽略未定义的值;
这对比例尺(d3.scale)定义域计算很有用处,当只考虑数据的定义区域。
另外,元素的比较用的是自然排序而不是数字排序。
例如,["20","3"]的最小值是20,然而[20,3]的最小值是3。
d3.max(array[, accessor])
返回给定数组(array)中自然排序最大的值。
如果数组为空,返回undefined。
如果指定了accessor 参数,等同与在计算最大值之前调用了array.map(accessor)方法。
而并非内置的Math.max,这个方法会忽略未定义的值;
这对当只需要定义数据的区域的比例尺定义域计算很有用处。
另外,元素的比较用的是自然排序而不是数字排序。
例如,["20","3"]的最大值是3,然而[20,3]的最大值是20。
d3.extent(array[, accessor])
返回给定数组(array)自然排序的最小值和最大值,等同于同时调用d3.min和d3.max.
d3.sum(array[, accessor])
返回给定数组(array)的和。
如果数组为空,返回 0。
可选参数accessor函数 被指定,等同于在计算和之前调用array.map(accessor) 。
此方法忽略无效值(如NaN 和undefined);
当只考虑明确定义的值时,这个方法可用于计算数据的和。
d3.mean(array[, accessor])
返回给定数组(array)的平均数。
如果数组为空,返回 undefined。
可选参数accessor函数 被指定,等同在计算平均数之前调用array.map(accessor) 。
此方法忽略无效值(如NaN 和undefined),当只考虑明确定义的值时这个方法计算数据和是很有用的。
d3.median(array[, accessor])
返回给定数组(array)以R-7算法得出的中位数。
如果数组为空,返回 undefined。
可选参数accessor 被指定,等同在计算中位数之前调用array.map(accessor) 。
此方法忽略无效值(如NaN 和undefined) ,当只考虑明确定义的值时这个方法计算数据和是很有用的。
d3.quantile(numbers, p)
返回给定数组numbers的p分位数,其中p 是一个0到1范围的数。
例如,中位数可以由p = 0.5计算,第一个四分位数是p = 0.25,
第三个四分位数是p = 0.75。
这个特别实现了R-7算法,这是R编程语言和Excel默认的方式。
这个方法需要数组numbers包含数字且数字升序顺序排列,例如使用 d3.ascending排序。
var a = [0, 1, 3];
d3.quantile(a, 0); // return 0
d3.quantile(a, 0.5); // return 1
d3.quantile(a, 1); // return 3
d3.quantile(a, 0.25); // return 0.5
d3.quantile(a, 0.75); // return 2
d3.quantile(a, 0.1); // return 0.19999999999999996
d3.bisectLeft(array, x[, lo[, hi]])
定位数组 array 中的 x 的插入点,以保持已有序列。
参数 lo 和 hi 用来指定数组的子集;默认情况下整个数组都被使用。
如果 x 在 array 中已存在,插入点在所有元素之前(左侧)。
返回值适合用作拼接(splice)已经排序的数组array 的第一个参数。
返回的插入点i把array 分为两个区:
数组中所有array.slice(lo, i)中v < x 的v在左边,
数组中所有 array.slice(i, hi)中v >= x 的v在右边。
d3.bisectRight(array, x[, lo[, hi]])
和bisectLeft类似,但返回插入点来自于数组array中任意实体x之后(右侧)。
返回的插入点i把array 分为两个区:
数组中所有array.slice(lo, i)中v <= x的v在左边,
数组中所有 array.slice(i, hi)中v > x 的v在右边。
scale
scale 是函数。
序数比例尺
序数比例尺的输入域是离散的,比如:一组名称或类别。
d3.scale.ordinal()
构造一个新的序数比例尺,使用空的输入域和输出范围。
如果序数比例尺没有指定输出范围,取值时总会返回 undefined 。
ordinal(x)
传入一个输入域中的值 x,返回对应输出范围中的值。
如果输出范围已指定(比如通过 range指定,
但是不是通过 rangeBands、rangeRoundBands 或 rangePoints 来指定的),
并且入参 x 的值不在输入域中,那么 x 就会被隐含地添加进到输入域中;
这之后,当使用相同的值 x 再次调用该函数时就会返回输出范围中相同的值 y。
d3.scale.category10()
构造一个新的序数比例尺,使用10种类型的颜色。
d3.scale.category20()
构造一个新的序数比例尺,使用20种类型的颜色。
d3.scale.category20b()
构造一个新的序数比例尺,使用另20种类型的颜色。
d3.scale.category20c()
构造一个新的序数比例尺,使用另另20种类型的颜色。
数值比例尺
d3.scale
比例尺 是将定义域映射为值域的函数 数值比例尺 有连续的定义域,例如一系列数字或时间。
d3.scale.linear()
线性比例尺是最常见的比例尺,为连续地把输入域映射到连续的输出范围提供了良好的缺省选择。
该映射是线性的,输出范围值y可以表示为输入域值x的线性函数为:
y = mx + b
。
用默认域[0,1]构造一个新的比例尺,默认的范围为[0,1]。
因此,默认比例尺相当于数字恒等函数;例如linear(0.5)返回0.5。
linear.domain([numbers])
设置输入范围
如果数字numbers被指定,设置比例尺的输入域到数字的指定数组。
数组必须包含两个或两个以上的数字。
如果给定的数组中的元素不是数字,他们将被强制转换为数字;
这种强迫发生同样,当规模被调用。
因此,线性标尺可用于类型,如日期的对象(date objects)可以被转换成数字编码;
但是,它通常是用d3.time.scale的日期更方便。
(您可以使用的valueOf实现自己的转换数量的对象。)
如果未指定数字,则返回比例尺的输入域。
虽然线性标度通常只有两个数值在其域中,可以用polylinear比例尺指定两个以上的值。
在这种情况下,必须有值的输出范围内的当量数。
一个polylinear刻度表示多个分段线性尺度上划分一个连续的定义域和值域。
这是用于定义发散的定量尺度是特别有用的。
例如,把白色和红色作为负值,白色和绿色作为正值:
var color = d3.scale.linear()
.domain([-1, 0, 1])
.range(["red", "white", "green"]);
所得到的值的颜色( - 0.5)是RGB(255,128,128)和色彩(0.5)的值是RGB(128,192,128)。
在内部,polylinear比例尺通过二分查找对应于给定域值输出插值。
通过重复在这两个领域和范围值,你也可以强制输入域的块映射到一个固定的输出范围。
linear.range([values])
设置输出范围
//通过颠倒range,可实现图像颠倒
如果值被指定,设置刻度的输出范围值的指定数组。
数组必须包含两个或多个值,以匹配输入域的基数,否则第二个的长被截断以匹配另一个。
给定的数组中的元素不必是数字;
所支持的底层的内插器(interpolator)的任何值都可以。
然而,数值范围是必需的倒置运算符。
如果未指定values的值,则返回当前比例次的输出范围。
d3.svg.line()
构造一个新的线生成器使用默认的x和y访问器函数(假设输入数据是一个两元素数字数组),和线性插值器。
返回的函数生成路径数组为开口分段线性曲线,折线
通过改变插值器,可以生成样条线以及步长函数。
另外,可以最后粘上其他路径命令。
例如,如果想生成一个封闭的路径,追加closepath (Z)命令:
g.append("path")
.attr("d", function(d) { return line(d) + "Z"; });
线生成器设计来和面积生成器(area)一起使用。
例如,当生成面积图时,你可能使用带有填充属性的面积生成器,
以及带有描边属性的线生成器来突出面积的上边缘。
当线生成器只是用来设置d属性,
可以使用SVG样式和属性控制线的展示,
例如fill,stroke和stroke-width。
line(data)
为指定的data元素数组返回路径数据字符串,如果路径是空则返回null。
line.x([x])
如果指定了x,为指定的函数或常量设置x访问器。
如果x没有指定,返回当前的x访问器。
这个访问器为传递给x线生成器的数据数组中的每个元素。
默认的访问器假设每个输入的元素是一个二元素数字数组:
function x(d) {
return d[0];
}
通常,一个x访问器是指定的,因为输入数据是不同格式的,
或者因为想使用比例尺(数值比例尺)。
例如,如果数据指定为一个含有x,y属性的的对象,
而不是一个元组,可以反引用这些属性同时应用比例尺:
var x = d3.scale.linear().range([0, w]),
y = d3.scale.linear().range([h, 0]);
var line = d3.svg.line()
.x(function(d) { return x(d.x); })
.y(function(d) { return y(d.y); });
x访问器像D3中其他值函数一样的方式调用。
函数的this上下文就是选择中的当前元素
(通常,相同的this上下文调用线函数;
然而,在通常情况下线生成器传递给attr操作符,this上下文将关联DOM元素)。
函数传入两个入参当前的数据d和当前的索引i。
this上下文,索引就是控制点中的索引,而不是选择中当前元素的索引。
x访问器按照数据数组中指定的顺序,每个元素恰好调用一次。
这样,就可能指定不确定性访问器,例如随机数生成器。
也可以指定x访问器为一个常量而不是函数,在所有点都有相同的x坐标情况下。
line.y([y])
如果指定了y,为指定的函数或常量设置y访问器。
如果y没有指定,返回当前的y访问器。
这个访问器为传递给y线生成器的数据数组中的每个元素。
默认的访问器假设每个输入的元素是一个二元素数字数组:
function y(d) {
return d[1];
}
像所有的其他图形库,SVG使用左上角作为原点。
这样在屏幕中较高的y值就更低。
对于可视化我们常常想要原点是在左下角。
一个简单的方法实现这个可以使用range([h, 0])替代range([0, h])反转y比例尺的范围。
line.interpolate([interpolate])
如果指定了interpolate 参数,就会设置插值器模式为指定的字符串或者函数。
如果没有指定,就返回当前的插值器模式。支持下面的命名插值器模式:
linear -分段线性片段,如折线。
linear-closed –闭合直线段,以形成一个多边形。
step - 水平和垂直段之间交替,如在step函数中。
step-before -垂直和水平段之间交替,如在step函数中。
step-after -水平和垂直段之间交替,如在step函数中。
basis - B样条曲线(B-spline),在两端的控制点的重复。
basis-open – 开放B样条曲线,首尾不会相交。
basis-closed -封闭B样条曲线,如在一个循环。
bundle – 等价于basis, 除了使用tension参数拉直样条曲线。
cardinal – 基本样条曲线(Cardinal spline),在末端控制点的重复。
cardinal-open –开放的基本样条曲线,首尾不会相交,但和其他控制点相交。
cardinal-closed -封闭基本样条曲线,如在一个循环。
monotone - 三次插值(cubic interpolation),可以保留y的单调性。
其中一些插值模式的行为可能通过指定的张力tension进行进一步定制。
如果interpolate 是一个函数,
然后这个函数将被调用来反转一个形如[[x0, y0], [x1, y1], …]的点数组,
返回一个SVG路径数据字符串(SVG path data string),用来展示线。
字符串开始处的“M” 隐含的,不应该被返回。
例如,线性插值被实现为:
function interpolateLinear(points) {
return points.join("L");
}
这相当于(并且比这更有效):
function interpolateLinear(points) {
var path = "";
for (var i = 0; i < points.length; i++) {
if (i) path += "L";
path += points[i][0] + "," + points[i][1];
}
return path;
}
乘方比例尺
除了有一个在输出范围值被计算之前应用于输入值域的指数变换之外,
乘方比例尺类似于线性比例尺。
映射到输出范围值y可以被表示为一个输入值域x的函数:
y = mx^k + b
,
其中k是指数的值。
乘方比例尺也支持负值,在这种情况下,输入值权力天平也支持负值,
在这种情况下,输入值以指数-1进行乘方计算,由此产生的输出值也将以-1来乘方计算。
d3.scale.sqrt()
//开平方
构造一个新的乘方比例尺,输入值域默认为[0,1],输出范围默认为[0,1],指数默认为0.5。
这种方法可以简记为:
d3.scale.pow().exponent(.5)
返回的比例尺是一个函数,它接受一个代表输入值域中某一个值的参数x,
返回值是对应于输出范围的一个值。
因此,这个比例尺对于数字来说,相当于函数sqrt的功能;
例如:sqrt(0.25)的结果将返回0.5。
d3.scale.pow()
构造一个新的乘方比例尺,
默认输入值域为[0,1],
默认输出范围[0,1],
默认指数为1。
因此,对于数字来说,默认的乘方比例尺相当于数字正比例函数(the identity function);
例如pow(0.5)的结果将返回0.5。
pow(x)
给定一个输入域值x,返回输出范围中相应的值。
注意:一些interpolators重用返回值。
例如,如果值域是任意对象,然后d3.interpolateObject自动被应用并且比例尺重用这个返回的对象。
通常,一个比例尺的返回值会立刻被应用于设置一个属性(attribute)或样式(style);
不过,如果你需要存储比例尺的返回值,可以适当地使用字符串强转换或复制值。
pow.rangeRound(values)
将指定的values组成的数组设置为输出范围,
同时设置比例尺的插值器到d3.interpolateRound。
当比例尺输出的值需要为整数时,这便是一个非常方便使用套路,
以此避免不确定性的小数产生。
也可以在比例尺应用后通过手动将输出值处理为整数。
pow.exponent([k])
如果k值被指定值,当前指数将被设置为k值。
如果k值没有被指定,则返回当前指数。默认值是1。
pow.range([values])
如果values被指定,便将指定包含values的数组设置为比例尺的输出范围。
这个数组必须包含两个或两个以上的值,来对应匹配输入域的基数,
否则多于两个以上的将被截断从而去对应其它值。
给定数组中的元素不要求必须为数字;支持基本插值器(interpolator)的任何值都可以使用。
然而,数字范围需要转化操作符去转化。
如果values没有被指定,将返回当前的输出范围。
对数比例尺
d3.scale.log()
构建一个默认域[1,10]新的对数比例尺,默认范围[0,1],底数是10。
log(x)
给一个在输入定义域中的x值,返回一个输出值域的相应值。
注:一些内插器(interpolators)重用返回值。
例如,如果域的值是任意对象,那么d3.interpolateObject是自动应用和按比例返回的对象。
通常情况下,一个比例尺的返回值被立即用于设置属性(attribute)或样式(style);
但是,如果你需要存储比列尺的返回值,使用字符串控制或创建一个合适的副本。
量化比例尺
量化比例尺是线性比例尺的变体,定义域是连续的,值域是离散的。
定义域基于值域的份数将被划分为同样的份数。
这种线性关系可以表示为:
y = mx + b
定义域是用来可视化的数据维度,
例如,人口样本中的一组学生的高度(以米为单位).
值域是输出的可视化维度,
例如条形图中的条高(以像素为单位)。
d3.scale.quantize()
使用默认的定义域[0,1],定义一个量化变换,默认的范围是[0,1];
因此,默认的量化变换等同于数值的四舍五入round方法;
例如:quantize(0.49)返回0,quantize(0.51)返回1,
详见下例:
var q = d3.scale.quantize().domain([0, 1]).range(['a', 'b', 'c']);
//q(0.3) === 'a', q(0.4) === 'b', q(0.6) === 'b', q(0.7) ==='c';
//q.invertExtent('a') returns [0, 0.3333333333333333]
quantize(x)
指定一个值x作为输入域值,返回对应该域值的范围值。
理解:quantize(0.4)则会使用默认的值域0和1,
即:该quantize(0.4)返回值为0,因为四舍五入0.4为0,以此类推。
时间比例尺
D3的时间比例尺(Time scale)是d3.scale.linear比例尺的扩展,
使用Javascript的Date对象作为其输入域(domain)。
因此,不同于普通的线性比例尺(linear scale),
domain的值会被强制转为时间类型而非数字类型;
同样的,反函数(invert)返回的是一个时间类型。
最方便的是,time scale同样提供了基于time intervals的合适的打点器(ticks),
解除了为任何基于时间的域生成轴的痛苦。
d3.time.scale返回的是一个比例尺对象,同时也是一个函数。
你可以像任何函数一样引用它,同时它有额外的方法可以改变它的行为。
如D3的其它类一样,scale对象也可以链式调用方法,setter方法返回scale对象本身,
可以用一个简洁的声明中引用多个setters。
d3.time.scale()
使用默认的域和范围来构建一个新的时间比例尺;
默认以本地时间配置ticks和tick format。
临界值比例尺
临界值比例尺很像定量 quantize比例尺,只是他允许你将输入域的任意的子集合映射到离散的输出值上。
输入值是连续的,并且基于一组临界值被划到不同的区域。
输入值域通常是你想要用来可视化的数据的尺度,例如是一群学生的身高。
输出值域通常是所需的输出可视化数据的尺度。例如是一组颜色(用字符串表示)。
d3.scale.threshold()
构造一组新的临界值比例尺,默认的输入范围是[.5],默认的输出范围是[0,1],
因此,对数字来说,默认quantize比例尺将和round函数相同,
例如,输入0.49将输出0,输入0.51将输出1.
var t = d3.scale.threshold().domain([0, 1]).range(['a', 'b', 'c']);
t(-1) === 'a';
t(0) === 'b';
t(0.5) === 'b';
t(1) === 'c';
t(1000) === 'c';
t.invertExtent('a'); //returns [undefined, 0]
t.invertExtent('b'); //returns [0, 1]
t.invertExtent('c'); //returns [1, undefined]
threshold(x)
x代表输入域值,函数将返回对应的输出范围的值。
过渡
Interpolation
D3有很多内置interpolators来简化任意值的过渡;
插值器是一个函数,用来将值域[0,1]中参数值t映射为一种颜色,数字或任意值。
d3.interpolators
内置插值器工厂的数组,是d3.interpolate所使用的。
额外的插值器工厂可能被添加到这个数组的末尾端。
如果它支持可以插入两个指定的输入值,那么每个工厂可能会返回一个插值器;
否则,工厂将返回一个假值并尝试返回其他的插值器。
例如,注册一个自定义插值器用来格式化美元和美分,你可能会写:
d3.interpolators.push(function(a, b) {
var re = /^\$([0-9,.]+)$/, ma, mb, f = d3.format(",.02f");
if ((ma = re.exec(a)) && (mb = re.exec(b))) {
a = parseFloat(ma[1]);
b = parseFloat(mb[1]) - a;
return function(t) {
return "$" + f(a + b * t);
};
}
});
d3.interpolate("$20", "$10")(1/3),返回 $16.67;
d3.interpolate("$20", "$10")(1) ,返回 $10.00;
d3.interpolate("$20", "$10")(0) ,返回 $20.00。
d3.transition([selection], [name])
创建动画过渡。这等价于 d3.select(document).transition()
。
这个方法很少使用,因为它通常更容易从现有选择导出的转变,
而不是从现有的过渡导出的选择。当使用可选的选择调用,
这个方法通常返回指定选择;例如它是一个空操作。
然而,transition.each的上下文中,
这个方法将为指定的选择(继承了延迟,持续和其他父过渡中的属性)创建一个新的过渡。
这用来实现可以不论在选择器或者在过渡中都能被调用的可重用组件是非常有用的。
在后者的情况下支持导出并行过渡。
transition.delay([delay])
指定过渡延迟(delay )以毫秒ms为单位。
如果延迟是一个常量,则所有的元素将被赋予相同的延迟;
如果延迟是一个函数,则这个函数将被每个选中的元素(按顺序)计算,
将被传递当前的数据d和当前的索引i作为函数的变量,使用this上下文作为当前DOM元素。
这个函数的返回值将被用来为每个元素的延迟设置值。
默认的延迟是0。如果延迟(duration)没有被指定,就返回过渡中第一个非空元素绑定的delay值。
设定延迟为索引i的倍数是一种方便方式错开元素过渡。
例如,如果你使用duration 中固定的持续,并且当前选择有n个元素,你
可以通过2 * duration 错开过渡:
.delay(function(d, i) { return i / n * duration; })
你也可以计算出延迟作为数据的一个功能,从而产生一个数据驱动的动画。
延迟总是相对一系列过渡中的第一个而言.
transition.duration([duration])
指定每个元素的持续时间(duration ),单位为毫秒。
如果持续时间是常量的,那么所有的元素被给予相同的持续时间;
否则,如果持续时间是函数,则该函数为每个选定的元件(按顺序)计算持续时间,
被传递的当前数据d与当前索引i,并用this表示当前的DOM元素。
该函数的返回值被用于设置每个元素的持续时间。
默认持续时间为250毫秒。
如果没有指定时间,则返回绑定过渡(transition)中的第一个非空元素的持续时间。
transition.ease([value[, arguments]])
指定过渡的缓动函数(easing function。
如果value参数是一个函数,它被用于缓解当前参数定时值t,t通常在范围[0,1]内。
(在过渡结束时,t可以是稍大于1)否则,value参数被假定为一个字符串,
这个参数被传递给d3.ease方法来产生一个缓动函数。
默认缓动函数是“cubic-in-out”。
需要注意的是它不能用来定制每个元件或每个属性的缓动函数;
但是,如果你使用的“线性(linear)”缓和函数,
可以通过使用attrTween或styleTween插值器中内置的定制缓动功能。
如果未指定缓动,则返回绑定到此过渡(transition)中的第一个非空元素的缓动函数。
transition.styleTween(name, tween[, priority])
根据指定的补间函数指定的名称过渡CSS样式属性的值。
可选参数priority 可以被指定为null或者字符串“important”(没有感叹号)。
过渡的起始和结束值由补间函数决定;
补间函数在没给元素过渡开始的时候调用,被传递的参数是当前数据d,当前索引I,
当前属性值a,this上下文代表当前DOM元素。
补间函数的返回值必须是一个插值器:
一个函数映射定义域[0,1]中的值t为一个颜色、数字或者属性值。
例如,style操作符是建立在styleTween操作符之上的。
补间函数被style操作符使用取决于终值是一个函数还是常量。
终值是函数时:
function tween(d, i, a) {
return d3.interpolate(a, String(value.call(this, d, i)));
}
终值是常量时:
function tween(d, i, a) {
return d3.interpolate(a, String(value));
}
styleTween操作符在需要定制插值器的使用使用到,
例如:理解CSS3转换的语义。
对简单常用的情况使用style操作符,即插值器可以从当前计算的样式属性自动驱动到期望的终值。
transition.attrTween(name, tween)
根据指定的补间(tween)函数,通过指定的名称(name)过渡属性值。
过渡的开始和结束值由补间函数决定。
补间函数在每个元素的过渡开始的时候被调用,传入参数有当前数据d,当前索引i,
this上下文表示当前DOM元素。
补间函数的返回值必须是一个插值器:
函数将定义域[0,1]映射为颜色、数字或者属性值。
例如,attr操作符是建立在attrTween操作符之上的。
补间函数被attr操作符使用取决于终值是一个函数还是常量。
如果终值是一个函数则:
function tween(d, i, a) {
return d3.interpolate(a, String(value.call(this, d, i)));
}
如果终值是一个常量则:
function tween(d, i, a) {
return d3.interpolate(a, String(value));
}
这个attrTween操作符在你需要一个自定义的内插器的时候用到,
例如:理解SVG路径数据语义。
一种常见的技术是数据空间插值:
其中interpolateObject用来插入两个数据值,
这个插值的结果(也就是用一个shap)用来计算新属性值。
使用attr操作符处理简单常见的情况,即内插器可以自动地从当前属性值转到期望的终值。
Easing
d3.ease(type[, arguments…])
返回一个指定类型(type),带有任何可选参数(arguments)的内置缓动函数。
一个缓动函数将当前参数化的时间值t从定义域[0,1]映射到一个相似返回的其他值;
这通常用来设置过渡的缓动。D3支持以下的缓动类型:
linear -标识函数, t.
poly(k) – t 的 k次方 (例如3).
quad – 等价于poly(2).
cubic - 等价于poly(3).
sin – 使用三角函数 sin.
exp – 2的t次方
circle - 四分之一圈
elastic(a, p) - 模拟一个橡皮筋;略有延长可能会超出0,1。
back(s) - 模拟备份到一个停车位。
bounce - 模拟一个有弹性碰撞。 这些内置的类型可以采用各种方式进行扩展:
in - 标识的功能。
out -逆转缓动的方向为[1,0]。
in-out -从[0,.5]和[.5,1]复制和镜像缓动函数。
out-in -从[1,.5]和[.5,0]复制和镜像缓动函数。 默认的缓动函数是“cubic-in-out” 它提供了适合慢入慢出动画。
ease(t)
给定的参数时间t,通常在范围[0,1]内,返回的缓动的时间。
返回的值通常是在范围[0,1]为好,但对于某些缓动的函数也可以超出这个范围,
比如“弹性(elastic)”就可稍微延伸。
Timers
D3在内部维护一个高效的定时器队列,使成千上万的定时器可以用最小的开销并发地处理;
此外,该定时器队列保证动画的一致的定时时同时或分阶段转换被调度。
如果浏览器支持它,定时器队列将使用requestAnimationFrame流体高效的动画。
定时器队列也是聪明的使用setTimeout的时候有一个调度事件之前,出现长时间的延迟。
d3.timer(function[, delay[, time]])
启动一个自定义动画计时器,重复地调用指定的函数(function ),直到它返回true。
计时器启动后没有办法把它取消,所以一定要确保完成时,你的计时器函数返回true!
当给定函数将在一段延迟之后被调用时,一个以毫秒为单位的可选数字delay可能被指定。
延时是相对于指定时间从UNIX纪元以毫秒为单位;如果没有指定时间,则默认为Date.now。 您可以使用延迟(delay )和时间(time )以指定function应该开始被调用的相对和绝对时刻。例如,一个日历通知可能被编码为: d3.timer(notify, -4 * 1000 * 60 * 60, +new Date(2012, 09, 29)); // four hours before midnight October 29 (months are zero-based)
Interpolation
D3有很多内置interpolators来简化任意值的过渡;
插值器是一个函数,用来将值域[0,1]中参数值t映射为一种颜色,数字或任意值。
d3.interpolate(a, b)
返回一个介于a和b之间的默认插值器。
插值器的类型是基于后面一个值b的类型,使用以下算法:
1.如果b是颜色(color)类型,则返回interpolateRgb插值器。
2.如果b是字符串(string)类型,则返回interpolateString插值器。
3.如果b是数组(array)类型,则返回interpolateArray插值器。
4.如果b是对象(object)类型,且不能强制转换为数字类型, 则返回interpolateObject插值器。
5.否则,返回interpolateNumber插值器。
基于选定的插值器,a将被强制转换为一个适当的对应类型。
颜色检查适用于 d3.rgb和其他颜色空间以及/^(#|rgb(|hsl()/形式的颜色字符串或CSS指定的颜色。
这个默认插值器的行为可以扩展至支持其他的类型。
只要添加用户自定义插值器到d3.interpolators数组中即可。
interpolate(t)
对在区间[0,1]中一个给定的参数t,返回相关的插入值。
插值器通常用结合比例尺一起使用,
映射一个输入域(如定量维度)到一个输出范围(如一系列颜色或像素位置)。
轴 Axis
轴组件设计来和D3的定量(quantitative),时间(time)和序数比例尺(ordinal)一起使用。
d3.svg.axis()
创建一个默认的轴。
axis(selection)
将轴应用到选择器和过渡上。选择必须包含svg或者g元素。例如:
d3.select("body").append("svg")
.attr("class", "axis")
.attr("width", 1440)
.attr("height", 30)
.append("g")
.attr("transform", "translate(0,30)")
.call(axis);
axis.scale([scale])
如果指定了 scale 参数则设置刻度尺,并返回轴。
如果未指定 scale 参数,将返回当前的刻度尺,默认为线性刻度。
axis.orient([orientation])
如果指定了方向 orientation 参数则设置方向 ,并返回轴。
如果未指定 orientation 参数,将返回当前的刻度尺,默认为"bottom"。
支持下面几种方向:
"top" -刻度位于横轴域路径上面
"bottom" -刻度位于横轴域路径下面
"left" -刻度位于纵轴域路径左边
"right" -刻度位于纵轴域路径右边
如果指定的方向是不支持的值之一,该轴将恢复为默认的方向。
改变方向将影响刻度和它们的标签相对于轴路径的的位置,但不改变该轴本身的位置;
为了改变轴相对于基址图的位置,可以指定g元素上的 transform 变换属性。
axis.ticks([arguments…])
如果指定了 arguments 参数,存储指定的参数为之后来用生成刻度并返回轴。
参数之后会传递给scale.ticks生成刻度值(除非刻度值通过明确地指定axis.tickValues)。
参数将传递给比例尺的tickFormat方法用来生成默认的刻度格式。
如果没有指定参数,返回当前的刻度参数,默认是[10]。
合适的参数取决于关联的比例尺:对于线性比例尺,你可以指定刻度数为axis.ticks(20);
对于对数比例尺你可以指定数量和刻度格式;
对于时间比例尺,时间间隔例如axis.ticks(d3.time.minutes, 15)可能更合适。
axis.tickPadding([padding])
如果指定填充边距 padding,设置填充边距的指定值并返回对应的轴。
如果没有指定填充边距 padding,返回当前默认填充边距(默认为3像素)。
axis.tickFormat([format])
如果指定格式 format,格式设置为指定的函数并返回axis。
如果没有指定格式 format,返回当前格式函数,默认为空。
空格式表示应该使用比例尺的默认格式器,此格式通过调用scale.tickFormat产生。
在这种情况下,ticks指定的参数同样传递给scale.tickFormat方法。
查看d3.format创建格式的帮助。
例如,axis.tickFormat(d3.format(.0f“))将通过逗号分组千位显示一个整数。
首先定义格式器:var commasFormatter = d3.format(”,.0f”) 可以让你把它作为你的数据的函数,
例如,在comma-grouped整数前添加“$”符号:.tickFormat(function(d) { return "$" + commasFormatter(d); })。
注意:对于对数比例尺,刻度的数值不能自定义;
然而,刻度的数值标签可以通过ticks自定义。
同样,对数比例尺刻度的格式器通常是通过ticks而不是tickFormat指定,
以保持默认标签隐藏(label-hiding)行为。
格式化
D3使用标准的数字格式化使得一切变得简单,例如,创建一个用0补齐4位数字的函数,可以这样:
var zero = d3.format("04d");
现在,你就可以调用 zero 来很方便的格式化你的数字了:
zero(2); // "0002"
zero(123); // "0123"
当然,除了数字,D3还支持格式化和解析日期,逗号分隔字串。
d3.format(specifier)
返回给定的字符串(specifier)的格式化函数
(等同于适用默认的美国英语语言环境的locale.numberFormat)。
唯一的入参是数字,返回代表格式化数字的字符串。
这个格式化规范模拟的是Python 3.1内置的格式化规范语言format specification mini-language。
规范(specifier)的通常格式如下:
[[fill]align][sign][symbol][0][width][,][.precision][type]
fill可以是任意字符,除了 “{” 和 “}”,fill 由紧跟它的align选项标识。
align有三种选项:
("<") 在可用的区域左对齐。
(">") 在可用的区域右对齐(默认)。
("^") 在可用的区域居中。
sign可能是:
plus ("+") - 可以用于正数或负数。
minus ("-") - 仅仅用于负数(默认)。
space (" ") - 前面的空格应该用在正数前面,而减号必须用在负数!
symbol可能是:
currency ("$") - 本地货币符号的前端或后缀
base ("#") - 对于二进制、八进制或十六进制的输出,前缀分别是 "0b", "0o", or "0x".
0选项允许补零.
width 定义最小字段宽度. 如果没有指定,那么宽度将取决于内容。
,选项允许使用逗号作为千位分隔符.
The precision indicates how many digits should be displayed after the decimal point for a value formatted with types "f" and "%",
or before and after the decimal point for a value formatted with types "g", "r" and "p".
The available type values are:
exponent ("e") - use Number.toExponential.
general ("g") - use Number.toPrecision.
fixed ("f") - use Number.toFixed.
integer ("d") - use Number.toString, but ignore any non-integer values.
rounded ("r") - round to precision significant digits, padding with zeroes where necessary in similar fashion to fixed ("f"). If no precision is specified, falls back to general notation.
percentage ("%") - like fixed, but multiply by 100 and suffix with "%".
rounded percentage ("p") - like rounded, but multiply by 100 and suffix with "%".
binary ("b") - outputs the number in base 2.
octal ("o") - outputs the number in base 8.
hexadecimal ("x") - outputs the number in base 16, using lower-case letters for the digits above 9.
hexadecimal ("X") - outputs the number in base 16, using upper-case letters for the digits above 9.
character ("c") - converts the integer to the corresponding unicode character before printing.
SI-prefix ("s") - like rounded, but with a unit suffixed such as "9.5M" for mega, or "1.00µ" for micro.
The type "n" is also supported as shorthand for ",g".
请求
d3.json(url[, callback])
指定的url创建一个JSON文件请求其mime type为"application/json"。
如果指定了回调函数callback,请求将通过GET方法立即分发,
当文件被加载或者请求失败之后回调函数将被异步调用。
回调函数的调用使用两个参数:error(有的话)和解析过的JSON。
错误发生时解析过的JSON是未定义的。如果没有指定回调函数,
返回的请求可能使用xhr.get或近似的方法分发,并使用xhr.on处理。
嵌套 (Nest)
嵌套允许数组中的元素被组织为分层树型结构;
类似SQL语句里面的GROUP BY方法,但不能多级别分组,而且输出的结果是树而不是一般的表。
树的层级由key方法指定。树的叶节点可以按值来排序,而内部节点可以按键来排序。
可选参数汇总(rollup)函数可以使用加法函数瓦解每个叶节点的元素.
nest 操作符(d3.nest返回的对象)是可以重复使用的,不保留任何嵌套数据的引用。
例如,思考下面1931-2年间明尼苏达州(美国州名)麦田地皮的表格数据结构:
var yields = [{yield: 27.00, variety: "Manchuria", year: 1931, site: "University Farm"},
{yield: 48.87, variety: "Manchuria", year: 1931, site: "Waseca"},
{yield: 27.43, variety: "Manchuria", year: 1931, site: "Morris"}, ...]
为了方便查看,可以嵌套元素首先按year然后按variety,如下:
var nest = d3.nest()
.key(function(d) { return d.year; })
.key(function(d) { return d.variety; })
.entries(yields);
返回的嵌套数组中。每个元素的外部数组是键-值对,列出每个不同键的值:
[{key: 1931, values: [
{key: "Manchuria", values: [
{yield: 27.00, variety: "Manchuria", year: 1931, site: "University Farm"},
{yield: 48.87, variety: "Manchuria", year: 1931, site: "Waseca"},
{yield: 27.43, variety: "Manchuria", year: 1931, site: "Morris"}, ...]},
{key: "Glabron", values: [
{yield: 43.07, variety: "Glabron", year: 1931, site: "University Farm"},
{yield: 55.20, variety: "Glabron", year: 1931, site: "Waseca"}, ...]}, ...]},
{key: 1932, values: ...}]
嵌套的形式可以在SVG或HTML很容易迭代和生成层次结构。
d3.nest()
创建一个新操作符。
keys集合初始为空。
如果map或entries 操作符在任何键函数被注册之前被调用,这个嵌套操作符通常返回输入数组。
nest.key(function)
注册一个新的键函数function。
键函数将被输入数组中的每个元素调用,并且必须返回一个用于分配元素到它的组内的字符串标识符。
通常,这个函数被实现为一个简单的访问器,如上面例子中year和variety的访问器。
输入的数组的引导(index)并没有传递给function。
每当一个key 被注册,它被放到一个内部键数组的末端,
和由此产生的map或实体将有一个额外的层级。
当前没有一个方法可以删除或查询注册的键。
最近注册的键在后续的方法中被当作当前键。
nest.entries(array)
为指定的array参数应用nest操作符,返回一个键值对数组。
从概念上讲,这和对 map 返回的关联数组应用 d3.entries 操作符类似,
但是这个是用于每一层而不是只有第一层(最外层)。
返回数组中的每个实体对应于第一个key函数返回的不同的key值。
实体值取决于注册的key函数的数量:
如果有一个关联的key,
值就是另外一个嵌套实体数组;
否则,值就是含有指定key值得输入数组array过滤得到的元素数组。