mouseMove = () => {
d3.event.preventDefault();
const mouse = d3.mouse(d3.event.target);
const [
xCoord,
yCoord,
] = mouse;
const mouseDate = xScale.invert(xCoord);
const mouseDateSnap = d3.timeYear.floor(mouseDate);
if (xScale(mouseDateSnap) < margin.left ||
xScale(mouseDateSnap) > width - margin.right) {
return;
}
const bisectDate = d3.bisector(d => d.date).right;
const xIndex = bisectDate(data, mouseDateSnap, 1);
const mousePopulation = data[xIndex].population;
svg.selectAll('.hoverLine')
.attr('x1', xScale(mouseDateSnap))
.attr('y1', margin.top)
.attr('x2', xScale(mouseDateSnap))
.attr('y2', height - margin.bottom)
.attr('stroke', '#147F90')
.attr('fill', '#A6E8F2')
;
svg.selectAll('.hoverPoint')
.attr('cx', xScale(mouseDateSnap))
.attr('cy', yScale(mousePopulation))
.attr('r', '7')
.attr('fill', '#147F90')
;
const isLessThanHalf = xIndex > data.length / 2;
const hoverTextX = isLessThanHalf ? '-0.75em' : '0.75em';
const hoverTextAnchor = isLessThanHalf ? 'end' : 'start';
svg.selectAll('.hoverText')
.attr('x', xScale(mouseDateSnap))
.attr('y', yScale(mousePopulation))
.attr('dx', hoverTextX)
.attr('dy', '-1.25em')
.style('text-anchor', hoverTextAnchor)
.text(d3.format('.5s')(mousePopulation));
};