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

おそらく、配列要素ではなく、名前付きプロパティのデータポイントにいるためです。データ構造を変更せずに、必要なカラーリングを行うにはどうすればよいですか? ありがとう!

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

もう 1 つの方法は、親データにアクセスするために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);) に偽のセミコロンがあるため、何か他のことが起こっている可能性があります。いずれにせよ、グループ インデックスではなく、データからカテゴリ別の色を導き出す方が慣用的であるため、上記の手法のいずれかを使用します。

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

重要なのは、各データムに一意の属性を与えることです。これを使用して、対応する要素に異なるグループ間で一意の色を与えることができます。

これが、同様の解決策を見つけるのに役立つか、サポートしてくれることを願っています!

于 2012-04-09T21:30:20.190 に答える