所以我想我的主要问题是我的数据并不像所有的d3演示一样。我制作了一个插件,将我的所有数据规范化为以下形式:
[{"name":"someName", "values":[{x1, y1}, {x2, y2}, ... {xn, yn}, ...]
所以这段代码适用于该行:
var line = d3.svg.line()
.x(function(d) { return x(d.x); })
.y(function(d) { return y(d.y); });
// data is a list of objects, each of which respresents a line
var series = svg.selectAll(".series")
.data(dataSimplified)
.enter().append("g")
.attr("class", "series");
series.append("path")
.attr("class", "line")
// the following function requires a list of things, like [{x0, y0}, {x1, y1}, ... {xn, yn}]
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.name); });
因此它基本上遍历每个“值”字段并执行行函数以获取x和y。但是,如果我为这些点做了类似的事情,它就行不通了!但是,以下内容有效:
// add points
for(var i=0; i<dataSimplified.length; i++){
for(var j=0; j<dataSimplified[i].values.length; j++){
svg.append("circle")
.attr("r", 3.5)
.attr("cx", function(d){ return x(dataSimplified[i].values[j].x); })
.attr("cy", function(d){ return y(dataSimplified[i].values[j].y); })
.attr("fill", function(d){ return color(dataSimplified[i].name); });
}
}
有没有比逐个添加积分更好的方法呢?为什么cx不接受像路径那样的列表?
答案 0 :(得分:4)
您可以再次为nested selections致电.data
(在这种情况下,嵌套在<circle>
标记内的<g>
标记。像这样:
series.selectAll('circle')
.data(function(d, i, j) { return d.values; })
.enter().append('circle')
.attr("r", 3.5)
.attr("cx", function(nd){ return x(nd.x); })
.attr("cy", function(nd){ return y(nd.y); })
.attr("fill", function(nd, i, j){ return color(dataSimplified[j].name); });
线与圆之间似乎不一致的原因是D3只是底层DOM节点(html或svg)上的一个薄层,并且不会从你那里抽象出来。所以在svg中,<path>
是一个包含内部点列表的标记,而<circle>
只是一个圆圈。因此,您对一个系列的结构将是这样的(假设您有三个数据点)。
<g><path/><circle/><circle/><circle/></g>
所以你的代码将反映出同样的结构。