2012-12-04 3 views
21

Diese Frage sieht ähnlich aus wie this one, aber ich bin immer noch nicht in der Lage herauszufinden, ob es möglich ist, d3.behavior.zoom zu verwenden, aber ohne die Pan-Fähigkeit. Mit anderen Worten, ich möchte nur mit dem Rad rein-/rauszoomen.Wie pan für d3.behavior.zoom zu deaktivieren?

Der Grund dafür ist, dass ich auf dem "zoombaren" Bereich putzen möchte.

Danke!

Antwort

28

Sagen Sie bitte ein Zoom-Verhalten definiert haben:

var zoom = d3.behavior.zoom().on('zoom', update); 

Wenn Sie das Zoomverhalten auf eine Auswahl anwenden, können Sie den Ereignis-Listener deregistrieren, dass es intern verwendet, um bestimmte Wechselwirkungen zu erkennen und darauf zu reagieren. In Ihrem Fall möchten Sie etwa Folgendes tun:

selection.call(zoom) 
    .on("mousedown.zoom", null) 
    .on("touchstart.zoom", null) 
    .on("touchmove.zoom", null) 
    .on("touchend.zoom", null); 

Ich bin mir nicht sicher, ob Sie die Berührungsereignisse entfernen möchten. Sonst könnte das Zoomen mit Doppeltippen entfallen. Sie sollten mit denen experimentieren.

+1

Für meinen Fall habe ich nur:. 'D3.select ('svg') auf ('mousedown.zoom', null);' – Tony

+2

Um Panning wieder zu aktivieren, nur tun selection.call (Zoom); –

+0

Dies funktioniert nicht auf d3 v4. Es scheint, dass Zoomen und Ziehen separate Ereignisse sind ('d3.zoom()', 'd3.drag()'), so dass dies kein Problem mehr ist. (Definiere nicht 'd3.drag(). On (" drag ", function() {})') – NuclearPeon

4

Ich denke, es wäre gut, die Problemumgehung zu teilen, die ich gefunden habe, um mit diesem Problem umzugehen. Was ich getan habe ist, den Hörer auf den Start der Bürste zu verwenden, um „zu deaktivieren“, um den Zoom:

zoom.on("zoom",null); 
selection.call(zoom); 

und aktivieren Sie es wieder auf dem brushend Ereignis.

Es gibt einen weiteren Trick zu berücksichtigen und kommt von der Tatsache, dass es wichtig ist, den Skala und Übergang Werte der letzten gültigen Zoom Interaktion zu speichern, so dass Sie diese Werte verwenden, wenn die Bürste zu aktivieren auf dem brushend Ereignisse wie diese

zoom.scale(lastEventScale).translate(lastEventTranslate).on("zoom",drawZoom); 
selection.call(scatterZoom); 

würde ich höre andere mehr „elegant“ Lösungen für dieses Problem lieben.

0

Eine Lösung, die ich gefunden habe, war, ein Rect-Element vor das Zoom-aktivierte Element zu stecken (sie müssen Geschwister sein) und seine Füllung auf "transparent" setzen, wenn ich die Zoom-Interaktion deaktivieren wollte oder "keine" , als ich die Zoom-Interaktion aktivieren wollte. Es sah so etwas wie dieses:

if (chart._disableZoom) { 
    var rootPanel = d3.select('.rootPanel'); // this is the parent of the element that can be zoomed and panned 
    if (!rootPanel.select('.stopEventPanel').node()) { // create panel if it doesn't exist yet 
     //.stopEventPanel is appended next to the zoom-enabled element 
     rootPanel.append('rect').attr('class', 'stopEventPanel').attr('width', renderConfig.width).attr('height', renderConfig.height).attr('fill', 'transparent'); 
    } else { // disable zoom and pan 
     rootPanel.select('.stopEventPanel').attr('fill', 'transparent'); 
    } 
} else { // enable zoom and pan 
    d3.select('.rootPanel').select('.stopEventPanel').attr('fill', 'none'); 
}