Javascript d3:为嵌套数据中的多行着色

Javascript d3:为嵌套数据中的多行着色,javascript,d3.js,Javascript,D3.js,我目前正在从JSON对象数组的数据点组装一些线图,格式如下: var data = [{ "name": "metric1", "datapoints": [ [10.0, 1333519140], [48.0, 1333519200] ] }, { "name": "metric2", "datapoints": [ [48.0, 1333519200], [12.0, 1333519260

我目前正在从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"; }
我看到红色和蓝色相间的圆圈,这是意料之中的。
我听取了他的一些建议,试着:

circles.enter().append("circle")
  .attr("r", 3.5);
  .style("fill", function(d,i,j) { return j%2 ? "red" : "blue"; }

这不起作用(j未定义),可能是因为我们在命名属性datapoints中,而不是数组元素中。在不改变数据结构的情况下,我如何进行我想要的着色?谢谢

在我的一次想象中,我也遇到了同样的问题。我的解决方案如下(适用于您的示例):

关键是为每个数据赋予一个唯一的属性,该属性可用于为不同组中的相应元素赋予唯一的颜色


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

这里最简单的方法是让圆继承父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; }
另一种方法是使用访问父数据:

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);
中)有一个虚假的分号,所以可能还有其他原因。无论如何,从数据而不是组索引中导出分类颜色更为惯用,因此我会使用上述技术之一。

我通过在组而不是圆上设置样式来解决了这个问题(为什么我在堆栈溢出上发帖才想到这一点?)。我仍然希望得到一个不太周全的答案(例如,如果一个群体中的圆圈和路径需要不同的样式,或者孩子的财产由于任何原因都无法继承),非常感谢你的回答!抱歉,如果我误解了这一点,但这段代码看起来会为每个圆指定一个唯一的颜色,这有点解决了一个不同的问题。我的问题是希望同一行中的每个圆具有相同的颜色。看起来我可能会想出类似的方法,但我想知道是否有更惯用的方法。啊,现在我知道问题出在哪里了!我会考虑的!另一种方法是使用for循环:迭代度量并在循环内绘制每个图和相应的圆。这样做并不漂亮,但确实有效。
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));
});