私はD3.jsのドキュメントを読んでいますが、ドキュメントの _selection.data
_メソッド を理解するのが難しいと感じています。
これは、ドキュメントに記載されているサンプルコードです。
_var matrix = [
[11975, 5871, 8916, 2868],
[ 1951, 10048, 2060, 6171],
[ 8010, 16145, 8090, 8045],
[ 1013, 990, 940, 6907]
];
var tr = d3.select("body").append("table").selectAll("tr")
.data(matrix)
.enter().append("tr");
var td = tr.selectAll("td")
.data(function(d) { return d; })
.enter().append("td")
.text(function(d) { return d; });
_
私はこれのほとんどを理解していますが、_var td
_ステートメントの.data(function(d) { return d; })
セクションで何が起こっているのでしょうか?
私の最良の推測は次のとおりです。
var tr
_ステートメントは、4要素配列を各trノードにバインドしましたvar td
_ステートメントは、その4要素配列をデータとして使用します。しかし、.data(function(d) { return d; })
は実際にそのデータをどのように取得し、何を返しますか?
あなたが書くとき:
….data(someArray).enter().append('foo');
D3は、配列の各エントリに1つずつ、<foo>
要素の束を作成します。さらに重要なことは、配列の各エントリのデータを__data__
プロパティとしてそのDOM要素に関連付けます。
これを試して:
var data = [ {msg:"Hello",cats:42}, {msg:"World",cats:17} ];
d3.select("body").selectAll("q").data(data).enter().append("q");
console.log( document.querySelector('q').__data__ );
(コンソールに)表示されるのは、最初に作成されたq
要素に関連付けられたオブジェクト{msg:"Hello",cats:42}
です。
後で行う場合:
d3.selectAll('q').data(function(d){
// stuff
});
d
の値は、その__data__
プロパティになります。 (この時点で、// stuff
を新しい値の配列を返すコードに置き換えることは、ユーザー次第です。)
別の例 HTML要素にバインドされたデータと、下位要素のデータのサブセットを再バインドする機能を示します。
このコードが何をしているのかを理解する鍵は、選択が配列の配列 DOM要素であることを認識することです。最も外側の配列は「選択」と呼ばれ、内側の配列は「グループ」と呼ばれ、これらのグループにはDOM要素が含まれます。これをテストするには、d3js.orgのコンソールにアクセスし、d3.selectAll( 'p')などの選択を行います。「p」要素を含む配列を含む配列が表示されます。
この例では、selectAll( 'tr')を最初に呼び出すと、すべての 'tr'要素を含む単一のグループで選択を取得します。次に、matrix
の各要素が各 'tr'要素に一致します。
ただし、その選択に対してselectAll( 'td')を呼び出すと、選択にはすでに 'tr'要素のグループが含まれています。今回は、これらの各要素はそれぞれ 'td'要素のグループになります。グループは単なる配列ですが、古い選択(この場合は 'tr'要素)を参照するparentNodeプロパティも持っています。
この新しい「td」要素の選択でdata(function(d) { return d; })
を呼び出すと、d
は各グループの親ノードにバインドされたデータを表します。したがって、この例では、最初のグループの「td」は配列にバインドされます[11975、5871、8916、2868]。 「td」の2番目のグループは[1951、10048、2060、6171]にバインドされています。
マイクボストックの選択とデータバインディングに関する優れた説明は、ここで読むことができます。 http://bost.ocks.org/mike/selection/
使用されているデータのインデックスを表示するには、カウンターiを使用します。
var tr = d3.select("body").append("table").selectAll("tr")
.data(matrix)
.enter().append("tr") //create a row for each data entry, first index
.text(function(d, i) { return i}); // show the index i.e. d[0][] then d[1][] etc.
var td = tr.selectAll("td")
.data(function(d) { return d; })
.enter().append("td")
.style("background-color", "yellow") //show each cell
.text(function(d,i) { return i + " " + d; }); // i.e d[from the tr][0] then d[from the tr][1]...