d3-shape
可视化通常由离散的图形标记组成,如symbols(符号)、arcs(弧)、lines(线)和areas(区域)。柱状图中的矩形很容易通过SVG或Canvas直接生成,但其他的形状就比较复杂了,如rounded annular sectors(圆角环形扇区)和centripetal Catmull–Rom splines(向心Catmull–Rom样条)。此模块为你提供了各种形状生成器。
和D3的其他方面一样,这些形状是由数据驱动的;每个形状发生器对外暴露accessor以控制输入数据如何映射到一个视觉表现。例如,你可以通过为数据字段制作比例尺来为时间序列定义一个线条生成器以适应图表:
var line = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.value); });
该线条生成器可以用于计算SVG路径元素的d
属性:
path.datum(data).attr("d", line);
或者你可以使用它渲染Canvas 2D上下文:
line.context(context)(data);
Installing
如果你使用npm,请键入npm install d3-shape
。否则,请下载最新版本。你也可以直接从d3js.org加载,作为standalone library(独立库)或D3 4.0的一部分来使用。支持AMD,CommonJS和vanilla环境。在vanilla环境下,会输出一个全局的d3
:
<script src="https://d3js.org/d3-path.v1.min.js"></script>
<script src="https://d3js.org/d3-shape.v1.min.js"></script>
<script>
var line = d3.line();
</script>
API Reference
Arcs
弧生成器可以在饼图和圆环图中生成一个圆形和扇形区域,如饼图或圆环图。如果开始角度和结束角度之间的差值(角跨度)大于τ,弧生成器将生成一个完整的圆或圆环。如果小于τ,则弧会有圆角和间距。弧的中心总是在⟨0,0⟩,可以使用transform(另请参阅:SVG和Canvas)进行移动。
另请参阅饼图生成器,它为饼图或圆环图中的数据数组计算必要的角度值;这些角度值可以传入弧生成器中使用。
d3.arc()
用默认配置构建一个新的arc generator(弧生成器)。
arc(arguments…)
为给定arguments生成一段弧。arguments是任意的,它只是简单的随this
对象一起传入弧生成器的accessor函数。例如,在默认配置下,期望具有半径和角度的对象为:
var arc = d3.arc();
arc({
innerRadius: 0,
outerRadius: 100,
startAngle: 0,
endAngle: Math.PI / 2
}); // "M0,-100A100,100,0,0,1,100,0L0,0Z"
如果半径和角度被定义为常数,则可以生成一段没有任何参数的弧:
var arc = d3.arc()
.innerRadius(0)
.outerRadius(100)
.startAngle(0)
.endAngle(Math.PI / 2);
arc(); // "M0,-100A100,100,0,0,1,100,0L0,0Z"
如果弧生成器有上下文,则弧将作为一系列路径方法的调用呈现在这个上下文中,函数将无返回值。否则,返回一个路径数据字符串。
arc.centroid(arguments…)
计算给定arguments生成的弧的中线的中点[x, y]。arguments是任意的,它只是简单的随this
对象一起传入弧生成器的accessor函数。要生成一致的弧,accessors必须是确定的,即对于相同的arguments返回相同的值。中点定义为 (startAngle + endAngle) / 2和(innerRadius + outerRadius) / 2。例如:
注意:这不是弧的几何中心,它可能在弧的外面,此方法只是方便确定标签位置。
arc.innerRadius([radius])
如果指定了radius,则将内半径设置为给定的函数或数字,并返回此弧生成器。如果不指定radius,则返回当前的内半径accessor,默认为:
function innerRadius(d) {
return d.innerRadius;
}
在构建一个stacked polar bar chart(堆叠极条形图)时将内半径指定为一个函数是非常有用的,通常使用sqrt scale,更常见的是,为圆环图或饼图指定一个恒定的内半径。如果外半径小于内半径,则内外半径会被交换。负数会被视为0。
arc.outerRadius([radius])
如果指定了radius,则将外半径设置为给定的函数或数字,并返回此弧生成器。如果不指定radius,则返回当前的外半径accessor,默认为:
function outerRadius(d) {
return d.outerRadius;
}
在构建一个coxcomb(极地区图)或polar bar chart(极条形图)时将外半径指定为一个函数是非常有用的,通常使用sqrt scale,更常见的是,为圆环图或饼图指定一个恒定的外半径。如果外半径小于内半径,则内外半径会被交换。负数会被视为0。
arc.cornerRadius([radius])
如果指定了radius,则将圆角半径设置为给定的函数或数字,并返回此弧生成器。如果不指定radius,则返回当前的圆角半径accessor,默认为:
function cornerRadius() {
return 0;
}
如果圆角半径大于0,则用给定半径的圆对弧进行圆角。对于扇区,则外沿的两个角会被圆化;对于环扇区,所有四个角都会被圆化。下图展示了圆角:
圆角半径可能会大于 (outerRadius - innerRadius) / 2。此外,如果弧的角度值小于π,则圆角半径会被减小至两个相邻圆角的相交值。这种情况常发生在内沿角上。另请参阅arc corners animation。
arc.startAngle([angle])
如果指定了angle,则将起始角度设置为给定的函数或数字,并返回此弧生成器。如果不指定angle,则返回当前的起始角度accessor,默认为:
function startAngle(d) {
return d.startAngle;
}
angle为弧度值,-y(12点)处为0,顺时针方向为正。如果|endAngle - startAngle| ≥ τ,会生成一个完整的圆或圆环。
arc.endAngle([angle])
如果指定了angle,则将结束角度设置为给定的函数或数字,并返回此弧生成器。如果不指定angle,则返回当前的结束角度accessor,默认为:
function endAngle(d) {
return d.endAngle;
}
angle为弧度值,-y(12点)处为0,顺时针方向为正。如果|endAngle - startAngle| ≥ τ,会生成一个完整的圆或圆环。
arc.padAngle([angle])
如果指定了angle,则将间距角度设置为给定的函数或数字,并返回此弧生成器。如果不指定angle,则返回当前的间距角度accessor,默认为:
function padAngle() {
return d && d.padAngle;
}
间距角度会被转换为两个相邻弧之间的固定直线距离,定义为padRadius * padAngle。这个距离从弧的起点到终点相等地减去。如果弧为一个完整的圆或圆环,当|endAngle - startAngle| ≥ τ时间距角度会被忽略。
如果内半径或角跨度相对于间距角度较小,则有可能无法保持相邻弧之间的边相互平行。在这种情况下,弧的内边可能会缩小为一个点,类似于一个扇形。因此,间距只应用于圆环(即内半径为正),如图所示:
使用间距推荐的最小内半径为outerRadius * padAngle / sin(θ),θ为最小arc的角度值。例如,如果外半径为200像素,间距角度为0.02弧度,则合理的θ为0.04弧度,合理的内半径为100像素。另请参阅arc padding animation。
通常,间距角度不直接在弧生成器上设置,而是用饼生成器生成,以确保由间距的弧的区域同其值是相称的;另请参阅pie.padAngle和pie padding animation。如果你直接向弧生成器应用一个恒定的间距角度,它会减小较小的弧,造成失真。
arc.padRadius([radius])
如果指定了radius,则设置间距半径为给定的函数或数字,并返回此弧生成器。如果不指定radius,则返回当前的间距半径accessor,默认为nul,表示会根据sqrt(innerRadius * innerRadius + outerRadius * outerRadius)自动计算。pad radius确定了相邻arc间的直线分割距离,定义为padRadius * padAngle。
arc.context([context])
如果指定了context,则设置上下文并返回该此弧生成器。如果不指定context,则返回当前上下文,默认为null。如果上下文不为null,则生成的弧将作为一系列路径方法的调用呈现到该上下文中。否则,返回生成弧的路径数据字符串。
Pies
饼生成器不会直接生成形状,而是计算生成饼图或圆环图所需表格数据集的角度值,这些角度值可以传入弧生成器中。
d3.pie()
使用默认配置构建一个新的饼生成器。
pie(data[, arguments…])
为给定data数组生成饼,返回一个表示每个数据的弧角度的对象数组。任何额外的arguments都是任意的;它们只是简单的随this
对象传入饼生成器的accessor中。返回数组的长度和data一致,返回数组中的每个元素i都对应输入数组中的元素i。返回数组中的每个对象都具有以下属性:
data
- 输入数据;输入数据数组中的对应元素。value
- 弧的数值。index
- 从0开始的弧的排序索引。startAngle
- 弧的起始角度。endAngle
- 弧的结束角度。padAngle
- 弧的间距角度。
此方法用于和弧生成器的默认开始角度、结束角度、间距角度accessors一起使用。角的单位是任意的,但如果你想同时使用饼生成器和弧生成器,你应该使用弧度,-y(12点)处为0,顺时针方向为正。
给定一个小的数字数据集,下面展示是如何计算弧角度并绘制成饼图的:
var data = [1, 1, 2, 3, 5, 8, 13, 21];
var arcs = d3.pie()(data);
第一对括号,pie()
,构建一个默认的饼生成器。第二对,pie()(data)
,对数据集调用该生成器,返回一个对象数组:
[
{"data": 1, "value": 1, "index": 6, "startAngle": 6.050474740247008, "endAngle": 6.166830023713296, "padAngle": 0},
{"data": 1, "value": 1, "index": 7, "startAngle": 6.166830023713296, "endAngle": 6.283185307179584, "padAngle": 0},
{"data": 2, "value": 2, "index": 5, "startAngle": 5.817764173314431, "endAngle": 6.050474740247008, "padAngle": 0},
{"data": 3, "value": 3, "index": 4, "startAngle": 5.468698322915565, "endAngle": 5.817764173314431, "padAngle": 0},
{"data": 5, "value": 5, "index": 3, "startAngle": 4.886921905584122, "endAngle": 5.468698322915565, "padAngle": 0},
{"data": 8, "value": 8, "index": 2, "startAngle": 3.956079637853813, "endAngle": 4.886921905584122, "padAngle": 0},
{"data": 13, "value": 13, "index": 1, "startAngle": 2.443460952792061, "endAngle": 3.956079637853813, "padAngle": 0},
{"data": 21, "value": 21, "index": 0, "startAngle": 0.000000000000000, "endAngle": 2.443460952792061, "padAngle": 0}
]
注意:返回数组的顺序和data是一致的,尽管这个饼图是按降序排序的,从最后一个数据的弧在(值21)十二点开始。
pie.value([value])
如果指定了value,则设置value accessor为给定的函数或数字,并返回该饼生成器。如果不指定value,则返回当前的value accessor,默认为:
function value(d) {
return d;
}
当生成饼时,将对输入数据数组的每一个元素调用value accessor,并将元素d
,索引i
和数组data
作为三个参数传入。默认的value accessor假设如数据都为数字,或者使用valueOf强行将它们转换成数字。如果你的数据不是简单的数字,那你应该指定一个accessor以返回给定数据对应的数值。例如:
var data = [
{"number": 4, "name": "Locke"},
{"number": 8, "name": "Reyes"},
{"number": 15, "name": "Ford"},
{"number": 16, "name": "Jarrah"},
{"number": 23, "name": "Shephard"},
{"number": 42, "name": "Kwon"}
];
var arcs = d3.pie()
.value(function(d) { return d.number; })
(data);
这类似于在调用饼生成器前将你的数据mapping(映射)到值。
var arcs = d3.pie()(data.map(function(d) { return d.number; }));
accessor的好处在于输入数据和返回的对象保持着联系,从而更容易访问数据的其他字段,例如设置颜色或者添加标签。
pie.sort([compare])
如果指定了compare,则设置data comparator为给定的函数并返回该饼生成器。如果不指定compare,则返回当前的data comparator,默认为null。如果data comparator和value comparator都为null,则弧会根据输入顺序放置。否则,会根据data comparator对数据进行排序,并使用结果顺序。隐式的设置data comparator,并将value comparator设为null。
compare函数接收两个参数a和b,每个元素都来自输入数据数组。如果a对应的弧在b对应的弧前,则comparator必须返回一个小于0的数;如果a对应的弧在b对应的弧后,则comparator必须返回一个大于0的数;返回0意味着a和b的相对顺序未指定。例如,通过name对弧进行排序:
pie.sort(function(a, b) { return a.name.localeCompare(b.name); });
排序并不会影响生成的弧数组的顺序,弧数组的顺序始终和输入数据数组的顺序保持一致;它只影响每个弧的角度。第一个弧从起始角度开始,最后一个弧以结束角度结束。
pie.sortValues([compare])
如果指定了compare,则设置value comparator为给定的函数,并返回该饼生成器。如果不指定compare,则返回当前的value comparator,默认为降序。默认的value comparator为:
function compare(a, b) {
return b - a;
}
如果data comparator和value comparator都为null,则弧会根据输入顺序放置。否则,会根据data comparator对数据进行排序,并使用结果顺序。隐式的设置data comparator,并将value comparator设为null。
value comparator和data comparator类似,除了两个参数a和b是用value accessor从输入数据数组中得到的,而不是数据元素。如果a对应的弧在b对应的弧前,则comparator必须返回一个小于0的数;如果a对应的弧在b对应的弧后,则comparator必须返回一个大于0的数;返回0意味着a和b的相对顺序未指定。例如,按升序对弧进行排序:
pie.sortValues(function(a, b) { return a - b; });
排序并不会影响生成的弧数组的顺序,弧数组的顺序始终和输入数据数组的顺序保持一致;它只影响每个弧的角度。第一个弧从起始角度开始,最后一个弧以结束角度结束。
pie.startAngle([angle])
如果指定了angle,则将饼所有的起始角度都设为给定的函数或数字,并返回该饼生成器。如果不指定angle,则返回当前的起始角度accessor,默认为:
function startAngle() {
return 0;
}
这里的起始角度指的是饼所有起始角度,即第一个弧的起始角度。起始角度accessor调用一次,传入相同的参数和this
上下文作为饼生成器。角的单位是任意的,但如果你想同时使用饼生成器和弧生成器,你应该使用弧度,-y(12点)处为0,顺时针方向为正。
pie.endAngle([angle])
如果指定了angle,则将饼所有的结束角度都设为给定的函数或数字,并返回该饼生成器。如果不指定angle,则返回当前的结束角度accessor,默认为:
function endAngle() {
return 2 * Math.PI;
}
这里的起始角度指的是饼所有结束角度,即第一个弧的结束角度。结束角度accessor调用一次,传入相同的参数和this
上下文作为饼生成器。角的单位是任意的,但如果你想同时使用饼生成器和弧生成器,你应该使用弧度,-y(12点)处为0,顺时针方向为正。
结束角度限制为startAngle ± τ到|endAngle - startAngle| ≤ τ。
pie.padAngle([angle])
如果指定了angle,则将间距角度设为给定的函数或数字,并返回该饼生成器。如果不指定angle,则返回当前的间距角度accessor,默认为:
function padAngle() {
return 0;
}
这里的间距角度指的是相邻两个弧的angular separation(角间距)。预留的间距总量为angle乘以输入数据数组的元素个数,最大为|endAngle - startAngle|;剩余空间则按照值的比例进行分配。另请参阅pie padding animation。间距角度accessor调用一次,传入相同的参数和this
上下文作为饼生成器。角的单位是任意的,但如果你想同时使用饼生成器和弧生成器,你应该使用弧度。
Lines
线生成器可以在线形图中生成spline(样条)或polyline(折线)。线也可以应用在其他的可视化类型中,如hierarchical edge bundling中的连接线。
d3.line()
使用默认配置创建一个新的线生成器。
line(data)
为给定的data数组生成线条。根据此线生成器相关的曲线,输入data在传入线生成器前需要先通过x-value排序。如果线生成器有上下文,则线将作为一系列路径方法的调用呈现到上下文中,函数无返回值。否则,返回一个路径数据字符串。
line.x([x])
如果指定了x,则将x accessor设为给定的函数或数字,并返回该线生成器。如果不指定x,则返回当前的x accessor,默认为:
function x(d) {
return d[0];
}
当生成线时,将对输入数据数组的每一个有定义的元素调用x accessor,并将元素d
、索引i
和数组data
作为三个参数传入。默认的x accessor假设数据为二元数组。如果你的数据不是该格式,或者你希望在渲染前进行转换,那你应该指定一个自定义accessor。例如,如果x
为time-scale,y
为linear-scale:
var data = [
{date: new Date(2007, 3, 24), value: 93.24},
{date: new Date(2007, 3, 25), value: 95.35},
{date: new Date(2007, 3, 26), value: 98.84},
{date: new Date(2007, 3, 27), value: 99.92},
{date: new Date(2007, 3, 30), value: 99.80},
{date: new Date(2007, 4, 1), value: 99.47},
…
];
var line = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.value); });
line.y([y])
如果指定了y,则将y accessor设为给定的函数或数字,并返回该线生成器。如果不指定y,则返回当前的y accessor,默认为:
function y(d) {
return d[1];
}
当生成线时,将对输入数据数组的每一个有定义的元素调用y accessor,并将元素d
、索引i
和数组data
作为三个参数传入。默认的y accessor假设数据为二元数组。另请参阅line.x。
line.defined([defined])
如果指定了defined,则将defined accessor设为给定的函数或布尔值,并返回该线生成器。如果不指定y,则返回当前的y accessor,默认为:
function defined() {
return true;
}
默认的accessor假设输入数据总是有定义的。当生成线时,将对输入数据数组的每一个元素调用defined accessor,并将元素d
、索引i
和数组data
作为三个参数传入。如果给定元素是有定义的(即,如果defined accessor对该元素返回true),则随后会对x和y accessor求值,并将点加入到当前线段中。否则,将跳过该元素并结束当前线段,在下一个有定义的点开始新的线段。其结果是,生成的线可能会有一些discrete segments(离散段)。例如:
注意,如果一条线段仅包含一个点,它可能不可见,除非使用圆形或方形的line caps。另外,一些曲线只有包含多个点时才可见,如curveCardinalOpen。
line.curve([curve])
如果指定了curve,则设置曲线工厂函数并返回该线生成器。如果不指定curve,则返回当前的曲线工厂函数,默认为curveLinear。
line.context([context])
如果指定了context,则设置上下文并返回该线生成器。如果不指定context,则返回当前的上下文,默认为null。如果上下文为null,则生成的线将作为一系列路径方法的调用呈现到上下文中。否则,返回一个表示生成的线的path data(路径数据)字符串。
d3.lineRadial()
使用默认配置构建一个径向线生成器,径向线生成器相当于标准Cartesian line generator(卡迪尔线生成器),除了将x和y accessor换成了angle 和radius accessor。径向线始终相对于⟨0,0⟩放置,可以使用transform(另请参阅:SVG,Canvas)改变原点。
lineRadial(data)
相当于line。
lineRadial.angle([angle])
相当于line.x,除了accessor返回的是以弧度为单位的角度值,在-y(12点)处为0。
lineRadial.radius([radius])
相当于line.y,除了accessor返回的是半径:即到原点⟨0,0⟩的距离。
lineRadial.defined([defined])
相当于line.defined。
lineRadial.curve([curve])
相当于line.curve。注意, curveMonotoneX 或curveMonotoneY不推荐用于径向线,因为他们假设数据在x或y上是单调的,这通常是不真实的径向线。
lineRadial.context([context])
相当于line.context。
Areas
面积生成器用于生成一块面积,如在面积图中。一块面积由两条边界线定义,无论是样条或折线。通常,两条线共享相同的x值(x0 = x1),只是y值(y0和y1)不同;最常见的是,y0始终定义为0。第一条线(the topline)由x1和y1定义,并且最先渲染;第二条线(the baseline)由x0和y0定义,第二个渲染,并随着点以相反的顺序渲染。在curveLinear curve中,这将产生一个顺时针多边形。
d3.area()
用默认配置构建一个面积生成器。
area(data)
为给定的data数组生成一块面积。根据此面积生成器相关的curve,给定的输入data在传入面积生成器前可能需要按照x值进行排序。如果面积生成器有上下文,则生成的线条将作为一系列path method(路径方法)的调用呈现到上下文中,函数无返回值。否则,返回一个path data(路径数据)字符串。
area.x([x])
如果指定了x,则将x0设为x、x1设为null,并返回该面积生成器。如果不指定x,则返回当前的x0 accessor。
area.x0([x])
如果指定了x,则设置x0 accessor为给定的函数或数字,并返回该面积生成器。如果不指定x,则返回当前的x0 accessor,默认为:
function x(d) {
return d[0];
}
当生成面积后,将对输入数据数组的每一个有定义的元素调用x0 accessor,并将元素d
,索引i
和数组data
作为三个参数传入。默认的x0 accessor假设输入的数据为二元数字数组。如果你的数据不为此格式,或者你希望在渲染前转换数据,你应该指定一个自定义accessor。例如,如果x
为time-scale,y
为linear-scale:
var data = [
{date: new Date(2007, 3, 24), value: 93.24},
{date: new Date(2007, 3, 25), value: 95.35},
{date: new Date(2007, 3, 26), value: 98.84},
{date: new Date(2007, 3, 27), value: 99.92},
{date: new Date(2007, 3, 30), value: 99.80},
{date: new Date(2007, 4, 1), value: 99.47},
…
];
var area = d3.area()
.x(function(d) { return x(d.date); })
.y1(function(d) { return y(d.value); })
.y0(y(0));
area.x1([x])
如果指定了x,则设置x1 accessor为给定的函数或数字,并返回该面积生成器。如果不指定x,则返回当前的x1 accessor,默认为null,表示先前计算的x0将用于x1。
当生成面积后,将对输入数据数组的每一个有定义的元素调用x1 accessor,并将元素d
,索引i
和数组data
作为三个参数传入。另请参阅area.x0。
area.y([y])
如果指定了y,则将y0设置为y,y1设置为null,并返回该面积生成器。如果不指定y,则返回当前的y0 accessor。
area.y0([y])
如果指定了y,则设置y0 accessor为给定的函数或数字,并返回该面积生成器。如果不指定y,则返回当前的y0 accessor,默认为:
function y() {
return 0;
}
当生成面积后,将对输入数据数组的每一个有定义的元素调用y0 accessor,并将元素d
,索引i
和数组data
作为三个参数传入。另请参阅area.x0。
area.y1([y])
如果指定了y,则设置y1 accessor为给定的函数或数字,并返回该面积生成器。如果不指定y,则返回当前的y1 accessor,默认为:
function y(d) {
return d[1];
}
accessor允许为null,表示先前计算的y0将用于y1。当生成面积后,将对输入数据数组的每一个有定义的元素调用y1 accessor,并将元素d
,索引i
和数组data
作为三个参数传入。另请参阅area.x0。
area.defined([defined])
如果指定了defined,则设置defined accessor为给定的函数或布尔值,并返回该面积生成器。如果不指定defined,则返回当前的defined accessor,默认为:
function defined() {
return true;
}
默认的accessor假设输入数据总是有定义的。当生成面积后,将对输入数据数组的每一个元素调用defined accessor,并将元素d
,索引i
和数组data
作为三个参数传入。如果给定元素是有定义的(即,如果defined accessor对该元素返回true),则随后会对x0,x1,y0和y1 accessor求值,并将点加入到当前area segment(面积分段)中。否则,将跳过该元素并结束当前面积分段,在下一个有定义的点开始新的面积分段。其结果是,生成的线条可能会有一些discrete segments(离散段)。例如:
注意,如果面积分段仅包含一个点,它可能不可见,除非使用圆形或方形的line caps。另外,一些曲线只有包含多个点时才可见,如curveCardinalOpen。
area.curve([curve])
如果指定了curve,则设置曲线工厂函数并返回该面积生成器。如果不指定curve,则返回当前的曲线工程函数,默认为curveLinear。
area.context([context])
如果指定了context,则设置上下文并返回该面积生成器。如果不指定context,则返回当前的上下文,默认为null。如果上下文为null,则生成的面积将作为一系列path method(路径方法)的调用呈现到上下文中。否则,返回一个表示生成的面积的path data(路径数据)字符串。
area.lineX0()
area.lineY0()
返回一个新的拥有该面积生成器当前defined accessor,curve和context的线生成器。线的x-accessor为该面积的x0-accessor,线的y-accessor为面积的y0-accessor。
area.lineX1()
返回一个新的拥有该面积生成器当前defined accessor,curve和context的线生成器。线的x-accessor为该面积的x1-accessor,线的y-accessor为面积的y0-accessor。
area.lineY1()
返回一个新的拥有该面积生成器当前defined accessor,curve和context的线生成器。线的x-accessor为该面积的x0-accessor,线的y-accessor为面积的y1-accessor。
d3.areaRadial()
用默认配置构建一个新的径向面积生成器,径向面积生成器相当于标准Cartesian(笛卡尔)面积生成器,除了x和y accessor换成了angle和radius accessor。径向面积始终相对于⟨0,0⟩放置,可以使用transform(另请参阅:SVG,Canvas)改变原点。
areaRadial(data)
相当于area。
areaRadial.angle([angle])
相当于area.x,除了accessor返回的是以弧度为单位的角度值,在-y(12点)处为0。
areaRadial.startAngle([angle])
相当于area.x0,除了accessor返回的是以弧度为单位的角度值,在-y(12点)处为0。注意:通常使用angle,而不是设置单独的起始角度和结束角度。
areaRadial.endAngle([angle])
相当于area.x1,除了accessor返回的是以弧度为单位的角度值,在-y(12点)处为0。注意:通常使用angle,而不是设置单独的起始角度和结束角度。
areaRadial.radius([radius])
相当于area.y,除了accessor返回的是半径,即到原点⟨0,0⟩的距离。
areaRadial.innerRadius([radius])
相当于area.y0,除了accessor返回的是半径,即到原点⟨0,0⟩的距离。
areaRadial.outerRadius([radius])
相当于area.y1,除了accessor返回的是半径,即到原点⟨0,0⟩的距离。
areaRadial.defined([defined])
相当于area.defined。
areaRadial.curve([curve])
相当于area.curve。注意:curveMonotoneX或 curveMonotoneY不推荐用于径向面积,因为他们假设数据在x或y上是单调的,这通常是不真实的径向面积。
areaRadial.context([context])
相当于line.context。
areaRadial.lineStartAngle()
areaRadial.lineInnerRadius()
返回一个新的拥有该径向面积生成器当前defined accessor,curve和context的径向线生成器。线的angle accessor为该面积的start angle accessor,线的radius accessor为该面积的inner radius accessor。
areaRadial.lineEndAngle()
返回一个新的拥有该径向面积生成器当前defined accessor,curve和context的径向线生成器。线的angle accessor为该面积的end angle accessor,线的radius accessor为该面积的inner radius accessor。
areaRadial.lineOuterRadius()
返回一个新的拥有该径向面积生成器当前defined accessor,curve和context的径向线生成器。线的angle accessor为该面积的start angle accessor,线的radius accessor为该面积的outer radius accessor。
Curves
lines定义为一系列二维[x,y]点,类似的,areas由topline(背线)和baseline(基线)定义,就只剩下如何将discrete representation(离散表示)转换为continuous shape(连续形状)了:即,如何在点之间插值。为此提供了很多种曲线。
曲线通常不直接构建或使用,而是传入line.curve和area.curve。例如:
var line = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.value); })
.curve(d3.curveCatmullRom.alpha(0.5));
d3.curveBasis(context)
用给定的控制点生成一条cubic basis spline(三次基样条)。第一个和最后一个点不断重复,样条从第一个点开始,到最后一个点结束,并与第一个点和第二个点间的线段相切,与倒数第二个点和最后一个点间的线段也相切。
d3.curveBasisClosed(context)
用给定的控制点生成一条closed cubic basis spline(闭合三次基样条)。当线段结束时,前三个控制点会重复,生成一个C2 continuity闭环。
d3.curveBasisOpen(context)
用给定的控制点生成一条cubic basis spline(三次基样条)。和basis不同的是,第一个点和最后一个点不会重复,因此曲线通常不会和这些点相交。
d3.curveBundle(context)
用给定的控制点生成一条straightened cubic basis spline(矫直三次基样条),样条末尾会根据曲线的beta拉直,beta默认为0.85。这种曲线通常用于在hierarchical edge bundling中disambiguate connections(消除歧义的连接),由Danny Holten在Hierarchical Edge Bundles: Visualization of Adjacency Relations in Hierarchical Data中提出。这种曲线不会执行curve.areaStart和curve.areaEnd;它用于和d3.line一起工作,而不是d3.area。
bundle.beta(beta)
根据给定beta(范围为[0,1])返回一条bundle curve,表示bundle strength。如果beta等于0,则在第一个点和最后一个点之间生成一条直线;如果beta等于1,则生成一条standard basis spline(标准基样条)。例如:
var line = d3.line().curve(d3.curveBundle.beta(0.5));
d3.curveCardinal(context)
用给定控制点生成一条cubic cardinal spline(三次基数样条),对第一段和最后一个段使用one-sided differences(单侧差异)。默认tension为0。
d3.curveCardinalClosed(context)
用给定控制点生成一条closed cubic cardinal spline(闭合三次基数样条)。当线段结束时,前三个控制点会重复,生成一个闭环。默认tension为0。
d3.curveCardinalOpen(context)
用给定控制点生成一条cubic cardinal spline(三次基数样条)。和curveCardinal不同的是,不会对第一段和最后一段使用one-sided differences(单侧差异),因此曲线开始于第二个点,结束于倒数第二个点。默认tension为0。
cardinal.tension(tension)
用给定的tension(返回为[0,1])返回一条cardinal curve(三次基数样条)。tension决定了切线的长度:当tension为1时全部生成0切线,相当于curveLinear;当tension为0时生成一条均匀的Catmull–Rom样条。例如:
var line = d3.line().curve(d3.curveCardinal.tension(0.5));
d3.curveCatmullRom(context)
用给定的控制点和参数alpha生成一条cubic Catmull–Rom spline(三次Catmull–Rom样条),alpha默认为0.5,由Yuksel等人在On the Parameterization of Catmull–Rom Curves中提出,会对第一段和最后一段使用one-sided differences(单侧差异)。
d3.curveCatmullRomClosed(context)
用给定的控制点和参数alpha生成一条cubic Catmull–Rom spline(三次Catmull–Rom样条),alpha默认为0.5,由Yuksel等人提出。当线段结束时,前三个控制点会重复,生成一个闭环。
d3.curveCatmullRomOpen(context)
用给定的控制点和参数alpha生成一条cubic Catmull–Rom spline(三次Catmull–Rom样条),alpha默认为0.5,由Yuksel等人提出。与curveCatmullRom不同的是,不会对第一段和最后一段使用one-sided differences(单侧差异),因此曲线开始于第二个点,结束于倒数第二个点。
catmullRom.alpha(alpha)
用给定的alpha(范围为[0,1])返回一条cubic Catmull–Rom curve(三次Catmull–Rom样条)。如果alpha为0,则生成一条uniform spline(均匀样条),相当于tension为0的curveCardinal;如果alpha为1,则生成一条chordal spline(弦样条);如果alpha为0.5,则生成一条centripetal spline(向心样条)。向心样条推荐用于避免self-intersections(自相交)和overshoot(超过)。例如:
var line = d3.line().curve(d3.curveCatmullRom.alpha(0.5));
d3.curveLinear(context)
用给定点生成一条折线。
d3.curveLinearClosed(context)
用给定点并在线段结束时重复第一个点生成一条闭合的polyline(折线)。
d3.curveMonotoneX(context)
生成一条在y轴上保持单调的三次样条,假设在x轴单调,由Steffen在A simple method for monotonic interpolation in one dimension中提出:“一条具有连续first-order derivatives(一阶导数)的光滑曲线穿过任何给定的数据点而不产生spurious oscillations。Local extrema(局部极值)只会出现在数据给出的grid points(结点),而不是在两个相邻的结点之间。”
d3.curveMonotoneY(context)
生成一条在x轴上保持单调的三次样条,假设在y轴单调,由Steffen在A simple method for monotonic interpolation in one dimension中提出:“一条具有连续first-order derivatives(一阶导数)的光滑曲线穿过任何给定的数据点而不产生spurious oscillations。Local extrema(局部极值)只会出现在数据给出的grid points(结点),而不是在两个相邻的结点之间。”
d3.curveNatural(context)
生成一条endpoints(端点)的second derivative(二阶导数)为0的natural cubic spline(自然三次样条)。
d3.curveStep(context)
生成一个由交替的水平线和垂直线组成的piecewise constant function(分段常数函数,即step function(阶跃函数))。y值在每对相邻x值的中点处变化。
d3.curveStepAfter(context)
生成一个由交替的水平线和垂直线组成的piecewise constant function(分段常数函数,即step function(阶跃函数))。y值在x值后变化。
d3.curveStepBefore(context)
生成一个由交替的水平线和垂直线组成的piecewise constant function(分段常数函数,即step function(阶跃函数))。y值在x前变化。
Custom Curves
曲线通常不会直接使用,而是传入line.curve和area.curve中。然而,如果没有内置曲线满足你的需求,你可以通过下面的接口定义自己的曲线实现。你还可以使用内置曲线类型的底层接口作为line和area generator的替代品。
curve.areaStart()
指示新面积段的开始。每个面积段都由背线和基线两条线段组成:基线紧接着背线,背线上的点与基线上的点顺序相反。
curve.areaEnd()
指示当前面积段的结束。
curve.lineStart()
指示一个新的线段的开始。伴随着一个或多个点。
curve.lineEnd()
指示当前线段的结束。
curve.point(x, y)
指示用给定的x和y值在当前线段上形成一个新的点。
Links
link生成一条从源点到目标点的平滑的cubic Bézier curve(三次贝塞尔曲线)。曲线在开始点和结束点的切线是垂直的、水平的或者径向的。
d3.linkVertical()
返回一个新的带有垂直切线的link generator。例如,要在根部在显示区域顶边的tree diagram中可视化links,你可以这样写:
var link = d3.linkVertical()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; });
d3.linkHorizontal()
返回一个带有水平切线的link generator。例如,要在根部在显示区域左边的tree diagram中可视化links,你可以这样写:
var link = d3.linkHorizontal()
.x(function(d) { return d.y; })
.y(function(d) { return d.x; });
link(arguments...)
为给定的arguments生成link。arguments是任意的;它们只是简单的随着this
对象传入link generator的accessor中。例如,在默认配置下,期望的对象为:
link({
source: [100, 100],
target: [300, 300]
});
link.source([source])
如果指定了source,则设置source accessor为给定的函数并返回该link generator。如果不指定source,则返回当前的source accessor,默认为:
function source(d) {
return d.source;
}
link.target([target])
如果指定了target,则设置target accessor为给定的函数并返回该link generator。如果不指定target,则返回当前的target accessor,默认为:
function target(d) {
return d.target;
}
link.x([x])
如果指定了x,则设置x-accessor为给定的函数并返回该link generator。如果不指定x,则返回当前的x-accessor,默认为:
function x(d) {
return d[0];
}
link.y([y])
如果指定了y,则设置y-accessor为给定的函数并返回该link generator。如果不指定y,则返回当前的y-accessor,默认为:
function y(d) {
return d[1];
}
link.context([context])
如果指定了context,则设置上下文并返回该link generator。如果不指定context,则返回当前的上下文,默认为null。如果上下文为null,则生成的link将作为一系列路径方法的调用呈现到此上下文中。否则,返回一个路径数据字符串。另请参阅d3-path。
d3.linkRadial()
返回一个带有径向切线的link generator。例如, 要在根部在显示区域中心的tree diagram中可视化links,你可以这样写:
var link = d3.linkRadial()
.angle(function(d) { return d.x; })
.radius(function(d) { return d.y; });
linkRadial.angle([angle])
相当于link.x,除了accessor返回的是以弧度为单位的角度值,在-y(12点)处为0。
linkRadial.radius([radius])
相当于link.y,除了accessor返回的是半径:到原点⟨0,0⟩的距离。
Symbols
symbols(符号)提供一个明确的形状编码,通常用于scatterplots(散点图)。符号总是集中在⟨0,0⟩;可以使用transform(另请参阅:SVG,Canvas)移动到不同位置。
d3.symbol()
用默认配置构建一个新的symbol generator。
symbol(arguments...)
为给定的arguments生成符号。arguments是任意的;它们只是简单的随着this
对象传入symbol generator的accessor中。例如,在默认配置下,不需要任何参数就可以生成一个64平方像素的圆。如果symbol generator有context,则生成的符号将作为一系列路径方法的调用呈现到此上下文中,函数无返回值。否则,返回一个路径数据字符串。
symbol.type([type])
如果指定了type,则设置符号类型为给定的函数或符号类型,并返回该line generator。如果不指定type,则返回当前的symbol type accessor,默认为:
function type() {
return circle;
}
另请参阅symbols,了解内置的符号类型。要想实现自定义符号类型,传入一个执行了symbolType.draw的对象。
symbol.size([size])
如果指定了size,则设置大小为给定的函数或数字,并返回该symbol generator。如果不指定size,则返回当前的size accessor,默认为:
function size() {
return 64;
}
指定大小为一个函数对于用size encoding(大小编码)构建一个散点图是非常有用的。如果你想缩放符号以适应给定的边界框,而不是缩放area,试试SVG的getBBox。
symbol.context([context])
如果指定了context,则设置上下文并返回该symbol generator。如果不指定context,则返回当前的上下文,默认为null。如果上下文不为null,则生成的符号将作为一系列路径方法的调用呈现到此上下文中。否则,返回一个路径数据字符串。
d3.symbols
一个包含所有内置符号类型:circle(圆)、cross(十字形)、diamond(钻石)、square(矩形)、star(星)、triangle(三角形)和wye的数组。当你想对分类数据使用形状编码时,这对构建一个ordinal scale的range非常有用。
d3.symbolCircle
圆形符号。
d3.symbolCross
四臂长度相等的十字形。
d3.symbolDiamond
菱形符号。
d3.symbolSquare
方形符号。
d3.symbolStar
五角星符号。
d3.symbolTriangle
向上的三角形符号。
d3.symbolWye
Y型符号。
d3.pointRadial(angle, radius)
以弧度为单位返回给定angle和radius的点 [x, y],在-y(12点)处为0,顺时针方向为正。
Custom Symbol Types
符号类型通常不会直接使用,而是传入symbol.type中。然而,如果没有内置类型满足你的需求,你可以通过下面的接口定义自己的符号类型实现。你还可以使用内置符号类型的底层接口作为symbol generator的替代品。
symbolType.draw(context, size)
将该符号类型根据指定的size以平方像素的形式呈现到指定的context中。context实现了CanvasPathMethods接口。(注意,这是CanvasRenderingContext2D接口的一个子集!)
Stacks
有些形状可以堆叠起来,一个挨一个。例如,每月销售额的条形图可以按产品类别分解成多系列条形图,垂直堆叠。这相当于通过一个有序的维度(如产品类别)细分条形图并应用颜色编码。
堆叠图表可以同时显示总体值和每个类别值;但是,通常比较难以在不同类别之间进行比较,因为只有堆叠的底部层是对齐的。所以,要小心选择堆叠的顺序,想想streamgraph。(另请参阅grouped charts)。
和pie generator一样,stack generator也不直接生成形状。它计算你可以传入area generator或直接使用的位置,比如说放置条形。
d3.stack()
用默认配置创建一个新的stack generator。
stack(data[, arguments…])
为给定data数组生成一个堆叠,返回代表每个系列的数组。arguments是任意的,它们只是简单的随着this
对象传入accessors。
每个系列由keys accessor定义;返回数组中的每个系列i对应第i个key。每个系列都是一个点数组,每个点j对应输入data的第j个元素。最后,每个点代表一个数组[y0,y1],其中y0为下限值(baseline),y1为上限值(topline);y0和y1的差值对应该点的计算值。每个系列的key可表示为series.key,index可表示为series.index。每个点的输入元素可表示为point.data。
例如,假设下表代表水果的月销售额:
Month | Apples | Bananas | Cherries | Dates |
---|---|---|---|---|
1/2015 | 3840 | 1920 | 960 | 400 |
2/2015 | 1600 | 1440 | 960 | 400 |
3/2015 | 640 | 960 | 640 | 400 |
4/2015 | 320 | 480 | 640 | 400 |
这可以用JavaScript表示为对象数组:
var data = [
{month: new Date(2015, 0, 1), apples: 3840, bananas: 1920, cherries: 960, dates: 400},
{month: new Date(2015, 1, 1), apples: 1600, bananas: 1440, cherries: 960, dates: 400},
{month: new Date(2015, 2, 1), apples: 640, bananas: 960, cherries: 640, dates: 400},
{month: new Date(2015, 3, 1), apples: 320, bananas: 480, cherries: 640, dates: 400}
];
为这个数据生成一个stack:
var stack = d3.stack()
.keys(["apples", "bananas", "cherries", "dates"])
.order(d3.stackOrderNone)
.offset(d3.stackOffsetNone);
var series = stack(data);
var series = stack(data);
生成的数组中每个series都有一个元素。每个系列每月都有一个点,每个点都有一个下限值和上限值以确定基线和背线:
[
[[ 0, 3840], [ 0, 1600], [ 0, 640], [ 0, 320]], // apples
[[3840, 5760], [1600, 3040], [ 640, 1600], [ 320, 800]], // bananas
[[5760, 6720], [3040, 4000], [1600, 2240], [ 800, 1440]], // cherries
[[6720, 7120], [4000, 4400], [2240, 2640], [1440, 1840]], // dates
]
然后,每个序列通常被传入area generator以渲染一张面积图,或者用于为条形图构造矩形。
stack.keys([keys])
如果指定了keys,则设置keys accessor为给定的函数或数组,并返回该stack generator。如果不指定keys,则返回当前的keys accessor,默认为空数组。每个key都会生成一个序列(层)。keys通常为字符串,但它们可以是任意值。序列的key会连同每个数据点传入value accessor,以计算点的值。
stack.value([value])
如果指定了value,则设置value accessor为给定的函数或数字,并返回该stack generator。如果不指定value,则返回当前的value accessor,默认为:
function value(d, key) {
return d[key];
}
因此,默认情况下,stack generator假定输入数据为对象数组,每个对象都暴露出具名属性和数字值;另请参阅stack。
stack.order([order])
如果指定了order,则设置order accessor为给定的函数或数组,并返回该stack generator。如果不指定order,则返回当前的order accessor,默认为stackOrderNone;使用key accessor给出的顺序。另请参阅stack orders了解内置的顺序。
如果order为一个函数,则传入生成的序列数组,并返回一个表示stack顺序的数字索引数组。例如,默认顺序定义为:
function orderNone(series) {
var n = series.length, o = new Array(n);
while (--n >= 0) o[n] = n;
return o;
}
stack顺序是在offset前计算的;因此,在计算顺序时,所有点的下限值都为0。每个序列的索引属性在顺序计算完成前也都还没有设置。
stack.offset([offset])
如果指定了offset,则设置offset accessor为给定的函数或数组,并返回该stack generator。如果不指定offset,则返回当前的offset accessor,默认为stackOffsetNone;使用0作为基线。另请参阅stack offsets了解内置的offsets。
如果offset为函数,则传入生成的序列数组和数字索引数组。然后offset函数负责更新序列数组下限值和上限值来进行布局。例如,默认的offset定义为:
function offsetNone(series, order) {
if (!((n = series.length) > 1)) return;
for (var i = 1, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
s0 = s1, s1 = series[order[i]];
for (var j = 0; j < m; ++j) {
s1[j][1] += s1[j][0] = s0[j][1];
}
}
}
Stack Orders
stack orders通常不直接使用,而是传入stack.order。
d3.stackOrderAscending(series)
返回一个序列,最小的序列(根据值的总和)位于底部。
d3.stackOrderDescending(series)
返回一个序列,最大的序列(根据值的总和)位于底部。
d3.stackOrderInsideOut(series)
返回一个序列顺序,较大的序列(根据值的总和)位于内部,而较小的序列位于外部。此顺序推荐用于streamgraphs和wiggle offset一起使用。另请参阅Byron和Wattenberg的Stacked Graphs—Geometry & Aesthetics。
d3.stackOrderNone(series)
返回给定序列顺序[0, 1, … n - 1],其中n为series中元素的个数。因此,stack顺序由key accessor给出。
d3.stackOrderReverse(series)
返回给定序列顺序的反向顺序 [n - 1, n - 2, … 0],其中n为series中元素的个数。因此,stack顺序由key accessor的反演给出。
Stack Offsets
stack offsets通常不直接使用,而是传入stack.offset。
d3.stackOffsetExpand(series, order)
应用0基线并normalizes(规范)每个点的值,背线始终为1.
d3.stackOffsetDiverging(series, order)
正值堆叠在0的上方,而负值在0的下方。
d3.stackOffsetNone(series, order)
应用一条0基线。
d3.stackOffsetSilhouette(series, order)
将0基线转向下,使得streamgraph的中点始终在0的位置。
d3.stackOffsetWiggle(series, order)
转换基线以最小化层的weighted wiggle。此offset推荐用于streamgraphs与inside-out order一起使用。另请参阅Bryon和Wattenberg的Stacked Graphs—Geometry & Aesthetics了解更多。