function drawMap(borderColor, borderWidth) {
const margin = {top: 75, right: 100, bottom: 0, left: 0};
const visWidth = 1100 - margin.left - margin.right;
const visHeight = 700 - margin.top - margin.bottom;
const svg = d3.create('svg')
.attr('width', visWidth + margin.left + margin.right)
.attr('height', visHeight + margin.top + margin.bottom);
const g = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
const projection = d3.geoAlbersUsa()
.fitSize([visWidth, visHeight], usaGeo);
const path = d3.geoPath().projection(projection);
g.append('g')
.selectAll('path')
.data(usaGeo.features)
.join('path')
.attr('d', path)
.attr('fill', d => 'white')
.attr('stroke', borderColor)
.attr('stroke-width', borderWidth);
g.append("g")
.selectAll("circle")
.data(geoInfo)
.join("circle")
.attr("fill", "red")
.attr("cx", function(d) { return projection([d.lon,d.lat])[0] })
.attr("cy", function(d) { return projection([d.lon,d.lat])[1] })
.attr("r", d => 7)
.on('mouseenter', mouseEnter)
.on('mouseleave', mouseLeave);
// create tooltip
const tooltip = svg.append('g')
.attr('visibility', 'hidden');
const tooltipHeight = 16;
// add a rectangle to the tooltip to serve as a background
const tooltipRect = tooltip.append('rect')
.attr('fill', 'black')
.attr('rx', 5)
.attr('height', tooltipHeight);
// add a text element to the tooltip to contain the label
const tooltipText = tooltip.append('text')
.attr('fill', 'white')
.attr('font-family', 'sans-serif')
.attr('font-size', 12)
.attr('y', 2) // offset it from the edge of the rectangle
.attr('x', 3) // offset it from the edge of the rectangle
.attr('dominant-baseline', 'hanging');
// handle hovering over a circle
function mouseEnter(event, d) {
// make the circle larger
d3.select(this)
.attr('r', 7 * 2);
// update the label's text and get its width
tooltipText.text(d.school_name);
const labelWidth = tooltipText.node().getComputedTextLength();
tooltip.append('text')
.attr('fill', 'white')
.attr('font-family', 'sans-serif')
.attr('font-size', 12)
.attr('y', 15) // offset it from the edge of the rectangle
.attr('x', 3) // offset it from the edge of the rectangle
.attr('dominant-baseline', 'hanging')
.text(d.ban_type);
// set the width of the tooltip's background rectangle
// to match the width of the label, plus some extra space
tooltipRect.attr('width', labelWidth + 6);
// move the tooltip to the position of the circle (offset by a bit)
// and make the tooltip visible
const xPos = projection([d.lon,d.lat])[0];
const yPos = projection([d.lon,d.lat])[1];
tooltip.attr('transform', `translate(${xPos},${yPos})`)
.attr('visibility', 'visible');
}
// handle leaving a circle
function mouseLeave(event, d) {
// reset the size of the circle
d3.select(this)
.attr('r', 7)
// make the tooltip invisible
tooltip
.attr('visibility', 'hidden');
}
return svg.node();
}