2017-11-17 2 views
2

Ich habe Probleme zu verstehen, wie der Zoom in D3 funktioniert, insbesondere wie er aufgerufen wird und wie die Einstellungen initialisiert werden. Ich habe den folgenden Code-Snippet (nur die wesentlichen Bits sind enthalten), die von einem Manning Lehrbuch auf D3 V4 ist und funktioniert gut:D3 Zoom Einstellungen

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

function createMap(countries, cities) { 
    var projection = d3.geoMercator() 
     .scale(scale) 
     .translate([width/2,height/2]) 

var mapZoom = d3.zoom() 
    .on("zoom", zoomed) 

var zoomSettings = d3.zoomIdentity 
    .translate(width/2, height/2) 
    .scale(scale) 

svg.call(mapZoom).call(mapZoom.transform, zoomSettings) // ?!!! 

function zoomed() { 
     var e = d3.event 
     .translate([e.transform.x, e.transform.y]) 
     .scale(e.transform.k) 

    // I didn't include the drawing of the paths, but 
     they are appended to the SVG, and this updates their data. 

    d3.selectAll("path.graticule").attr("d", geoPath) 
    d3.selectAll("path.countries").attr("d", geoPath) 
    d3.selectAll("circle.cities") 
    .attr("cx", d => projection([d.x,d.y])[0]) 
    .attr("cy", d => projection([d.x,d.y])[1]) 
} 

Warum ist es notwendig, die Zoomfunktion mehrmals auf die anrufen Svg?Das erste Mal, wenn es aufgerufen wird, übergeben wir es nicht die "ZoomSettings", und das zweite Mal, dass wir es tun. Worauf kommt es an? Hat das etwas mit der Tatsache zu tun, dass das Zoom-Ereignis am SVG funktioniert, und nicht an einer Gruppe, die alle meine Pfade enthält? Ich bin so zu viel einfacher Beispiele für Zoom verwendet, die auf einem SVG genannt werden und die Elemente werden an eine Gruppe gebunden:

var zoom = d3.zoom() 
    .scaleExtent([1,3]) 
    .on("zoom", zoomed) 

function zoomed(){ 
    g.attr("transform", d3.event.transform) 
} 

var svg = d3.select("body").append("svg") 
    .attr("width",width) 
    .attr("height",height) 
    .call(zoom) 

var g = d3.select("svg").append("g") 

// All elements are bound to group^ 

Jede Klärung jemand auf diese liefern könnte, wäre sehr geschätzt. Ich finde den Zoom() in D3 trotz der API unglaublich verwirrend.

Antwort

2

Diese Zeile:

svg.call(mapZoom).call(mapZoom.transform, zoomSettings) 

macht zwei getrennte Dinge.

Zuerst ist svg.call(mapZoom)applying the zoom behavior zu svg. Der zweite Anruf, .call(mapZoom.transform, zoomSettings), ist programmatically setting a zoom transform an die Svg. Dies setzt den Ausgangszustand, bevor der Benutzer etwas dagegen unternimmt.

darüber so denken wie folgt aus:

  1. den Zoomverhalten erstellen (var zoom = d3.zoom())
  2. Wenden Sie es Element SVG (svg.call(mapZoom))
  3. Stellen Sie den Ausgangszustand (.call(mapZoom.transform, zoomSettings))