Built with blockbuilder.org
forked from EE2dev's block: leaflet and d3.legend
license: mit |
Built with blockbuilder.org
forked from EE2dev's block: leaflet and d3.legend
<!DOCTYPE html> | |
<html> | |
<head> | |
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" | |
integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" | |
crossorigin=""/> | |
<!-- Make sure you put this AFTER Leaflet's CSS --> | |
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js" | |
integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==" | |
crossorigin=""></script> | |
<script src="http://d3js.org/d3.v5.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.25.6/d3-legend.min.js"></script> | |
<style> | |
#map { height: 400px; } | |
aside, pre { display: none; } | |
div#allLegends { position: relative; } | |
div.legend { position: relative; width: 300px; float: left; } | |
</style> | |
</head> | |
<body> | |
<aside class="myDataset">group,lat,long,index,address | |
BK,48.157630,11.648014,1800,loithringer | |
BK,48.141579,11.604729,100,sdakjh | |
BK,48.143640,11.603463,1800,dsfasfslk 3. | |
BK,48.157630,11.648014,1800,loithringer | |
BK,48.141579,11.604729,100,sdakjh | |
BK,48.143640,11.603463,1800,dsfasfslk 3. | |
BK,48.143827,11.602895,500, sadkfjalsfj | |
BK,48.143640,11.603463,,dsfasfslk 3. | |
BK,48.143827,11.602895,, sadkfjalsfj | |
BK,48.144099,11.602444,120, hansenstrasse 4A</aside> | |
<aside class="d2">group,lat,long,value | |
KK,48.157630,11.648014,30 | |
KK,48.141579,11.604729,1800 | |
KK,48.143640,11.603463,200</aside> | |
<aside class="d3">group,lat,long,value | |
KI,48.157630,11.648014,Sepp | |
KI,48.141579,11.604729,Schorsch | |
KI,48.143640,11.603463,Hans</aside> | |
<div id="map"></div> | |
<div id="allLegends"></div> | |
<script> | |
var mbAttr = 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' + | |
'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' + | |
'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>', | |
mbUrl = 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoiZWUyZGV2IiwiYSI6ImNqaWdsMXJvdTE4azIzcXFscTB1Nmcwcm4ifQ.hECfwyQtM7RtkBtydKpc5g'; | |
var grayscale = L.tileLayer(mbUrl, {id: 'mapbox.light', attribution: mbAttr}), | |
satellite = L.tileLayer(mbUrl, {id: 'mapbox.satellite', attribution: mbAttr}), | |
streets = L.tileLayer(mbUrl, {id: 'mapbox.streets', attribution: mbAttr}); | |
var layerGroups = {}; | |
var dataParameters = []; | |
var dp; | |
////////////////////////////////////////////////////////////////// | |
// Usage: | |
// 1. set class of aside element above to match the name of the data | |
// 2. insert data into aside element | |
// 3. specify the following dp (data parameters) | |
// | |
// options for scales: | |
// "scaleThreshold", "scaleOrdinal", "scaleOrdinal" or "scaleQuantile" | |
////////////////////////////////////////////////////////////////// | |
// ------> for more data sets, copy FROM here | |
// dataset 1 | |
dataParameters.push({}); | |
dp = dataParameters[dataParameters.length - 1]; | |
// specify start | |
dp.selector = "aside.myDataset"; | |
dp.name = dp.selector.split(".").pop(); | |
dp.delimiter = ","; | |
dp.numColumns = ["lat","long","index"]; | |
dp.valueColumn = "index"; | |
dp.scaleType = "scaleThreshold"; | |
// specify end | |
dp.data = readData(dp.selector, dp.delimiter, dp.numColumns, dp.valueColumn); | |
dp.scale = getScale(dp.data, dp.scaleType, dp.valueColumn); | |
dp.group = L.layerGroup(); | |
addCircles(dp); | |
addLegend(dp.scale, dp.scaleType, dp.name); | |
// ------> for more data sets, copy TO here | |
// dataset2 | |
dataParameters.push({}); | |
dp = dataParameters[dataParameters.length - 1]; | |
// specify start | |
dp.selector = "aside.d2"; | |
dp.name = dp.selector.split(".").pop(); | |
dp.delimiter = ","; | |
dp.numColumns = ["lat","long"]; | |
dp.valueColumn = "value"; | |
dp.scaleType = "scaleQuantize"; | |
// specify end | |
dp.data = readData(dp.selector, dp.delimiter, dp.numColumns, dp.valueColumn); | |
dp.scale = getScale(dp.data, dp.scaleType, dp.valueColumn); | |
dp.group = L.layerGroup(); | |
addCircles(dp); | |
addLegend(dp.scale, dp.scaleType, dp.name); | |
// dataset3 | |
dataParameters.push({}); | |
dp = dataParameters[dataParameters.length - 1]; | |
// specify start | |
dp.selector = "aside.d3"; | |
dp.name = dp.selector.split(".").pop(); | |
dp.delimiter = ","; | |
dp.numColumns = ["lat","long"]; | |
dp.valueColumn = "value"; | |
dp.scaleType = "scaleOrdinal"; | |
// specify end | |
dp.data = readData(dp.selector, dp.delimiter, dp.numColumns, dp.valueColumn); | |
dp.scale = getScale(dp.data, dp.scaleType, dp.valueColumn); | |
dp.group = L.layerGroup(); | |
addCircles(dp); | |
addLegend(dp.scale, dp.scaleType, dp.name); | |
// dataset 4 | |
dataParameters.push({}); | |
dp = dataParameters[dataParameters.length - 1]; | |
// specify start | |
dp.selector = "aside.myDataset"; | |
dp.name = "The quantile dataset"; | |
dp.delimiter = ","; | |
dp.numColumns = ["lat","long","index"]; | |
dp.valueColumn = "index"; | |
dp.scaleType = "scaleQuantile"; | |
// specify end | |
dp.data = readData(dp.selector, dp.delimiter, dp.numColumns, dp.valueColumn); | |
dp.scale = getScale(dp.data, dp.scaleType, dp.valueColumn); | |
dp.group = L.layerGroup(); | |
addCircles(dp); | |
addLegend(dp.scale, dp.scaleType, dp.name); | |
var map = L.map('map', { | |
center: [48.1523107, 11.6231103], | |
zoom: 14, | |
layers: [grayscale, dataParameters[0].group] | |
}); | |
var baseLayers = { | |
"Grayscale": grayscale, | |
"Streets": streets, | |
"Satellite": satellite | |
}; | |
var overlays = {}; | |
dataParameters.forEach(function(ele) { | |
overlays[ele.name] = ele.group; | |
}) | |
L.control.layers(baseLayers, overlays).addTo(map); | |
///////////////////////////////////////// | |
// helper functions | |
///////////////////////////////////////// | |
function addLegend(scale, scaleType, title) { | |
var svg = d3.select("#allLegends") | |
.append("div") | |
.attr("class", "legend " + title) | |
.append("svg") | |
.style("width", 300) | |
.style("height", 300); | |
svg.append("g") | |
.attr("class", "legend") | |
.attr("transform", "translate(20,20)"); | |
var legend = d3.legendColor() | |
.labelFormat(d3.format(".2f")) | |
.title(title); | |
if (scaleType === "scaleThreshold") { | |
legend = legend.labels(d3.legendHelpers.thresholdLabels); | |
} | |
legend.scale(scale); | |
svg.select("g.legend") | |
.call(legend); | |
} | |
function addCircles(dp) { | |
var circle; | |
var colorScale = dp.scale; | |
dp.data.forEach(function(element) { | |
circle = L.circle([element.lat, element.long], { | |
color: colorScale(element[dp.valueColumn]), | |
fillColor: colorScale(element[dp.valueColumn]), | |
fillOpacity: 1, | |
radius: 5 | |
}).addTo(dp.group); | |
circle.bindPopup("Wert: " + element[dp.valueColumn] + "<br>Adresse: " + element.address); | |
}); | |
} | |
// see also: http://d3indepth.com/scales/ | |
function getScale(data, scaleType, valueCol) { | |
var scale; | |
if (scaleType === "scaleThreshold") { | |
var min = d3.min(data, function(d) { return d[valueCol]; }); | |
var max = d3.max(data, function(d) { return d[valueCol]; }); | |
var d = (max-min)/7; | |
scale = d3.scaleThreshold() | |
.domain([min+1*d,min+2*d,min+3*d,min+4*d,min+5*d,min+6*d]) | |
.range(['#ffffe0','#ffd59b','#ffa474','#f47461','#db4551','#b81b34','#8b0000']); | |
} else if (scaleType === "scaleQuantize") { | |
scale = d3.scaleQuantize() | |
.domain(d3.extent(data, function(d) { return d[valueCol]; })) | |
.range(['#ffffe0','#ffd59b','#ffa474','#f47461','#db4551','#b81b34','#8b0000']); | |
} else if (scaleType === "scaleQuantile") { | |
scale = d3.scaleQuantile() | |
.domain(data.map(function(d) { return d[valueCol]; }).sort(function(a, b){return a-b})) | |
.range(['#ffffe0','#ffd59b','#ffa474','#f47461','#db4551','#b81b34','#8b0000']); | |
} else if (scaleType === "scaleOrdinal") { | |
scale = d3.scaleOrdinal() | |
.domain(data.map(function(d) { return d[valueCol]; })) | |
.range(d3.schemePaired); | |
} | |
return scale; | |
} | |
function readData(selector, delimiter, columnsNum, valueCol) { | |
var psv = d3.dsvFormat(delimiter); | |
var initialData = psv.parse(d3.select(selector).text()); | |
_data = initialData.filter(function(e) { return e[valueCol].length !== 0; }); | |
console.log("Skipped: " + (initialData.length - _data.length) + " rows."); | |
if (typeof columnsNum !== "undefined") { | |
_data.forEach( function (row) { | |
convertToNumber(row, columnsNum); | |
}); | |
} | |
console.log(_data); | |
return _data; | |
} | |
function convertToNumber(d, _columnsNum) { | |
for (var perm in d) { | |
if (_columnsNum.indexOf(perm) > -1) | |
if (Object.prototype.hasOwnProperty.call(d, perm)) { | |
d[perm] = +d[perm]; | |
} | |
} | |
return d; | |
} | |
</script> | |
</body> | |
</html> |