7

D3 2.4.2 を使用して、次のような多数のパス要素を作成します。

for (var i = 0; i < pathIndices.length; i++) {
  graph.append("svg:path")
    .style("stroke", colors[pathIndices[i]])
    .style("stroke-width", "2.5px")
    .style("fill", "none")
    .attr("class", PATH_CLASS)
    .attr("id", PATH_ID_PREFIX + pathIndices[i])
    .attr("d", lineFunc(data))[0];
}

それらはすべて、期待どおりに画面に描画されます。後で、ユーザーが何らかの入力を行ったときに、そのうちの 1 つを前面に表示したいので、これを行うイベント ハンドラーを用意しました。

var pathToHighlight = selectPath(pathIndex);
var paths = d3.selectAll("." + PATH_CLASS);
paths.sort(
  function(a, b) {
    if (a === pathToHighlight) {
      return -1;
    }
    else if (b === pathToHighlight) {
      return 1;
    }
    else {
      return 0;
    }
  }
);

Chrome でブレークポイントを設定すると、ここでのパスの選択が成功したことが示されます (pathsは SVGPathElements の配列です)。しかし、コードは何もせず、sort 関数内にブレークポイントを設定すると、常に未定義であることが示されaますb。d3 コードに進むと、内部関数d3_selection_sortComparatorが適切な引数を使用してコンパレーターを呼び出すと、独自の未定義__data__のメンバーと AND 結合されていることを除いて、次のundefinedように渡されることがわかります。

// a and b are correct, but a.__data__ and b.__data__ are undefined
return comparator(a && a.__data__, b && b.__data__);

ここで何が間違っていますか?私のパスは画面に正しく描画されるため、正しいデータが必要なようです。右?

編集:画像:

パスの内容

パラメータ a と b は定義されていません

4

3 に答える 3

5

selection.sort期待しているように聞こえるときに使用していArray.sortます。このメソッドは、要素およびにバインドされたデータselection.sortに基づいて選択をソートするために使用されます。要素にデータがバインドされていない場合、これは機能しません。他の何かに基づいてセレクションをソートしたい場合 (ある要素参照が別の要素参照と等しいことをテストするなど)、次のように呼び出す前に、セレクションから要素の配列を取得する必要があります。ab.sort()

// `paths` is a Selection
var paths = d3.selectAll("." + PATH_CLASS);
// `pathElements` is an Array
var pathElements = paths[0];

pathElements.sort(function(a,b) {
  // now `a` and `b` are Element references
  // ...
})

次に、DOM の順序を結果の配列の順序に一致させるという追加の手順を実行する必要があります。

とはいえ、前面に表示したいだけの場合は、pathToHighlightその 1 つの要素を DOM に再度追加することをお勧めします。

が選択されている場合pathToHighlightは、次のようにします。

var el = pathToHighlight.node();
el.parentNode.appendChild(el);

または、それがすでに Element 参照である場合は、次のようにすることができます。

pathToHighlight.parentNode.appendChild(pathToHighlight);
于 2014-10-04T13:29:33.253 に答える
2

@jshanley が述べたように、選択した要素にはデータがバインドされていません (__data__ 属性は未定義です)。selection.sort に渡される関数は、要素にバインドされているデータを受け取りますが、あなたの場合は未定義です。

datum() 関数を使用して、選択した要素をデータにバインドできます。

これを試して:

paths.datum(function () { return this };).sort(...)

これにより、要素がそれ自体にバインドされ、並べ替え関数で参照できるようになります。

于 2014-10-08T12:08:04.467 に答える
0

.datum()の代わりに関数を試していただけます.__data__か?

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

selection.datum([value])
選択された各要素のバインドされたデータを取得または設定します

于 2012-08-03T09:34:18.357 に答える