web-dev-qa-db-ja.com

enter()の選択は、追加/挿入後に再利用できますか?

データ結合を使用して、データ要素ごとに2つの新しい要素を追加するシナリオがあります。

私はもともと次のようなことをしていました:

var y = d3.selectAll("line")
    .data([123, 456]);

y.enter().append("line");  // assume attr and style set
y.enter().append("line");

y.transition()...

考え抜く前に、トランジションで使用される更新選択には、入力選択からのマージされた追加が含まれることを期待していました。しかしもちろん、データ要素ごとの選択にはスロットが1つしかないため、これは機能しませんでした。

そこで、同じenter()選択を2回使用するようにコードを変更しましたが、遷移を実行するために新しい要素に対して再選択しました。

このアプローチはうまくいきましたが、私の質問は、これが物事を進めるための推奨される方法であるかどうかです。追加/挿入した後、必ずenter()の使用を停止する必要がありますか?または、更新の選択に最後に作成された要素のみが含まれることを覚えている限り、それを使用して複数の要素を作成しても大丈夫ですか?

これが間違っていることが判明した場合、これを達成するためのより良い方法は何ですか?

38
Scott Cameron

いいえ。データ結合の目的は、 要素をデータと同期する 、必要に応じて要素を作成、削除、または更新することです。要素を2回作成すると、要素はバインドされたデータ配列と1対1で対応しなくなります。

2つの要素を各データに対応させたい場合は、最初にグループ(G)要素を追加して、データからへの1対1のマッピングを確立します。要素。次に、必要に応じて子要素を追加します。結果の構造は次のようになります。

<g>
  <line class="line1"></line>
  <line class="line2"></line>
</g>
<g>
  <line class="line1"></line>
  <line class="line2"></line>
</g>

例えば:

var g = svg.selectAll("g")
    .data([123, 456]);

var gEnter = g.enter().append("g");
gEnter.append("line").attr("class", "line1");
gEnter.append("line").attr("class", "line2");
59
mbostock