2016-07-22 29 views
8

Drag and Drop Exampled3.js Umschreiben Zoom Beispiel in version4

Ich versuche, über einen Teil dieses Beispiel neu zu schreiben in meinem Code zu verwenden, und zwar dieses Stück:

function centerNode(source) { 
     scale = zoomListener.scale(); 
     x = -source.y0; 
     y = -source.x0; 
     x = x * scale + viewerWidth/2; 
     y = y * scale + viewerHeight/2; 
     d3.select('g').transition() 
      .duration(duration) 
      .attr("transform", "translate(" + x + "," + y + ")scale(" + scale + ")"); 
     zoomListener.scale(scale); 
     zoomListener.translate([x, y]); 
    } 

aber ich bin immer da das steckt Das v4-Paket hat sich ziemlich verändert. Ich schrieb meine zoomListener Funktion

var zoomListener = d3.zoom() 
       .scaleExtent([0.3,2]) 
       .on("zoom", zoomed); 

    function zoomed() { 
     transform = d3.event.transform; 
     console.log(d3.event); 
     svg.attr("transform", transform); 
    } 

function centerNode(source){ 
    t = transform; 
    console.log(t); 
    x = t.x*t.k; //I only want things to be centered vertically 
    y = (t.y + -source.x0)*t.k + (viewerHeight)/2 ; 
    svg.transition() 
    .duration(duration) 
    .attr("transform","translate(" + x + "," + y +")scale(" + t.k + ")"); 

    transform.scale(t.k); //DOES NOT WORK 
    transform.translate([x, y]); //DOES NOT WORK 

} 

und ich weiß sein, dass nach dem doc Dinge haben sich geändert und Informationen sind nicht mehr gespeichert werden, was mein zoomListener wäre D3 V4 release note on zoom Ich glaube, ich bin nur verwirrt, wie ich bin nehme an, es mit der neuen Version zu machen. Die letzten paar Zeilen meiner centerNode-Funktion funktionieren nicht, was dazu führt, dass beim Zentrieren des Knotens das Zoomen und Schwenken zurückgesetzt wird ...

Irgendwelche Vorschläge?

+0

https://coderwall.com/p/psogia/simplet-way-to-add-zoom-pan-on-d3-js – Sphinxxx

Antwort

13

Also nach viel graben und Versuch und Irrtum cam ich mit einer Antwort, die ziemlich gut für meine Zwecke funktioniert. Beachten Sie, dass dieser Code unten nur der relevante Teil meines Codes ist, nicht der gesamte Code, bestimmte Variablen waren selbsterklärend und haben sie daher nicht enthalten. AUCH DIES IST IN VERSION 4 von d3.js.

var zoom = d3.zoom() 
      .scaleExtent([0.3,2]) 
      .on("zoom", zoomed); 


var svg = d3.select("body") 
      .append("svg") 
       .attr("width", viewerWidth) 
       .attr("height", viewerHeight); 

var zoomer = svg.append("rect") 
       .attr("width", viewerWidth) 
       .attr("height", viewerHeight) 
       .style("fill", "none") 
       .style("pointer-events", "all") 
       .call(zoom); 

var g = svg.append("g"); 

zoomer.call(zoom.transform, d3.zoomIdentity.translate(150,0)); //This is to pad my svg by a 150px on the left hand side 

function zoomed() { 
    g.attr("transform", d3.event.transform);//The zoom and panning is affecting my G element which is a child of SVG 
} 

function centerNode(source){ 

    t = d3.zoomTransform(zoomer.node()); 
    console.log(t); 

    x = t.x; 
    y = source.x0; 

    y = -y *t.k + viewerHeight/2; 

    g.transition() 
    .duration(duration) 
    .attr("transform", "translate(" + x + "," + y + ")scale(" + t.k + ")") 
    .on("end", function(){ zoomer.call(zoom.transform, d3.zoomIdentity.translate(x,y).scale(t.k))}); 


} 

du nach den Beispielen für v4 auf der d3.js Seite, habe ich ein Rechteck um den Zoom

Das Zoom-Verhalten zu einer unsichtbaren rect des über das SVG Element angewandt anzuwenden ; Dadurch wird sichergestellt, dass es Eingaben erhält und dass die Koordinaten des Zeigers nicht von der Transformation des Zoomverhaltens beeinflusst werden. Pan & Zoom Example

Im Zentrum Knotenfunktion I d3.zoomTransform(zoomer.node()); bin mit bekommen Transformations den Strom auf die Seite angewendet. Der Zweck dieser Funktion ist nur, den zusammenklappbaren Baum vertikal und nicht horizontal zu zentrieren, also behalte ich die aktuelle transform.x (hier t.x) gleich. Die Koordinate in meinem Svg sind Flip daher, warum y= source.x0, Quelle ist ein welcher Knoten wurde in meinem zusammenklappbaren Baum angeklickt.("Sehen Sie sich das Beispiel an, auf das oben in diesem Thread verwiesen wird, um zu verstehen, was ich in Version 4 zu konvertieren versuche)

Ich bin die Transformation auf mein G-Element anwenden und dann möchte ich diese Änderungen an die Zoom-Transformation festschreiben zu tun, damit ich das .on("end", function(){}) sonst seltsame Verhalten mit dem Übergang tat, indem sie, dass alle es tut, ist der aktuelle Stand der Transformation zu setzen.

zoomer.call(zoom.transform, d3.zoomIdentity.translate(x,y).scale(t.k)) 

Diese Linie über eine Übersetzung von x bewirbt und y und eine Skala - das ist gleich, was der aktuelle Zustand - für die Identifizierungsmatrix muss eine neue Transformation für G bekommen, dann wenden Sie es an zoomer an, das ist das Element, das ichnannte 10 früher.

Das funktionierte wie ein Zauber für mich!

0

Aufruf transform.scale und transform.translate gibt eine neue Transformation zurück und ändert nichts. Deshalb:

transform = transform.translate([x, y]).scale(k) 

svg.call(zoomListener.transform, newTransform) 

(An dieser Stelle zoomListener ist ein ziemlich ungenau Name für diese, aber unabhängig ...)

k, x und y aus source abgeleitet werden, vielleicht als zeigen Ihnen, aber Ich bin mir nicht sicher, weil ich nicht weiß, was source ist. Aber für mich sieht t.x*t.k verdächtig aus, weil es die vorhandenen Transformationen x durch seine Skalierung multipliziert. Es scheint, als würde es eine Rückkopplungsschleife verursachen.

Weitere Informationen zum Zoom in Version 4 finden Sie unter this related StackOverflow post oder this example by mbostock, um die programmgesteuerte Steuerung der Zoom-Transformation eines Elements (in diesem Fall Leinwand) zu demonstrieren.

+0

Quelle ist, wo das Ereignis aus dem Baum aus dem Beispiel kommt, auf das ich zeigte über .. – Tekill

+0

@Yourinium Recht, aber ich kenne nicht die Begriffe, in denen 'source.x0' und' source.y0' definiert sind. Wie sind sie lat/lng Paare oder Pixel? Ich rate Pixel. Wie auch immer, ich arbeite selbst an einer ähnlichen Konvertierung, könnte also später mehr Einsicht haben ... – meetamit

+1

@Yourinium Ich habe festgestellt, dass die Reihenfolge der Transformation bei der Arbeit mit dem neuen 'zoomTransform'-Objekt sehr wichtig ist. Insbesondere sollte translate() 'vor' scale() 'stehen, andernfalls wird die Übersetzung intern mit der Skalierung multipliziert. Ich habe meine Antwort geändert, um das zu reflektieren. – meetamit