37

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

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

私は基本的に( http://jsfiddle.net/nrabinowitz/QMKm3/ )からズームコードをコピーして貼り付けました。これは、Mike Bostock が ( 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>

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

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

前もって感謝します!

4

1 に答える 1

81

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

d3.behavior.drag、d3.behavior.zoom、d3.svg.brush でのドラッグ ジェスチャの処理が改善されました。たとえば、mousedown でフォーカスが変更されるようになり、iframe の外側で mouseup が正しく機能し、touchstart がスタッターしなくなりました。

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

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

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(); });

作業例:

ドラッグしてズーム

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

于 2013-07-31T16:44:53.767 に答える