まず、d3.jsを使用して、さまざまなサイズの円を配列で表示しています。マウスオーバーで、マウスオーバーされた円が大きくなるようにします。現在、レンダリングされると、他の複数の円の後ろに隠れます。どうすれば修正できますか?
コードサンプルを次に示します。
.on("mouseover", function() {
d3.select(this).attr("r", function(d) { return 100; })
})
ソートと順序のメソッドを使用しようとしましたが、機能しませんでした。私はそれを正しくやらなかったと確信しています。何かご意見は?
オブジェクトの順序を変更し、マウスオーバーした円を最後に追加した要素にする必要があります。ここに見られるように: https://Gist.github.com/3922684 そして nautat で示唆されているように、メインスクリプトの前に以下を定義する必要があります:
d3.selection.prototype.moveToFront = function() {
return this.each(function(){
this.parentNode.appendChild(this);
});
};
次に、マウスオーバーでオブジェクトのmoveToFront
関数(たとえばcircles
)を呼び出す必要があります。
circles.on("mouseover",function(){
var sel = d3.select(this);
sel.moveToFront();
});
Edit:Henrik Nordberg で示唆されているように、.data()
の2番目の引数を使用してデータをDOMにバインドする必要があります。これは、要素のバインドを失わないために必要です。詳細については、ヘンリックの答えを読んでください(そして、賛成してください!)。一般的なアドバイスとして、d3の完全なパフォーマンス機能を活用するために、DOMにデータをバインドするときは、常に.data()
の2番目の引数を使用します。
Edit:Clemens Tolboom で述べたように、逆関数は次のようになります:
d3.selection.prototype.moveToBack = function() {
this.each(function() {
this.parentNode.firstChild
&& this.parentNode.insertBefore(this, firstChild);
}
});
};
moveToFront()
メソッドを使用する場合は、data()
joinメソッドに2番目の引数を指定していることを確認してください。指定しないと、データがDOMと同期しなくなります。
d3.jsは、データ(parse()
に提供される)メソッドを、作成したDOM要素と結合します。上記で提案したようにDOMを操作すると、d3.jsは、data()
呼び出しで各データ「ポイント」に一意の値を指定しない限り、どのDOM要素がどのデータ「ポイント」に対応するかを知りません APIリファレンス 表示:
.data(data, function(d) { return d.name; })
D3バージョン4の時点では、このタイプの動作を自分で実装することなく処理する組み込み関数のセットがあります。詳細については、 d3v4 documentation を参照してください。
要するに、要素を前面に表示するには、selection.raise()
を使用します
selection.raise()
親の最後の子として、選択した各要素を順番に再挿入します。に相当:
selection.each(function() {
this.parentNode.appendChild(this);
});
IE9での苦痛な経験から、parentNode.appendChildを使用すると、ノードでイベントハンドラーが失われる可能性があります。そのため、私は別のアプローチを使用する傾向があります。つまり、選択したノードが他のノードよりも上になるようにノードをソートします。
.on("mouseover", function(selected) {
vis.selectAll('.node')
.sort(function(a, b) {
if (a.id === selected.id) {
return 1;
} else {
if (b.id === selected.id) {
return -1;
} else {
return 0;
}
}
});
})