Skip to content

Instantly share code, notes, and snippets.

@rxw1
Created October 8, 2019 16:39
Show Gist options
  • Save rxw1/ca05d8ed507e8582439195365b980f43 to your computer and use it in GitHub Desktop.
Save rxw1/ca05d8ed507e8582439195365b980f43 to your computer and use it in GitHub Desktop.
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Deutschland</title>
<script src="https://d3js.org/d3.v5.js"></script>
<script src="https://unpkg.com/topojson@3"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<style type="text/css">
body {
margin: 0;
background-color: #d7d7d7;
}
.main {
height: 100%;
}
.svg-container {
display: inline-block;
position: relative;
width: 100%;
padding-bottom: 100%;
vertical-align: top;
overflow: hidden;
}
.svg-content {
display: inline-block;
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div id="main" class="svg-container"></div>
</body>
<script>
const colors = {
borders: "#ccc",
borders: "#ccc",
bg: "#d7d7d7"
}
const color = d => {
if (d.properties.NAME_2 == d.properties.NAME_3) {
return "#DC3FB7"
} else if (d.properties.NAME_1 == d.properties.NAME_2) {
return "#3F75DC"
} else {
return "#4a4a4a"
}
}
// margins
const margin = { top: 50, right: 50, bottom: 50, left: 50 }
let { width, height } = d3.select('#main').node().getBoundingClientRect();
width = width - margin.left - margin.right
height = height - margin.top - margin.bottom;
// svg setup
const svg = d3.select("#main")
.append("svg")
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", `0 0 ${width} ${height}`) // FIXME
.classed("svg-content", true)
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`)
var baseUrl = (level, detail) =>
`https://raw.githubusercontent.com/rwilhelm/deutschlandGeoJSON/master/${level}/${detail}.geojson`
var dataPromises = [
d3.json(baseUrl('2_bundeslaender', '4_niedrig')),
d3.json(baseUrl('3_regierungsbezirke', '4_niedrig')),
d3.json(baseUrl('4_kreise', '4_niedrig'))
]
Promise.all(dataPromises).then(data => {
var topology = topojson.topology({ foo: data[2] });
var geojson = topojson.feature(topology, topology.objects.foo)
var features = geojson.features;
const projection = d3.geoEqualEarth()
.fitExtent([[0, 0], [
width - margin.left - margin.right,
height - margin.top - margin.bottom,
]], geojson)
var path = d3.geoPath().projection(projection);
var drawPath = path(topojson.mesh(topology, topology.objects.foo, (a, b) => a !== b));
var autoColor = d3.scaleOrdinal().domain(features)
.range(d3.schemeSet3);
// draw text
var drawText = (el, id, x, y, dy, text) => {
return el.append("text")
.attr('id', id)
.attr("x", x)
.attr("y", y)
.attr("dy", dy)
.text(text);
}
// --- EVENTS ---
// mouse enters area
var onmouseenter = (d, i) => {
// autocolor area
d3.select(d3.event.target).attr("fill", autoColor);
// draw area names
drawText(svg, "land" + i, 50, 50, "0.35em", d.properties.NAME_1);
drawText(svg, "bezirk" + i, 50, 50, "1.35em", d.properties.NAME_2);
drawText(svg, "kreis" + i, 50, 50, "2.35em", d.properties.NAME_3);
}
// mouse leaves area
var onmouseleave = (d, i) => {
// reset area color
d3.select(d3.event.target).attr("fill", color)
// remove area names
d3.select("#land" + i).remove();
d3.select("#bezirk" + i).remove();
d3.select("#kreis" + i).remove();
}
// --- DRAW ---
// draw background
svg.append("rect")
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom)
.attr("fill", colors.bg);
// draw areas
svg.append("g")
.attr("cursor", "crosshair")
.selectAll("path")
.data(features)
.join("path")
.attr("stroke", colors.borders) // color boundaries 1
.attr("fill", color) // color areas
.attr("d", path)
.on("mouseenter", onmouseenter)
.on("mouseleave", onmouseleave)
// draw more proper borders
svg.select("g").append("path")
.attr("stroke", colors.borders) // color boundaries 2
.attr("fill", "none")
.attr("stroke-linejoin", "round")
.attr("d", drawPath)
})
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment