2016-11-23 1 views
1

Je suis suivi tutorial de Chris Zetter de créer une superposition Voronoi sur Leaflet, mais j'ai remplacé les tuiles Mapbox avec des tuiles Google Maps (en utilisant le plugin Google Mutant Leaflet) et utilisé mes propres données.Dépliant Google Map et d3 Voronoi superposition de diagramme

La superposition voronoi fonctionne, mais ne se met pas à jour lorsque la carte est déplacée ou que la vue est réinitialisée (événements moveend et viewreset).

Il semble que l'événement "viewreset" ne soit pas déclenché et que l'événement "moveend" ne déclenche pas la fonction "drawWithLoading".

L'erreur qui se pose est: Uncaught TypeError: Cannot read property 'call' of undefined(…) qui est sur la ligne indiquée de cette fonction:

map.on('load', function() { 

    d3.csv(url, function(csv) { 
    points = csv; 
    points.forEach(function(point) { 
     pointTypes.set(point.type, {type: point.type, color: point.color}); 
    }) 
    drawPointTypeSelection(); 
    map.addLayer(mapLayer); //ERROR on this line 
    }) 
}); 

est ici la fonction mapLayer il est référait à:

var mapLayer = { 
    onAdd: function(map) { 
    map.on('viewreset moveend', drawWithLoading); 
    drawWithLoading(); 
    }, 
}; 

Et voici la fonction drawWithLoading:

var drawWithLoading = function(e){ 

    console.log('drawWithLoading e', e); //TODO: delete later 
    d3.select('#loading').classed('visible', true); 
    if (e && e.type == 'viewreset') { 
     d3.select('#overlay').remove(); 
    } 
    setTimeout(function(){ 
     draw(); 
     d3.select('#loading').classed('visible', false); 
    }, 0); 
    } 

Je suis assez nouveau avec javascript et j'ai essayé de comprendre cela au cours des derniers jours.

Est-ce que quelqu'un sait pourquoi l'erreur de la fonction mapLayer arrive, et pourquoi la carte ne se redessine pas sur les événements "moveend" et "viewreset"?

Edité pour inclure du code entier:

// Selects check boxes in selector menu // 
showHide = function(selector) { 
    d3.select(selector).select('.hide').on('click', function(){ 
    d3.select(selector) 
     .classed('visible', false) 
     .classed('hidden', true); 
    }); 

    d3.select(selector).select('.show').on('click', function(){ 
    d3.select(selector) 
     .classed('visible', true) 
     .classed('hidden', false); 
    }); 
} 

