web-dev-qa-db-fra.com

Pourquoi d3.js v3 brise-t-il mon graphique de force lors de l'implémentation du zoom alors que v2 ne fonctionne pas?

J'ai une disposition de force que j'ai créée à l'aide de d3.js

Je voudrais avoir à la fois la fonctionnalité normale d'une disposition de force déplaçable ainsi que la possibilité de zoomer.

J'ai essentiellement copié/collé le code de zoom de ( http://jsfiddle.net/nrabinowitz/QMKm3/ ). C'est la même façon de zoomer que Mike Bostock utilise dans ( http://bl.ocks.org/mbostock/3680957 ).

Voici mon code: http://jsfiddle.net/kM4Hs/6/

Le zoom fonctionne bien, mais je ne peux pas sélectionner des nœuds uniques dans la disposition de force et les faire glisser.

J'ai trouvé que le coupable était le fait que les deux auteurs utilisent d3.v2.js plutôt que le nouveau d3.v3.js. Lorsque je change mon importation en v2, cela fonctionne parfaitement. Cependant, je voudrais utiliser la v3 si possible.

<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>

pourquoi la v3 brise-t-elle la disposition de la force alors que la v2 ne fonctionne pas, et plus important encore, que puis-je faire pour y remédier?

Merci d'avance!

37
Matthew Herbst

Si vous parcourez les notes de version , vous verrez une explication complète de tout ce qui a changé entre la version finale de 2.x (2.10.3) et la version la plus récente, 3.2.7. En particulier, à partir de la version 3.2.2:

Meilleure gestion des mouvements de glissement dans d3.behavior.drag, d3.behavior.zoom et d3.svg.brush en n'empêchant pas les comportements par défaut ou en arrêtant la propagation. Par exemple, la mousedown change désormais de focus, la mouseup en dehors d'une iframe fonctionne correctement et le touchstart ne bégaie pas.

Ainsi, dans V2, le comportement de glissement pourrait avoir la priorité sur le comportement de zoom en arrêtant la propagation sur les événements de zoom. Dans la V3, cela ne se produit plus automatiquement, vous donnant le choix du comportement prioritaire et du moment.

Si vous souhaitez donner la priorité au comportement de glissement lors du glissement des nœuds, vous devez stopPropagation sur les événements d'entrée pendant le glissement afin que ces événements ne sont pas interprétés simultanément comme un panoramique par le comportement du zoom. Arrêter la propagation sur dragstart suffit:

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

Si vous utilisez une disposition forcée, le code est:

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

Exemple de travail:

drag and zoom

Remarque: la combinaison de ces deux comportements signifie que l'interprétation des gestes est ambiguë et très sensible à la position. Un clic sur un cercle est interprété comme faisant glisser ce cercle, tandis qu'un clic à un pixel de distance peut être interprété comme un panoramique de l'arrière-plan. Une méthode plus robuste pour combiner ces comportements consiste à utiliser la modalité. Par exemple, si l'utilisateur maintient la touche ESPACE enfoncée, cliquer et faire glisser est interprété comme un panoramique plutôt que de glisser, quel que soit l'emplacement du clic. Cette approche est couramment utilisée dans les logiciels commerciaux tels qu'Adobe Photoshop.

81
mbostock