An example of a zoomable choropleth made with spam.js, this time with a tooltip, a legend and a quantile scale.
xxxxxxxxxx
<meta charset="utf-8" />
<style>
body {
max-width: 960px;
position: relative;
}
.tooltip {
position: absolute;
width: 200px;
height: 60px;
padding: 8px;
background: rgb(255,255,255);
font-family: "Helvetica Neue", "Helvetica", Arial sans-serif;
font-size: 12px;
border: 1px solid rgba(0,0,0,0.2);
box-shadow: 0 3px 5px rgba(0,0,0,0.5),0 0 0 1px rgba(0,0,0,.08);
border-radius: 2px;
pointer-events: none;
}
.g-place {
border-bottom: 1px solid rgb(130,130,130);
padding-bottom: 3px;
margin-bottom: 5px;
}
.g-headline {
font-size: 16px;
}
.g-sub {
color: rgb(130,130,130);
}
.g-value {
float: right;
}
.legend {
position: absolute;
background: rgba(255,255,255,0.5);
right: 0;
top: 0;
font-family: "Helvetica Neue",sans-serif;
font-size: 12px;
display: block;
padding: 10px;
height: 65px;
width: 100px;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script src="https://unpkg.com/rbush@1.4.3/rbush.js"></script>
<script src="https://unpkg.com/d3-svg-legend@1.13.0/d3-legend.min.js"></script>
<script src="https://unpkg.com/spamjs@1.1.0/spam.min.js"></script>
<script type='text/javascript'>
var mouseX, mouseY;
var hover = null;
var color = d3.scale
.quantile()
.range(["#f0f9e8", "#bae4bc", "#7bccc4", "#43a2ca", "#0868ac"]);
d3
.select("body")
.append("svg")
.attr("class", "legend");
var legend = d3.legend
.color()
.shapeHeight(10)
.shapeWidth(30)
.shapePadding(3)
.labelOffset(5)
.orient("vertical")
.labelAlign("start");
var tooltip = d3
.select("body")
.append("div")
.attr("class", "tooltip")
.style("opacity", 0);
document.onmousemove = handleMouseMove;
function handleMouseMove(event) {
mouseX = event.pageX;
mouseY = event.pageY;
tooltip.style("left", mouseX - 100 + "px").style("top", mouseY + 25 + "px");
}
d3.json("bcn.json", function(error, d) {
d3.json("districtes.json", function(error, districtes) {
topojson.presimplify(d);
topojson.presimplify(districtes);
color.domain(
d3.extent(d.objects["seccio-censal"].geometries, function(d) {
return d.properties.rate;
})
);
legend.scale(color);
d3.select(".legend").call(legend);
var map = new ZoomableCanvasMap({
element: "body",
zoomScale: 0.8,
projection: d3.geo
.mercator()
.center([29.6, 30.47])
.scale(250000)
.rotate([0, 0, -37.6]),
width: 960,
height: 650,
data: [
{
features: topojson.feature(d, d.objects["seccio-censal"]),
static: {
paintfeature: function(parameters, d) {
parameters.context.fillStyle = color(d.properties.rate);
parameters.context.fill();
}
},
dynamic: {
postpaint: function(parameters) {
if (!hover) {
tooltip.style("opacity", 0);
return;
}
parameters.context.beginPath();
parameters.context.lineWidth = 1 / parameters.scale;
parameters.path(hover);
parameters.context.stroke();
tooltip
.style("opacity", 1)
.html(
"<div class='g-place'>" +
"<span class='g-headline'>" +
hover.properties.districte +
"</span><br />" +
"<span class='g-sub'>" +
hover.properties.barri +
"</span>" +
"</div>" +
"<span>Birth rate</span>" +
"<span class='g-value'>" +
hover.properties.rate +
"‰</span>"
);
}
},
events: {
hover: function(parameters, d) {
hover = d;
parameters.map.paint();
}
}
},
{
features: topojson.feature(
districtes,
districtes.objects["districtes"]
),
static: {
paintfeature: function(parameters, d) {
parameters.context.lineWidth = 1 / parameters.scale;
parameters.context.strokeStyle = "rgb(70,70,70)";
parameters.context.stroke();
}
},
events: {
click: function(parameters, d) {
parameters.map.zoom(d);
}
}
}
]
});
map.init();
});
});
</script>
https://d3js.org/d3.v3.min.js
https://d3js.org/topojson.v1.min.js
https://unpkg.com/rbush@1.4.3/rbush.js
https://unpkg.com/d3-svg-legend@1.13.0/d3-legend.min.js
https://unpkg.com/spamjs@1.1.0/spam.min.js