2012-04-08 92 views
3

着色多行我目前组装与数据点内有一定的线图,从格式化像这样JSON对象的数组:D3:从嵌套数据

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是不确定的),大概是因为我们在命名的属性数据点,而不是一个数组元素。如何在不改变数据结构的情况下去做我想要的着色?谢谢!

+0

我通过设置组的样式而不是圆圈解决了这个问题(为什么需要我在堆栈溢出上发布才能想到这一点?)。我仍然很欣赏较少的work-around-y答案(例如,对于组内的圆圈和路径会需要不同样式,或者孩子的属性是无论如何都不能继承的情况)。 – 2012-04-08 23:26:01

回答

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

在我的一个可视化中,我遇到了同样的问题。我的解决办法是以下的(适合于您的示例):

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); 
    }); 

的关键是要得到的每个数据的唯一属性,该属性可以被用于产生相应的元件在不同的基团的独特颜色。

我希望这有助于或支持您找到类似的解决方案!

+0

非常感谢您的回答!对不起,如果我误解了这一点,但是这段代码看起来会为每个圆圈分配一个独特的颜色,这是解决不同的问题。我的问题是希望同一行中的每个圆都具有相同的颜色。看起来我可能会想出类似的东西,但我想知道是否有更习惯的方式。 – 2012-04-09 22:22:59

+0

啊,现在我明白了问题所在!我会考虑的! – EightBitBoy 2012-04-09 23:43:05

+0

另一个方法是使用for循环:遍历指标并绘制循环内的每个图形和相应的圆。这样做不是很漂亮,但它确实有效。 – EightBitBoy 2012-04-10 00:02:20