D3 を使用して生成された散布図があります。プロット上の点 (SVG 円) はクリックして選択でき、領域は D3 ブラシを使用して選択できます。
円がクリック イベントを確実に受け取るようにするには、最初にブラシを作成して、円がその上にくるようにします。残念ながら、これは、カーソルがプロット内のポイント上にあるときに、ドラッグしてブラシ範囲を作成できないことを意味します。
ホバー イベントとクリック イベントを円に渡す方法はありますが、ブラシでドラッグ関連のイベントを処理する方法はありますか?
D3 を使用して生成された散布図があります。プロット上の点 (SVG 円) はクリックして選択でき、領域は D3 ブラシを使用して選択できます。
円がクリック イベントを確実に受け取るようにするには、最初にブラシを作成して、円がその上にくるようにします。残念ながら、これは、カーソルがプロット内のポイント上にあるときに、ドラッグしてブラシ範囲を作成できないことを意味します。
ホバー イベントとクリック イベントを円に渡す方法はありますが、ブラシでドラッグ関連のイベントを処理する方法はありますか?
これは実現できますが、D3 ブラシ API を使用する必要があります(以下の注を参照)。
これはhttp://bl.ocks.org/4747894の例です。
brush要素は円の後ろにありますmousedownます。(他のイベントにも対応できます。)brush要素は適切に動作します。D3 ソース コードをトレースして確認すると、ブラシの上の要素からイベントが発生しextentたときに が正しくリセットされていないことがわかります。これは、要素のリスナーでブラシの をリセットすることで修正できます。mousemovecircleextentmousedowncircle
circles.on("mousedown", function (d, i) {
// _svg_ is the node on which the brush has been created
// x is the x-scale, y is the y-scale
var xy = d3.mouse(svg.node()),
xInv = x.invert(xy[0]),
yInv = y.invert(xy[1]);
// Reset brush's extent
brush.extent([[xInv, yInv], [xInv, yInv]]);
// Do other stuff which we wanted to do in this listener
});
注: API に従って、ブラシの選択は の呼び出し時に自動的に更新されません.extent(values)。円をクリックするだけで はリセットされますextentが、選択した内容は再描画されません。の内部で別の選択が開始されたcircle場合、または円の外側と現在の選択をクリックして選択が破棄されます。質問からわかるように、これは望ましい動作です。extentただし、これにより、ブラシの内容がグラフに表示される選択になるという前提で記述されたコードが壊れる可能性があります。
使用selection.on: http://jsfiddle.net/NH6zD/1
var target,
dimensions = {width: 200, height: 200},
svg = d3.select("body").append("svg").attr(dimensions),
rect = svg.append("rect").attr(dimensions); // Must be beneath circles
svg
.on("mousedown", function() {
target = d3.event.target || d3.event.srcElement;
if ( target === rect.node() ) {
/* Brush */
} else {
/* Circle */
}
})
.on("mousemove", function() {
if (!target) return;
if ( target === svg.rect() ) {
/* Brush */
} else {
var mouse = d3.mouse(svg.node());
target.attr({x: mouse[0], y: mouse[1]});
}
});
(function(exit) {
for (var i in exit) svg.on(exit[i], function() { target = undefined; });
})(["mouseout", "mouseup"]);