I'm working on a project where i put points on a map by using D3 and leaflet. I use this template because i have a lot of data to map.
First, i filter data with checkboxes by type and it works fine but now i want to add a dropdown list to filter by name of location. I was able to set the dropdown list with all names and when i click on a name, it filters the points i want by location. So no problem here
The problem is when i select a name and after change filter by the checkboxes, it returns filtered points for all the map and not just only the location selected. The same thing happens when i zoom on the map (i have a function which filter data by zooming to avoid the map to call useless data).
My csv looks like this :
date,dcomiris,latitude,longitude,type,iris,com,name
2014-01-01,600570101,49.4295880722704,2.08997269112341,7871F,Cathedrale-Universite,60057,Beauvais
2014-01-01,601750101,49.2585514437302,2.46903313061001,7871F,Rive Gauche,60175,Creil
2014-01-01,601750102,49.2658438351767,2.47995361882026,7871D,Voltaire,60175,Creil
2014-01-01,603820201,49.426958710346,2.8194006454886,7871H,Centre,60382,Margny-lès-Compiègne
And my js file :
infraMap = function(map, url, initialSelections) {
var pointTypes = d3.map(),
uniqueName = d3.map(),
points = [],
lastSelectedPoint;
var dropDown = d3.select("#filter").append("select")
.attr("name", "communes-liste");
// setup color
var cValue = function(d) { return d.type;},
color = d3.scale.category20();
// checkboxes
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 color(cValue(d)); });
labels.append("span")
.text(function(d) { return d.type; });
}
//fonction filtre checkboxes
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);
});
}
// 'loading...'
var drawWithLoading = function(e){
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);
}
// draw data
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);
//zoom filtering
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;
});
//map/svg
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
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")
svgPoints.append("circle")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.style('fill', function(d) { return color(cValue(d)); } )
.style('stroke', 'black')
.style('stroke-width', '1px')
.style("cursor", "pointer")
.attr("r", 4)
.on("mouseover", function(d) {
if(d.name == d.iris){
div.transition()
.duration(200)
.style("opacity", .9);
div.html(d.date + "<br/>" + d.name + "<br />" + d.type )
.style("left", (d3.event.pageX + 10) + "px")
.style("top", (d3.event.pageY - 28) + "px");
}
else{
div.transition()
.duration(200)
.style("opacity", .9);
div.html(d.date + "<br/>" + d.name + "<br />" + d.iris + "<br />" + d.type )
.style("left", (d3.event.pageX + 10) + "px")
.style("top", (d3.event.pageY - 28) + "px");
}
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
// dropdown list
var options = dropDown.selectAll("option")
.data([{name:"*Toutes les communes"}].concat(uniqueName.values()))
.enter()
.append("option");
options.text(function(d) { return d.name; })
.attr("value", function(d) { return d.name; })
.sort(function(a,b){return d3.ascending(a.name, b.name)});
//function dropdown
var dropListFilter = dropDown.on("change", function() {
var selected = this.value;
displayOthers = this.checked ? "inline" : "none";
display = this.checked ? "none" : "inline";
if(selected == '*Toutes les communes'){
svg.selectAll(".point")
.attr("display", display);
}
else{
svg.selectAll(".point")
.filter(function(d) {return selected != d.name;})
.attr("display", displayOthers);
svg.selectAll(".point")
.filter(function(d) {return selected == d.name;})
.attr("display", display);
}
});
}
var mapLayer = {
onAdd: function(map) {
map.on('viewreset moveend', draw);
draw();
}
};
d3.csv("my.csv", function(csv) {
points = csv;
points.forEach(function(point) {
uniqueName.set(point.name, {name: point.name});
pointTypes.set(point.type, {type: point.type, color: point.color});
})
drawPointTypeSelection();
map.addLayer(mapLayer);
});
}
I think the problem is that the two filters can't communicate because my dropdown list is in the draw
function and checkboxes are outside but when i put my dropdown list outside this function it can't find name of location.
Thanks !
Aucun commentaire:
Enregistrer un commentaire