// Draws Voronoi Map // 
voronoiMap = function(map, url, initialSelections) { 

    console.log('We got in here!'); 
    console.log('map', map); 
    console.log('url', url); 
    console.log('initialSelections', initialSelections); 
    window.myMap = map; 

    var pointTypes = d3.map(), 
     points = [], 
     lastSelectedPoint; 

    var voronoi = d3.geom.voronoi() 
     .x(function(d) { return d.x; }) 
     .y(function(d) { return d.y; }); 

    var selectPoint = function() { 
    d3.selectAll('.selected').classed('selected', false); 

    var cell = d3.select(this), 
     point = cell.datum(); 

    lastSelectedPoint = point; 
    cell.classed('selected', true); 

    d3.select('#selected h1') 
     .html('') 
     .append('a') 
     .text(point.name) 
     .attr('href', point.url) 
     .attr('target', '_blank') 
    } 

    var drawPointTypeSelection = function() { 
    showHide('#selections') 
    labels = d3.select('#toggles').selectAll('input') 
     .data(pointTypes.values()) 
     .enter().append("label"); 

    labels.append("input") 
     .attr('type', 'checkbox') 
     .property('checked', function(d) { 
     return initialSelections === undefined || initialSelections.has(d.type) 
     }) 
     .attr("value", function(d) { return d.type; }) 
     .on("change", drawWithLoading); 

    labels.append("span") 
     .attr('class', 'key') 
     .style('background-color', function(d) { return '#' + d.color; }); 

    labels.append("span") 
     .text(function(d) { return d.type; }); 
    } 

    var selectedTypes = function() { 
    return d3.selectAll('#toggles input[type=checkbox]')[0].filter(function(elem) { 
     return elem.checked; 
    }).map(function(elem) { 
     return elem.value; 
    }) 
    } 

    var pointsFilteredToSelectedTypes = function() { 
    var currentSelectedTypes = d3.set(selectedTypes()); 
    return points.filter(function(item){ 
     return currentSelectedTypes.has(item.type); 
    }); 
    } 

    var drawWithLoading = function(e){ 

    console.log('drawWithLoading e', e); //TODO: delete later 
    d3.select('#loading').classed('visible', true); 
    if (e && e.type == 'viewreset') { 
     d3.select('#overlay').remove(); 
    } 
    setTimeout(function(){ 
     draw(); 
     d3.select('#loading').classed('visible', false); 
    }, 0); 
    } 

    var draw = function() { 
    d3.select('#overlay').remove(); 

    var bounds = map.getBounds(), 
     topLeft = map.latLngToLayerPoint(bounds.getNorthWest()), 
     bottomRight = map.latLngToLayerPoint(bounds.getSouthEast()), 
     existing = d3.set(), 
     drawLimit = bounds.pad(0.4); 

    filteredPoints = pointsFilteredToSelectedTypes().filter(function(d) { 
     var latlng = new L.LatLng(d.latitude, d.longitude); 

     if (!drawLimit.contains(latlng)) { return false }; 

     var point = map.latLngToLayerPoint(latlng); 

     key = point.toString(); 
     if (existing.has(key)) { return false }; 
     existing.add(key); 

     d.x = point.x; 
     d.y = point.y; 
     return true; 
    }); 

    voronoi(filteredPoints).forEach(function(d) { d.point.cell = d; }); 

    console.log('map.getPanes()', map.getPanes()); 

    var svg = d3.select(map.getPanes().overlayPane).append("svg") 
     .attr('id', 'overlay') 
     .attr("class", "leaflet-zoom-hide") 
     .style("width", map.getSize().x + 'px') 
     .style("height", map.getSize().y + 'px') 
     .style("margin-left", topLeft.x + "px") 
     .style("margin-top", topLeft.y + "px"); 

    var g = svg.append("g") 
     .attr("transform", "translate(" + (-topLeft.x) + "," + (-topLeft.y) + ")"); 

    var svgPoints = g.attr("class", "points") 
     .selectAll("g") 
     .data(filteredPoints) 
     .enter().append("g") 
     .attr("class", "point") 
     .attr('data-name', function(d) { return d.name }); 

    var buildPathFromPoint = function(point) { 
     return "M" + point.cell.join("L") + "Z"; 
    } 

    svgPoints.append("path") 
     .attr("class", "point-cell") 
     .attr("d", buildPathFromPoint) 
     .style('fill', function(d) { //return '#' + d.color 
      if (d.name <= 10) {return "ffffd9"} 
        else if (d.name <=15 && d.name >10) {return "edf8b1"} 
        else if (d.name <=20 && d.name >15) {return "7fcdbb"} 
        else if (d.name <=25 && d.name >20) {return "41b6c4"} 
        else if (d.name <=35 && d.name >25) {return "1d91c0"} 
        else if (d.name <=45 && d.name >35) {return "253494"} 
        else {return "081d58"} 
     }) 
     .attr("opacity", 0.5) 
     .on('click', selectPoint) 
     .classed("selected", function(d) { return lastSelectedPoint == d}); 

    svgPoints.append("circle") 
     .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) 
     .style('fill', function(d) { //return '#' + d.color 
     if (d.name <= 10) {return "ffffd9"} 
        else if (d.name <=15 && d.name >10) {return "edf8b1"} 
        else if (d.name <=20 && d.name >15) {return "7fcdbb"} 
        else if (d.name <=25 && d.name >20) {return "41b6c4"} 
        else if (d.name <=35 && d.name >25) {return "1d91c0"} 
        else if (d.name <=45 && d.name >35) {return "253494"} 
        else {return "081d58"} }) 
     .attr("r", 1.4) 
     .attr("opacity", 0.6); 
    } 


    var mapLayer = { 
    onAdd: function(map) { 
     console.log("onviewreset map", map); //TODO: Delete later 
     map.on('viewreset moveend', drawWithLoading); 
     drawWithLoading(); 
    }, 
    }; 

    showHide('#about'); 

    map.on('load', function() { 
    console.log('map ready'); 
    d3.csv(url, function(csv) { 
     points = csv; 
     points.forEach(function(point) { 
     pointTypes.set(point.type, {type: point.type, color: point.color}); 
     }) 
     drawPointTypeSelection(); 
     console.log("addLayer"); //TODO: Delete Later 
     map.addLayer(mapLayer); 
     console.log("addedLayer"); //TODO: Delete Later 
    }) 
    }); 

    console.log('got here too'); 
} 

