2016-07-22 101 views
8

Drag and Drop Exampled3.js przepisywanie powiększenia przykład w version4

Próbuję przepisać część tego przykładu powyżej używać w moim kodu, szczególnie ten kawałek:

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

jednak jestem od utknięcie Pakiet v4 bardzo się zmienił. Pisałam funkcję zoomListener być

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 

} 

i wiem, że zgodnie z doc rzeczy się zmieniły i informacji nie są już przechowywane są na co byłoby moje zoomListener D3 V4 release note on zoom Chyba jestem po prostu mylić, w jaki jestem załóżmy, że zrobimy to w nowej wersji. Kilka ostatnich linii mojej funkcji centerNode nie działa, co ma na celu to, że kiedy wyśrodkuję węzeł, resetowanie powiększania i przesuwania ...

Jakieś sugestie?

+0

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

Odpowiedz

13

Po wielu kopaniu, próbach i błędach podchodzę z odpowiedzią, która działa całkiem dobrze dla moich celów. Zauważ, że poniższy kod jest tylko odpowiednią częścią mojego kodu, a nie całego kodu. Pewna zmienna nie wymaga wyjaśnień, więc ich nie uwzględniła. TAKŻE TO JEST WERSJA 4 z 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))}); 


} 

Jak na przykład dla v4 na stronie d3.js użyłem prostokąta zastosować zoom do

Zachowanie zoom jest stosowana do niewidzialnego rect przykrywać element SVG ; to zapewnia, że ​​odbiera dane wejściowe, a zmiana współrzędnych zoomu nie ma wpływu na współrzędną wskaźnika . Pan & Zoom Example

W funkcji węzła Center używam d3.zoomTransform(zoomer.node()); uzyskać prąd transformaty zastosowany do strony. Ta funkcja służy jedynie do centrowania składanego drzewa w pionie, a nie w poziomie, więc zachowuję bieżący plik transform.x (tutaj t.x) taki sam. Współrzędne w moim svg są odwrócone, a więc dlaczego został kliknięty węzeł w moim zwijanym drzewie.("Spójrz na przykład odnoszący się do początku tego wątku, aby zrozumieć, co próbuję przekonwertować na wersję 4)

Zastosuję transformację do mojego elementu G, a następnie chcę zatwierdzić te zmiany w transformacji powiększenia , do tego używam .on("end", function(){}) inaczej to robił dziwne zachowanie z przejściem, robiąc to wszystko, co robi jest ustawienie aktualnego stanu transformacji.

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

linia ta powyżej ubiega tłumaczenie xi y i skala - równa z bieżącym stanem - do macierzy identyfikującej musi uzyskać nową transformację dla G, a następnie zastosować ją do zoomer, która jest elementem, który nazwałem zoom wcześniej.

To zadziałało jak dla mnie urok!

0

Wywołanie transform.scale i zwraca nową transformację i niczego nie modyfikuje. Dlatego:

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

svg.call(zoomListener.transform, newTransform) 

(W tym momencie zoomListener jest dość niedokładna nazwa dla tego, ale niezależnie ...)

k, x i y mogą pochodzić z source, może jak można pokazać, ale Nie jestem pewien, bo nie wiem, co to jest source. Ale dla mnie, t.x*t.k wygląda podejrzanie, ponieważ mnoży istniejące transformacje x przez swoją skalę. Wydaje się, że spowodowałoby to sprzężenie zwrotne.

Aby uzyskać więcej informacji na temat powiększenia w wersji 4, należy sprawdzić, czy nie jest to this related StackOverflow post lub this example by mbostock demonstrujące programową kontrolę nad transformacją powiększenia elementu (w tym przypadku kanwą) i zawiera przejścia.

+0

źródło to miejsce, z którego wydarzenie pochodzi z drzewa z przykładu, który wskazałem powyżej .. – Tekill

+0

@Twojego prawa, ale nie znam terminów, w których zdefiniowane są 'source.x0' i' source.y0'. Czy są to pary lat/lng lub piksele? Zgaduję piksele. W każdym razie sam pracuję nad podobną konwersją, więc może mieć więcej wglądu później ... – meetamit

+1

@Yourinium Odkryłem, że kolejność transformacji ma duże znaczenie podczas pracy z nowym obiektem 'zoomTransform'. W szczególności, 'translate()' powinno pojawić się przed 'scale()', w przeciwnym razie tłumaczenie wewnętrznie zostanie pomnożone przez skalę. Zmodyfikowalem moją odpowiedź, aby to odzwierciedlić. – meetamit