我目前正在使用格式如下的JSON对象数组在数据点处组装一些带圆圈的折线图:
var data = [{
"name": "metric1",
"datapoints": [
[10.0, 1333519140],
[48.0, 1333519200]
]
}, {
"name": "metric2",
"datapoints": [
[48.0, 1333519200],
[12.0, 1333519260]
]
}]
我希望每个指标都有一个颜色,所以我试图根据索引为它们着色 数组数据中的对象。我目前用于放置圆圈的代码如下:
// We bind an svg group to each metric.
var metric_groups = this.vis.selectAll("g.metric_group")
.data(data).enter()
.append("g")
.attr("class", "metric_group");
// Then bind a circle for each datapoint.
var circles = metric_groups.selectAll("circle")
.data(function(d) { return d.datapoints; });
circles.enter().append("circle")
.attr("r", 3.5);
现在,如果我将最后一位改为:
circles.enter().append("circle")
.attr("r", 3.5);
.style("fill", function(d,i) { return i%2 ? "red" : "blue"; }
我可以看到交替的红色和蓝色圆圈 从Nested Selections : 'Nesting and Index'那里得到一些建议,我试过了:
circles.enter().append("circle")
.attr("r", 3.5);
.style("fill", function(d,i,j) { return j%2 ? "red" : "blue"; }
哪个不起作用(j未定义),大概是因为我们在命名属性datapoints中,而不是数组元素。如何在不改变数据结构的情况下进行我想要的着色?谢谢!
答案 0 :(得分:3)
这里最简单的方法是让圆圈从父G元素继承填充样式:
var color = d3.scale.category20();
var metricGroup = vis.selectAll(".metric-group")
.data(data)
.enter().append("g")
.attr("class", "metric-group")
.style("fill", function(d) { return color(d.name); });
var circle = metricGroup.selectAll("circle")
.data(function(d) { return d.datapoints; })
.enter().append("circle")
.attr("r", 3.5);
如果您将分类颜色定义为CSS类,您还可以使用动态类名并以这种方式继承:
var metricGroup = vis.selectAll(".metric-group")
.data(data)
.enter().append("g")
.attr("class", function(d) { return "metric-group " + color(d.name); });
使用相应的CSS:
.metric1 circle { fill: red; }
.metric2 circle { fill: blue; }
另一种方法是使用each访问父数据:
metricGroup.each(function(p, j) {
d3.select(this).selectAll("circle")
.data(p.datapoints)
.enter().append("circle")
.attr("r", 3.5)
.style("fill", color(p.name));
});
我还认为使用组索引j
会起作用;我不确定为什么它没有为你定义,但你的代码示例中有一个虚假的分号(在.attr("r", 3.5);
中),所以有可能还有别的东西在继续。无论如何,从数据而不是组索引中获取分类颜色更为惯用,所以我使用上述技术之一。
答案 1 :(得分:1)
在我的一个可视化中,我遇到了同样的问题。我的解决方案如下(适用于您的示例):
var count = 0;
var color = d3.scale.category20();
var metric_groups = this.vis.selectAll("g.metric_group")
.data(data).enter()
.append("g")
.attr("class", "metric_group");
var circles = metric_groups.selectAll("circle")
.data(function(d) {return d.datapoints;});
circles.enter().append("circle")
.attr("r", 3.5)
.style("fill", function(d,i){
d.number = count;
count++;
return color(d.number);
});
关键是为每个数据提供一个唯一的属性,可用于为相应的元素提供不同组的唯一颜色。
我希望这有助于或支持您找到类似的解决方案!