An example of using GeoJSON data and a Voronoi map for hovers.
xxxxxxxxxx
<head>
<meta charset="utf-8">
<style>
.stop {
fill: #C83D2D;
stroke: #C83D2D;
stroke-width: 0.01px;
}
.stop.active {
stroke-width: 0.05px;
}
.voronoi-stops {
fill: transparent;
stroke-width: 0.001;
stroke: #676767;
}
.text-tooltip {
position: absolute;
top: 0;
right: 0;
margin: 1em 1em 0 0;
padding: 1em;
font-size: 1.5em;
background-color: #F2F2F2;
border: 1px solid #222222;
}
</style>
</head>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script>
d3.json('metrotransit-green-line-stops.geo.json', function(error, stops) {
var width = 960;
var height = 500;
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height);
// Make projection and path handler
var projectionData = stops;
var centroid = d3.geo.centroid(projectionData);
var projection = d3.geo.albersUsa()
.scale(1000)
.translate([width / 2, height / 2]);
var projectionPath = d3.geo.path().projection(projection)
.pointRadius(function(d) { return 0.002; });
// Make group for features
var featureGroup = svg.append('g').attr('class', 'feature-group');
// Fit map to data
var b = projectionPath.bounds(projectionData);
featureGroup.attr('transform',
'translate(' + projection.translate() + ') ' +
'scale(' + 0.95 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height) + ') ' +
'translate(' + -(b[1][0] + b[0][0]) / 2 + ',' + -(b[1][1] + b[0][1]) / 2 + ')');
// Add stops
featureGroup.selectAll('.stop')
.data(stops.features)
.enter().append('path')
.attr('class', 'stop')
.attr('d', function(d) {
// Attach this path to data
d.stopPath = this;
return projectionPath(d);
});
// Make Voronoi map for hovering over stop
var text = d3.select('body').append('div').attr('class', 'text-tooltip');
var voronoiStops = d3.geom.voronoi()
.x(function(d) { return projection(d.geometry.coordinates)[0]; })
.y(function(d) { return projection(d.geometry.coordinates)[1]; })
.clipExtent([[0, 0], [width, height]]);
featureGroup.selectAll('.voronoi-stops')
.data(voronoiStops(stops.features))
.enter().append('path')
.attr('class', 'voronoi-stops')
.attr('d', function(d) { return 'M' + d.join('L') + 'Z'; })
.on('mouseover', function(d) {
text.style('display', 'block')
.text(d.point.properties.Station);
d3.select(d.point.stopPath).classed('active', true);
})
.on('mouseout', function(d) {
text.style('display', 'none')
.text('');
d3.select(d.point.stopPath).classed('active', false);
});
});
</script>
</body>
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://d3js.org/topojson.v1.min.js to a secure url
https://d3js.org/d3.v3.min.js
https://d3js.org/topojson.v1.min.js