// Draws Google Maps tiles using Road and Style tiles // 
var map = L.map('map'); 

var roadMutant = L.gridLayer.googleMutant({ 
      maxZoom: 24, 
      type:'roadmap' 
}).addTo(map); 

var styleMutant = L.gridLayer.googleMutant({ 
      styles: [ 
       {elementType: 'labels', stylers: [{visibility: 'off'}]}, 
       {featureType: 'water', stylers: [{color: '#444444'}]}, 
       {featureType: 'landscape', stylers: [{color: '#eeeeee'}]}, 
       {featureType: 'road', stylers: [{visibility: 'on'}]}, 
       {featureType: 'poi', stylers: [{visibility: 'off'}]}, 
       {featureType: 'transit', stylers: [{visibility: 'on'}]}, 
       {featureType: 'administrative', stylers: [{visibility: 'off'}]}, 
       {featureType: 'administrative.locality', stylers: [{visibility: 'off'}]} 
      ], 
      maxZoom: 24, 
      type:'roadmap' 
}); 

// Creates a styles selector menu // 
L.control.layers({ 
    Roadmap: roadMutant, 
    Styles: styleMutant 
}, {}, { 
    collapsed: false 
}).addTo(map); 



url = 'AllCoords_supertrial.csv'; 
initialSelection = d3.set(['1','2','3']); //Ideally would like to have all selected to start with or take away having to check boxes before drawing// 
voronoiMap(map, url, initialSelection); 
+0

Cela est difficile à déboguer avec les petits fragments de code que vous avez inclus. Pouvez-vous le reproduire dans un extrait de pile, plunker ou jsfiddle? – Mark

+0

@Mark J'ai inclus le code entier. Et voici le jsfiddle https://jsfiddle.net/62c6eadf/1/. Je ne l'ai jamais utilisé auparavant, mais j'espère que cela aidera, et faites-moi savoir s'il y a quelque chose d'autre qui vous facilitera la tâche. Merci! – Heather

Répondre

1

Même si vous avez affiché un code, et un violon, il est un peu difficile de savoir ce qui se passe. S'il vous plaît essayez de mettre à jour votre question pour fournir un complete example.

Je vais faire une supposition sauvage et le point à cette ligne de code:

var mapLayer = { 
    ... 
}; 

Si vous lisez les Leaflet tutorials, en particulier celles sur l'extension Dépliant pour créer de nouveaux types de couches de carte, vous vous rendrez compte que la façon de créer une sous-classe de Layer est:

var mapLayer = L.Layer.extend({ 
    onAdd: function(map) {...}, 
    ... 
}); 

Dépliant attend des couches de carte pour des cas de mise en œuvre L.Layer, toutes les méthodes internes. Si vous essayez d'ajouter quelque chose qui n'implémente pas l'interface L.Layer, les choses vont se casser.

Si vous ne comprenez pas les interfaces de sous-classes et de classes, veuillez actualiser vos connaissances sur OOP.

Cela peut ne pas être le seul problème dans votre code, mais c'est le seul que je peux voir en ce moment, sans avoir un regard complet sur un exemple complet.