My original intention was to create a simple example of Thailand map using d3.js. This was modified to only show the Bangkok Metro area.
Credit Apisit Toompakdee for his GeoJSON file thailand.json
forked from kristw's block: Thailand map
xxxxxxxxxx
<meta charset="utf-8">
<style>
.background {
fill: #eee;
pointer-events: all;
}
path {
stroke: none;
}
.map-layer {
fill: #fff;
stroke: #aaa;
}
text{
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: 300;
}
text.big-text{
font-size: 30px;
font-weight: 400;
}
</style>
<body>
<svg></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
const width = 960;
const height = 500;
let centered;
// Define color scale
const color = d3.scaleOrdinal(d3.schemeCategory10)
// Set svg width & height
const svg = d3.select('svg')
.attr('width', width)
.attr('height', height);
// Add background
svg.append('rect')
.attr('class', 'background')
.attr('width', width)
.attr('height', height)
.on('click', clicked);
const g = svg.append('g');
const mapLayer = g.append('g')
.classed('map-layer', true);
const bigText = g.append('text')
.classed('big-text', true)
.attr('x', 20)
.attr('y', 45);
const path = d3.geoPath()
// Load map data
d3.json('thailand.json', function(error, mapData) {
const provinces = new RegExp('^(' + [
'Bangkok',
'SamutPrakan',
'Nonthaburi',
'SamutSakhon',
'PathumThani',
'NakhonPathom'
].join('|') + ')$');
mapData.features = mapData.features
.filter(d => provinces.test(d.properties.CHA_NE));
const features = mapData.features;
const projection = d3.geoMercator()
.rotate([-100.6331, -13.2])
.fitSize([width, height], mapData);
path.projection(projection);
// Draw each province as a path
const sEnter = mapLayer.selectAll('path')
.data(features)
.enter().append('g')
.on('mouseover', mouseover)
.on('mouseout', mouseout)
.on('click', clicked);
sEnter.append('path')
.attr('d', path)
.attr('vector-effect', 'non-scaling-stroke')
.style('fill', fillFn)
sEnter.append('text')
.attr('x', d => path.centroid(d)[0])
.attr('y', d => path.centroid(d)[1])
.style('text-anchor', 'middle')
.style('stroke', '#222')
.text(nameFn)
});
// Get province name
function nameFn(d){
return d && d.properties ? d.properties.CHA_NE : null;
}
// Get province color
function fillFn(d, i){
return color(i);
}
// When clicked, zoom in
function clicked(d) {
let x, y, k;
// Compute centroid of the selected path
if (d && centered !== d) {
let centroid = path.centroid(d);
x = centroid[0];
y = centroid[1];
k = 4;
centered = d;
} else {
x = width / 2;
y = height / 2;
k = 1;
centered = null;
}
// Highlight the clicked province
mapLayer.selectAll('path')
.style('fill', (d, i) => centered && d===centered ? '#D5708B' : fillFn(d, i));
// Zoom
g.transition()
.duration(750)
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')scale(' + k + ')translate(' + -x + ',' + -y + ')');
}
function mouseover(d){
// Highlight hovered province
d3.select(this).style('fill', 'orange');
bigText.text(nameFn(d))
}
function mouseout(d){
// Reset province color
mapLayer.selectAll('path')
.style('fill', (d, i) => centered && d===centered ? '#D5708B' : fillFn(d, i));
// Clear province name
bigText.text('');
}
</script>
https://d3js.org/d3.v4.min.js