index.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<script src="//code.jquery.com/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="//maps.google.com/maps/api/js?sensor=true"></script>
<script type="text/javascript" src="//mbostock.github.com/d3/d3.js?1.29.1"></script>
<style type="text/css">
html, body, #map {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.stations, .stations svg {
position: absolute;
}
.stations svg {
width: 500px;
height: 500px;
padding-right: 100px;
font: 10px sans-serif;
}
.stations circle {
fill: #888;
fill-opacity: 0.01;
stroke-opacity: 0.75;
}
.schwarzenberg {
stroke: #f0f;
color: #f0f;
fill: #f0f;
}
.zeman {
stroke: #f00;
color: #f00;
fill: #f00;
}
div.tooltip
{
position: absolute;
text-align: center;
width: 140px;
height: 25px;
padding: 8px;
font: 10px sans-serif;
background: #ffff99;
border: solid 1px #aaa;
border-radius: 8px;
pointer-events: none;
}
</style>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
var map = new google.maps.Map(d3.select("#map").node(), {
zoom: 8,
center: new google.maps.LatLng(50,15),
mapTypeId: google.maps.MapTypeId.TERRAIN
});
var radiusScale = d3.scale.sqrt().domain([0, 500000]).range([0, 100]);
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 1e-6);
d3.json("cz_president_2013_both_2_ring.json", function(data) {
var overlay = new google.maps.OverlayView();
var marker;
overlay.onAdd = function() {
var layer = d3.select(this.getPanes().overlayLayer).append("div")
.attr("class", "stations");
overlay.draw = function() {
var projection = this.getProjection(),
padding = 200;
marker = layer.selectAll("svg")
.data(d3.entries(data.features))
.each(transform)
.enter().append("svg:svg")
.each(transform);
marker.append("svg:circle")
.attr("r", function(d) {
return (radiusScale(d.value.population.p6)+radiusScale(d.value.population.p9))/2 * Math.pow(map.getZoom(),3) / 729;
})
.attr("stroke-width", function(d) {
return Math.abs(radiusScale(d.value.population.p9)-radiusScale(d.value.population.p6)) * Math.pow(map.getZoom(),3) / 729;
})
.attr("class", function(d) {return "marker" + ' ' + d.value.classname})
.attr("cx", padding)
.attr("cy", padding)
.attr("title", function(d) {d.value.name + ': ' + d.value.winner + ' vyhrál ' + Math.max(d.value.population.p6,d.value.population.p9) + ':' + Math.min(d.value.population.p6,d.value.population.p9) })
.on("mouseover", mouseover)
.on("mousemove", function(d){mousemove(d);})
.on("mouseout", mouseout);
function mouseover() {
div.transition()
.duration(300)
.style("opacity", 1);
}
function mousemove(d) {
div
.text(d.title)
.style("left", (d3.event.pageX ) + "px")
.style("top", (d3.event.pageY) + "px");
}
function mouseout() {
div.transition()
.duration(300)
.style("opacity", 1e-6);
}
function transform(d) {
d = new google.maps.LatLng(d.value.coordinates[1], d.value.coordinates[0]);
d = projection.fromLatLngToDivPixel(d);
return d3.select(this)
.style("left", (d.x - padding) + "px")
.style("top", (d.y - padding) + "px");
}
};
};
overlay.setMap(map);
google.maps.event.addListener(map, 'zoom_changed', function() {
zoomit();
function zoomit() {
d3.selectAll("circle").each(function(d,i) {
$(this)
.attr("r",
(radiusScale(d.value.population.p6)+radiusScale(d.value.population.p9))/2 * Math.pow(map.getZoom(),3) / 729
)
.attr("stroke-width",
Math.abs(radiusScale(d.value.population.p9)-radiusScale(d.value.population.p6)) * Math.pow(map.getZoom(),3) / 729
)
})
}
})
});
</script>
</body>
</html>