2016-07-07 5 views
2

Ich benutze leaflet und Anzeige eines json mit d3 (vers3) auf der Karte. Grundsätzlich folge ich diesem Tutorial here.Update JSON auf Prospekt durch d3

Dies ist mein Code. Die erste callbackHandler beschreibt eine Methode, die Informationen empfängt, die eine andere Sprache an/sendet, basierend auf Benutzerinteraktion mit der Website. pathToFile ist eine Verknüpfung zu einer Datei (json), die dann von d3.json(...) geladen wird.

var svg = d3.select(map.getPanes().overlayPane).append("svg"), 
g = svg.append("g").attr("class", "leaflet-zoom-hide"); 

someMethod("myName", function(pathToFile) { 
    console.log(pathToFile); 
    d3.json(pathToFile, function(error, collection) { 
    console.log(collection); 
     if (error) throw error; 

     // Use Leaflet to implement a D3 geometric transformation. 
     function projectPoint(x, y) { 
      var point = map.latLngToLayerPoint(new L.LatLng(y, x)); 
      this.stream.point(point.x, point.y); 
     } 

     var transform = d3.geo.transform({point: projectPoint}), 
     path = d3.geo.path().projection(transform); 


     var feature = g1.selectAll("path") 
     .data(collection.features) 
     .enter().append("path") 
     .attr("stroke-width", 0.5) 
     .attr("fill-opacity", 0.7) 
     .attr("stroke", "white") 

     map.on("viewreset", reset); 
     reset(); 

     // Reposition the SVG to cover the features. 
     function reset() { 
      var bounds = path.bounds(collection), 
      topLeft = bounds[0], 
      bottomRight = bounds[1]; 

      svg1 .attr("width", bottomRight[0] - topLeft[0]) 
      .attr("height", bottomRight[1] - topLeft[1]) 
      .style("left", topLeft[0] + "px") 
      .style("top", topLeft[1] + "px"); 

      g.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")"); 

      feature.attr("d", path); 
     } 
     console.log("1"); 
     }); 
console.log("2"); 
}); 

Der lustige Teil ist: Das erste Mal, wenn der Code ausgeführt wird, funktioniert es gut. Meine json wird auf der Karte angezeigt, wie es sollte. Wenn jedoch die erste callbackHandler (someMethod) ein zweites Mal ausgeführt wird (nach Interaktion durch einen Benutzer mit der Website), wird die neue json nicht in der Broschüre angezeigt.

Das ist der Ausgang des console.log ich nach dem Versuch, enthalten die Karte zu aktualisieren:

// on startup of website, the callbackHandler "someMethod" gets 
./some/path/toFile 
Object {crs: Object, type: "FeatureCollection", features: Array[20]} 
2 
1 

// after interaction with the website and execution of the callbackHandler "someMethod" 
./some/other/path/toFile 
Object {crs: Object, type: "FeatureCollection", features: Array[9]} 
2 
1 

Aber die neue json nicht angezeigt bekommt. Stattdessen bleibt der alte. Warum ist das?

Antwort

2

Da habe ich keinen Code zum Spielen.

Meine Vermutung ist:

Beim ersten Aufruf someMethod die Datei hochgeladen wird und alles funktioniert.

var feature = g1.selectAll("path") 
     .data(collection.features) 
     .enter().append("path") 
     .attr("stroke-width", 0.5) 
     .attr("fill-opacity", 0.7) 
     .attr("stroke", "white") 

Grund:

Zum ersten Mal g1.selectAll("path") läuft. Die Auswahl ist leer und Sie hängen den Pfad an, wie in den Daten in collection.features dies funktioniert.

Zum zweiten Mal, wenn Sie g1.selectAll("path") tun, wird es Pfade zurück, die Sie Daten binden, aber append wird nicht arbeiten.

Also das Problem ist, müssen Sie alte collection.features entfernen oder müssen es aktualisieren.

Um das zu tun

Option1

var paths = g1.selectAll("path").data() 

paths.exit().remove();//remove old data paths 

var feature = paths 
     .enter().append("path") 
     .attr("stroke-width", 0.5) 
     .attr("fill-opacity", 0.7) 
     .attr("stroke", "white") 

Option 2 alle Wege

var paths = g1.selectAll("path").data() 

g1.selectAll("path").remove();//remove all paths 

var feature = paths 
     .enter().append("path") 
     .attr("stroke-width", 0.5) 
     .attr("fill-opacity", 0.7) 
     .attr("stroke", "white") 

Hope this behebt das Problem entfernen!

lesen Update/Enter/Exit here

+1

Vielen Dank, vor allem für den Link. Ich bin sehr neu in JS und d3 macht mir immer Ärger. Option 1 funktioniert nicht, Option 2 macht den Trick. Ich denke ich verstehe jetzt ein bisschen mehr! – Stophface

+0

Mit Option 2 möchten Sie jedoch die Reihenfolge ändern. 'g1.selectAll (" path "). remove(); // entferne alle Pfade' muss vor 'var paths = g1.selectAll (" path ") kommen. data()' – Stophface

+0

yeah du darfst ... aber es wird nichts beeinflussen. Der Grund ist, dass ich den Pfad später nach dem Entfernen angehängt habe. – Cyril