3

私は別のstackoverflowの質問を見ていて、次のことを試しました。

d3.selectAll(links.filter(function(db) {
  return db.source.id == 'foo'
})).each(function(p) {
      console.log (p.source.id)
    })

そして、それが

TypeError:未定義のプロパティ'source'を読み取ることができません

フィルタリングされた選択は、.source.id値を持つオブジェクトの適切な配列として返されます(この例では、D3の強制ネットワークにある標準のリンク表記を使用しています)。

なぜこれがうまくいかないのか知りたいだけです。

4

1 に答える 1

7

次の 2 つの方法のどちらを使用しているかを明確にしてください。

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter https://github.com/mbostock/d3/wiki/Selections#wiki-filter

d3.selectAll 関数は、セレクター文字列または DOM ノードの配列を受け入れます。あなたの場合はどちらですか?

https://github.com/mbostock/d3/wiki/Selections#wiki-d3_selectAll

selection.each() コールバック関数の変数 p は、選択範囲内の要素にバインドされたデータに対応することに注意してください。

https://github.com/mbostock/d3/wiki/Selections#wiki-each


アップデート

リンク変数は、通常の JavaScript オブジェクトの配列のようです。d3.selectAll関数は DOM ノード (またはセレクター文字列) の配列を想定しているため、これは正しくありません。興味深いことに、通常の配列を引数として使用しても問題はありません。たとえば、引き続きselection.eachメソッドを呼び出すことができます。

selection.each(関数)

現在の選択範囲内の各要素に対して指定された関数を呼び出し、現在のデータム d とインデックス i を現在の DOM 要素の this コンテキストと共に渡します。この演算子は、他のほぼすべての演算子によって内部的に使用され、選択された各要素に対して任意のコードを呼び出すために使用できます。each 演算子は、コールバック関数内で d3.select(this) を使用することにより、再帰的に選択を処理するために使用できます。

ただし、選択はデータがバインドされた DOM ノードの実際の選択ではないため、関数の最初の引数 (通常は d、この場合は p) は未定義になります。

2 番目の引数であるインデックス i は、繰り返し処理する元の配列のインデックスに引き続き対応します。d3.selectAll(links).each(function(p, i) { console.log(links[i].source.id); })それがあなたのために働いた理由です。基本的に、この (非 d3) JavaScript 式と同じことを行っています。links.forEach(function(v, i) { console.log(links[i].source.id); })

あなたが見ていたもののもう1つの簡単な例:

// anti-pattern:
var arr = ['a', 'b', 'c'];
d3.selectAll(arr)
    .each(function(d, i) {
      console.log(d, i, arr[i]);
    });

コンソールへのログ:

undefined 0 "a"
undefined 1 "b"
undefined 2 "c"

したがって、代わりに、強制指向のレイアウトでリンクを検査しようとしている場合は、それらのリンクを表す DOM ノードを選択できます。D3 ライブラリに含まれている標準的な力の例: http://d3-example.herokuapp.com/examples/force/force.htmをコンソールから実行します。

d3.selectAll('line')
    .each(function(d, i) {
      console.log(d.source.index);
    });
于 2013-01-08T15:33:12.447 に答える