“简单的” D3.js区域图
让我们来:
X | ÿ |
---|---|
0 | 10 |
1个 | 15 |
2 | 35 |
3 | 20 |
和做:
D3.js弯弯曲曲,我发现D3.js Wiki上的示例解释得太少,正在进行的事情也太多了。在此示例中,我将向您展示如何制作我能设计的最简单的面积图。如果您想直接跳到“答案”,请参阅完整的JavaScript。
D3.js不是一个K线走势图库。这是一个K线走势图零件库。该库感觉就像是SVG和数据操作的混搭,上面撒了一些糖。尽管具有极大的灵活性,但是灵活性是以复杂性为代价的。让我们潜入。
要构建K线走势图,我们需要:数据,SVG容器,边距,X轴,Y轴,区域形状本身以及一些CSS,以使其看起来更漂亮。
数据
我们不会把TSV或CSV加载程序或任何回调的东西弄乱。这是简单明了的数据。
var data = (
{ x: 0, y: 10, },
{ x: 1, y: 15, },
{ x: 2, y: 35, },
{ x: 3, y: 20, },
);
SVG
D3使用SVG(可缩放矢量图形)绘制形状。可以创建一个新的 标记,但我在HTML源代码中添加了以下内容。
保证金
D3中的K线走势图没有边距,但是主要的D3作者经常谈论定义常规边距。这个想法是要留出一些余地并定义一个SVG组(即 g
标签)设置为这些边距边界。该代码仅将组标记视为可绘制区域。
var margin = {top: 20, right: 20, bottom: 40, left: 50},
width = 575 - margin.left - margin.right,
height = 350 - margin.top - margin.bottom;
轴数
为了以可缩放的方式绘制数据,D3需要能够将数据(例如,x = 0,y = 10)映射到像素位置。我们必须获取X数据并将其设置在轴上,以使最大X值(即3)与K线走势图区域的像素宽度匹配。因为D3非常灵活,所以X和Y必须独立定义。
在数学课上,您可能被教导X代表域,Y代表范围。不幸的是,D3也使用域/范围术语来应用于轴。我们必须将X数据(0-3)作为域,并将K线走势图水平尺寸(0- width
)作为范围。 Y轴也必须采用相同的思路(将0-35应用于K线走势图垂直尺寸)。
你可以想到 x
和 y
变量作为转换函数,它们接受域值并将其转换为像素大小。 xAxis
和 yAxis
指示轴应该去哪里。
var x = d3.scale.linear()
.domain((0, d3.max(data, function(d) { return d.x; })))
.range((0, width));
var y = d3.scale.linear()
.domain((0, d3.max(data, function(d) { return d.y; })))
.range((height, 0));
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
区域
区域函数将每个数据点(如(2,35))转换为描述形状的信息。每个对应一个x位置,一个上y位置, y1
,以及较低的y位置, y0
。奇怪的是 y0
设置为的常数 height
。当您知道SVG相对于图形的左上角定位时,这很有意义。任何距离“向下”都是正数,因此正数 height
表示图形的底部。
var area = d3.svg.area()
.x(function(d) { return x(d.x); })
.y0(height)
.y1(function(d) { return y(d.y); });
放在一起
到目前为止,除了定义一些数据和函数外,我们什么也没做。现在我们需要使这些功能起作用。
var svg = d3.select("svg#area")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("path")
.datum(data)
.attr("class", "area")
.attr("d", area);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
的变量定义 svg
抓住 svg
带有ID的标签 area
并添加一个组标签, g
,以定义SVG中的边距。所有的绘图都将在其中进行 g
标签。
下一节将添加 path
。这是数据和区域功能相遇的地方。这是整个示例的重点。 D3使用每个数据点并将其传递给 area
功能。的 area
函数将数据转换为SVG中路径上的位置。它将导致:
class="area" d="M0,214.28571428571428L168.33333333333331,
171.42857142857142L336.66666666666663,0L505,128.57142857142858L505,
300L336.66666666666663,300L168.33333333333331,300L0,300Z"/>
最后两部分将轴添加到SVG。关于它们,没有太多要说的。
变得漂亮
在“将所有内容放在一起”中,我忽略了 .attr("class", "area")
解释。 D3可以添加带有 attr()
。我加了一些 class
属性,以便可以设置图形样式。 SVG使用的属性与标准HTML标签不同,但是下面的样式使该图具有简单的外观。
svg { border: 1px solid #dedede; }
.axis path, .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.area { fill: #4ca3bd; }
这篇文章首先出现在mattlayman.com上。