web-dev-qa-db-ja.com

なぜd2.js v3は、v2がズームしないときにズームを実装するときに力グラフを壊すのですか?

D3.jsを使用して作成した強制レイアウトがあります

ドラッグ可能なフォースレイアウトの通常の機能とズーム機能の両方が必要です。

基本的には、ズームコードを( http://jsfiddle.net/nrabinowitz/QMKm3/ )からコピー/貼り付けました。これは、マイクボストックが( http://bl.ocks.org/mbostock/3680957 )で使用するズームと同じ方法です。

これが私のコードです: http://jsfiddle.net/kM4Hs/6/

ズームは正常に機能しますが、フォースレイアウトで単一のノードを選択してドラッグすることができません。

私は犯人が両方の著者が新しいd3.v3.jsではなくd3.v2.jsを使用しているという事実であることがわかりました。インポートをv2に変更すると、完全に機能します。ただし、可能であればv3を使用したいと思います。

<script type='text/javascript' src='http://d3js.org/d3.v3.min.js'></script>

versus

<script type='text/javascript' src='http://d3js.org/d3.v2.min.js'></script>

なぜv3はv2が強制レイアウトを壊さないのに強制レイアウトを壊すのですか?さらに重要なことに、それを修正するにはどうすればよいですか?

前もって感謝します!

37
Matthew Herbst

リリースノート を熟読すると、2.xの最終リリース(2.10.3)と最新のリリース3.2.7の間で変更されたすべての詳細な説明が表示されます。特に、リリース3.2.2以降:

デフォルトの動作を妨げないか、伝播を停止しないことにより、d3.behavior.drag、d3.behavior.zoom、およびd3.svg.brushでのドラッグジェスチャーの処理が改善されました。たとえば、mousedownはフォーカスを変更し、iframeの外でのmouseupは正しく機能し、タッチスタートは途切れません。

したがって、V2では、ズームイベントの伝播を停止することにより、ドラッグ動作がズーム動作よりも優先される可能性があります。 V3では、これは自動的に行われなくなり、どの動作をいつ優先するかを選択できます。

ノードをドラッグするときにドラッグ動作に優先順位を付けたい場合は、ドラッグ中の入力イベントに対して stopPropagation にする必要がありますこれらのイベントは、ズーム動作によるパンとして同時に解釈されません。 dragstartで伝播を停止するだけで十分です。

var drag = d3.behavior.drag()
    .on("dragstart", function() { d3.event.sourceEvent.stopPropagation(); })
    .on("drag", function() { /* handle drag event here */ });

強制レイアウトを使用している場合、コードは次のとおりです。

var drag = force.drag()
    .on("dragstart", function() { d3.event.sourceEvent.stopPropagation(); });

作業例:

drag and zoom

注:これら2つの動作を組み合わせると、ジェスチャーの解釈が曖昧になり、位置に非常に敏感になります。円をクリックすると、その円がドラッグされていると解釈されますが、1ピクセル離れた場所をクリックすると、背景をパンすると解釈できます。これらの動作を組み合わせるより堅牢な方法は、モダリティを使用することです。たとえば、ユーザーがSPACEキーを押したままにすると、クリックとドラッグは、クリック位置に関係なく、ドラッグではなくパンと解釈されます。このアプローチは、Adobe Photoshopなどの商用ソフトウェアで一般的に採用されています。

81
mbostock