37

私は D3 を初めて使用し、構造化データの処理について何かを見つけるためにすでに数時間を費やしましたが、肯定的な結果はありませんでした。以下のデータ構造を使用して棒グラフを作成したいと思います。バーは (水平に) 描画されますが、ユーザー "jim" に対してのみです。

var data = [{"user":"jim","scores":[40,20,30,24,18,40]},
            {"user":"ray","scores":[24,20,30,41,12,34]}];

var chart = d3.select("div#charts").append("svg")                                   
              .data(data)
              .attr("class","chart")
              .attr("width",800)
              .attr("height",350);

chart.selectAll("rect")    
    .data(function(d){return d3.values(d.scores);})    
    .enter().append("rect")
    .attr("y", function(d,i){return i * 20;})
    .attr("width",function(d){return d;})
    .attr("height", 20);

誰かが私が間違ったことを指摘できますか?

4

2 に答える 2

99

selection.dataを介してデータを選択範囲に結合する場合、データ配列内の要素の数は、選択範囲内の要素の数と一致する必要があります。データ配列には2つの要素(JimとRay用)がありますが、バインドする選択には1つのSVG要素しかありません。複数のSVG要素を作成しようとしていますか、それともジムとレイの両方のスコアを同じSVG要素に配置しようとしていますか?

両方のデータ要素を単一のSVG要素にバインドする場合は、データを別の配列でラップできます。

var chart = d3.select("#charts").append("svg")
    .data([data])
    .attr("class", "chart")
    …

または、 selection.datumを使用します。これは、結合を計算せずにデータを直接バインドします。

var chart = d3.select("#charts").append("svg")
    .datum(data)
    .attr("class", "chart")
    …

人ごとに複数のSVG要素を作成する場合は、データ結合が必要です。

var chart = d3.select("#charts").selectAll("svg")
    .data(data)
  .enter().append("svg")
    .attr("class", "chart")
    …

2番目の問題は、配列でd3.valuesを使用してはならないことです。その関数は、オブジェクトの値を抽出するためのものです。1人あたり1つのSVG要素(つまり、この例では2つ)が必要であるとすると、rectのデータは、その人に関連付けられたスコアになります。

var rect = chart.selectAll("rect")
    .data(function(d) { return d.scores; })
  .enter().append("rect")
    …

まだ読んでいない場合は、次のチュートリアルを読むことをお勧めします。

于 2012-04-10T15:18:45.850 に答える
1

これにより、mbostock の優れた回答に加えて、ネストされた側面が明確になる場合があります。

データには 2 度の入れ子があります。2 つのオブジェクトの配列があり、それぞれに int の配列があります。最終的な画像にこれらの違いを反映させたい場合は、それぞれを結合する必要があります。

1 つの解決策を次に示します。各ユーザーは groupg要素で表され、各スコアは で表されますrect。これを行うにはいくつかの方法がありますdatum。svg で使用してから、各 で恒等関数を使用するかg、または でデータを直接結合できますgdataonを使用するのgがより一般的ですが、ここでは両方の方法を示します。

SVG でデータムを使用する:

var chart = d3.select('body').append('svg')
  .datum(data)             // <---- datum
  .attr('width',800)
  .attr('height',350)
  .selectAll('g')
  .data(function(d){ return d; })  // <----- identity function
  .enter().append('g')
    .attr('class', function(d) { return d.user; })
    .attr('transform', function(d, i) { return 'translate(0, ' + i * 140 + ')'; })
    .selectAll('rect')
    .data(function(d) { return d.scores; })
    .enter().append('rect')
      .attr('y', function(d, i) { return i * 20; })
      .attr('width', function(d) { return d; })
      .attr('height', 20);

グループ ( g) 要素でデータを使用する:

var chart = d3.select('body').append('svg')
  .attr('width',800)
  .attr('height',350)
  .selectAll('g')
  .data(data)          // <--- attach directly to the g
  .enter().append('g')
    .attr('class', function(d) { return d.user; })
    .attr('transform', function(d, i) { return 'translate(0, ' + i * 140 + ')'; })
    .selectAll('rect')
    .data(function(d) { return d.scores; })
    .enter().append('rect')
      .attr('y', function(d, i) { return i * 20; })
      .attr('width', function(d) { return d; })
      .attr('height', 20);

繰り返しますが、これらの g 要素を作成する必要はありませんが、そうすることで、ユーザー スコアを別の方法で表すことができるようになり (変換とは異なる y を持ちます)、次のように別のスタイルを与えることもできます。

.jim {
  fill: red;
}
.ray {
  fill: blue;
}
于 2015-08-17T18:14:09.960 に答える