4

我目前正在从格式如下的 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 未定义),大概是因为我们在命名属性数据点中,而不是在数组元素中。我如何在不改变数据结构的情况下进行我想要的着色?谢谢!

4

2 回答 2

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会起作用;我不确定为什么它对您来说是未定义的,但是您的代码示例(in .attr("r", 3.5);)中有一个虚假的分号,所以可能还有其他事情发生。无论如何,从数据而不是组索引中获取分类颜色更为惯用,因此我将使用上述技术之一。

于 2012-04-10T14:50:09.807 回答
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);
  });

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

我希望这可以帮助或支持您找到类似的解决方案!

于 2012-04-09T21:30:20.190 回答