Skip to content

Instantly share code, notes, and snippets.

@1Cr18Ni9
Last active October 15, 2017 02:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 1Cr18Ni9/d72b6ba95285b80fe4c7498e784a8e0c to your computer and use it in GitHub Desktop.
Save 1Cr18Ni9/d72b6ba95285b80fe4c7498e784a8e0c to your computer and use it in GitHub Desktop.
D3 + Leaflet
license: mit

Built with blockbuilder.org

Utilising marker's option: L.marker(latlng, { options }); to bind data that we can access it with event.target.options when hoove on markes. That is the perfect way of binding data I can think of.

When move your mouse over the marker, there will be a D3js created pie chart over it.

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css">
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
#map{ width:100%; height:500px; }
.tooltip{ width: 80px; height: 80px; position: absolute; left: -9999p; }
.tooltip > svg{ margin:auto; display: block; }
</style>
</head>
<body>
<div id="map"></div>
<script>
var points = [
{latlng: [30.94110220488552, -238.14239501953122], achieve: 0.34},
{latlng: [31.12819929911196, -238.24676513671875], achieve: 0.67},
{latlng: [30.987027960280326, -238.46649169921875], achieve: 0.59},
{latlng: [31.230417393130743, -238.47747802734375], achieve: 0.32},
{latlng: [31.235114421248575, -238.63128662109375], achieve: 0.97},
{latlng: [31.340735782189476, -238.41979980468747], achieve: 0.82}
];
var pointsGroup = L.layerGroup();
points.forEach(function(d){
// binding data to marker object's option
L.marker(d.latlng, { achieve: d.achieve })
.on("mouseover", onMouseOver)
.on("mouseout", onMouseOut)
.addTo(pointsGroup);
});
var layer1 = L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", {
detectRetina: true,
attribution: "&copy; " + "<a href='http://openstreetmap.org'>OpenStreetMap</a>" + " Contributors"
}),
layer2 = L.tileLayer("http://{s}.tile.thunderforest.com/landscape/{z}/{x}/{y}.png", {
attribution: "Thunderforest"
}),
layer3 = L.tileLayer.wms("http://basemap.nationalmap.gov/ArcGIS/services/USGSImageryTopo/MapServer/WMSServer", {
layers: "0",
format: "image/png",
transparent: false,
attribution: "USGS"
});
var baseLayers = {
"osm": layer1,
"thunderforest": layer2
},
subLayers = { "USGS": layer3, "Points": pointsGroup };
var map = L.map("map", {
center: [31.240985378021307, -238.50466489791867],
zoom: 10,
layers: [layer1, pointsGroup]
});
L.control.layers(baseLayers, subLayers, {position: "topright"}).addTo(map);
function onMouseOver(e){
var point = map.latLngToContainerPoint(e.latlng);
var tooltip = d3.select(map.getContainer())
.append("div")
.attr("class", "tooltip")
// Calculating according to marker and tooltip size
.style({ left: point.x - 40 + "px", top: point.y - 80 - 41 + "px" })
.node();
getPie(tooltip, e.target.options.achieve);
}
function onMouseOut(e){
d3.select(map.getContainer()).select(".tooltip").remove();
}
function getPie(node, value){
var size = 70;
var arc = d3.svg.arc().outerRadius(size / 2).innerRadius(size / 3),
pie = d3.layout.pie().sort(null);
d3.select(node).append("svg")
.attr({ width: size, height: size })
.append("g")
.attr("transform", "translate(" + [size / 2, size / 2] + ")")
.call(function(s){
s.append("text")
.text(d3.format(".2p")(value))
.style("font", "12px")
.attr({ "text-anchor": "middle", "alignment-baseline": "central" });
})
.selectAll("path")
.data(pie([value, 1 - value]))
.enter()
.append("path")
.attr({
d: arc,
fill: function(d,i){ return i ? "gray" : "red"; }
});
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment