Reputation: 129
I'm trying to filter my map markers layer based on selection of industry in dropdown list of which I've manually referenced in my html here - I'd like to initially retain the pre-loaded marker data and provide an option to filter the markers by selection from the dropdown.
<select class="dropdown" id="selDataset">
<option value="" selected="selected">Industry</option>
<option value ="ind1">Accomodation and Food Services</option>
<option value ="ind2">Educational Services</option>
<option value ="ind3">Administrative and Support and Waste Management and Remediation Services</option>
<option value ="ind4">Professional, Scientific, and Technical Services</option>
<option value ="ind5">Manufacturing</option>
<option value ="ind6">Construction</option>
<option value ="ind7">Health Care and Social Assistance</option>
<option value ="ind8">Wholesale Trade</option>
<option value ="ind9">Information</option>
</select>
Here is my .js code - My guess is I need to define a function that encloses the first for loop and setting an if else statement if a selection is made to filter lat,lng for that industry, else return all by default. I'm just not sure how to reference the html dropdown selection to filter the markers. I have implemented drop downs via D3.js for table filtering, and have used overlay layers before, but I can't find an implementation of this using leaflet marker layers.
// Creating map object
var myMap = L.map("map", {
center: [40.73, -74.0059],
zoom: 11
});
// Adding tile layer to the map
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(myMap);
var data = [{
lat: 40.75,
lng: -73.99,
BusinessName: 'Bank LLC',
Industry: 'Banking'
},
{
lat: 40.73,
lng: -73.97,
BusinessName: 'Some Hotel',
Industry: 'Hospitality'
},
{
lat: 40.74,
lng: -74.00,
BusinessName: 'Other Hotel',
Industry: 'Hospitality'
}
];
// Create a new marker cluster group
var markers = L.layerGroup();
// Loop through data
for (var i = 0; i < data.length; i++) {
// Set the latitude, longitude property to a variable
var latitude = data[i].lat;
var longitude = data[i].lng;
var popText = ("<h3>" + data[i].BusinessName + "</h3><h3>Industry: " + data[i].Industry + "</h3>");
// var industry = data[i].Industry;
// var mySelector = $("#Industry").val();
// Check for location property
if (latitude) {
// Add a new marker to the cluster group and bind a pop-up
markers.addLayer(L.marker([latitude, longitude])
.bindPopup(popText));
};
}
// Add our marker cluster layer to the map
myMap.addLayer(markers);
#map {
height: 400px;
width: 600px;
}
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/leaflet-src.js"></script>
<div id="map"></div>
Upvotes: 1
Views: 1155
Reputation: 13139
The way D3 works is not by redrawing everything from scratch, but by updating the underlying data that the selection works with:
draw()
that draws the given data. Inside draw()
, make sure you also remove any remnants of the old drawings;draw
with a subset of the underlying data;draw()
with all data to provide initial markers.For your code, have a look at array functions, like Array.prototype.map
and Array.prototype.filter
, as they're generally very useful when working with data like this.
// Creating map object
var myMap = L.map("map", {
center: [40.73, -74.0059],
zoom: 11
});
// Adding tile layer to the map
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(myMap);
var allData = [{
lat: 40.75,
lng: -73.99,
BusinessName: 'Bank LLC',
Industry: 'Banking'
},
{
lat: 40.73,
lng: -73.97,
BusinessName: 'Some Hotel',
Industry: 'Hospitality'
},
{
lat: 40.74,
lng: -74.00,
BusinessName: 'Other Hotel',
Industry: 'Hospitality'
}
];
// Create a new marker cluster group
var markers = L.layerGroup();
// Add our marker cluster layer to the map
myMap.addLayer(markers);
function draw(data) {
// Start fresh
markers.clearLayers();
// Loop through data
for (var i = 0; i < data.length; i++) {
// Set the latitude, longitude property to a variable
var latitude = data[i].lat;
var longitude = data[i].lng;
var popText = ("<h3>" + data[i].BusinessName + "</h3><h3>Industry: " + data[i].Industry + "</h3>");
// var industry = data[i].Industry;
// var mySelector = $("#Industry").val();
// Check for location property
if (latitude) {
// Add a new marker to the cluster group and bind a pop-up
markers.addLayer(L.marker([latitude, longitude])
.bindPopup(popText));
};
}
}
var industries = allData
.map(function(row) {
return row.Industry;
})
.sort()
.filter(function(v, i, arr) {
// This selects only unique industries:
// Only return a value if it's the first occurrence or if
// it's different from the previous entry in the sorted(!) array
return i === 0 || arr[i - 1] != v;
});
draw(allData);
d3.select("#selectIndustries")
// Select all non-disabled options
// to avoid touching the placeholder one
.selectAll("option:not([disabled])")
.data(industries)
.enter()
.append("option")
.attr("value", function(d) {
return d;
})
.text(function(d) {
return d;
});
d3.select("#selectIndustries")
.on("change", function() {
var selection = this.value;
var filteredData = allData.filter(function(d) {
return d.Industry == selection;
});
draw(filteredData);
});
#map {
height: 400px;
width: 600px;
}
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/leaflet-src.js"></script>
<div id="map"></div>
<select id="selectIndustries">
<option disabled selected>Select an option</option>
</select>
Upvotes: 1