chart = {
const svg = d3.create("svg").attr("width", width).attr("height", height)
const xScale = d3.scaleLinear()
.domain(d3.extent(data, d=> +d.tavg_anomaly))
.range([margin.left, width-margin.right])
const yScale = d3.scaleLinear()
.domain(d3.extent(data, d=> +d.pcp_anomaly))
.range([height-margin.bottom, margin.top])
const colorScale = d3.scaleSequential(d3.interpolateBuPu)
.domain(d3.extent(data, d=> +d.wnv_incidence_cnt))
const sizeScale = d3.scaleSqrt()
.domain(d3.extent(data, d=> d.wnv_incidence_cnt))
.range(constants.radii)
const xAxis = d3.axisBottom(xScale);
const yAxis = d3.axisLeft(yScale);
const dotsContainer = svg.append("g").attr("class","container")
const dotgroups = dotsContainer.selectAll(".dot")
.data(data.sort((a, b)=> d3.ascending(+a.wnv_incidence_cnt, +b.wnv_incidence_cnt)))
.join("g")
.attr("class", d=>`dot ${"code-" + d.fipscode}`)
.attr("transform", d=> `translate(${xScale(+d.tavg_anomaly)}, ${yScale(+d.pcp_anomaly)})`)
.on("mouseover",function(d){
d3.select(this).raise();
console.log(d.fipscode)
d3.selectAll(`.dot`).selectAll("circle").attr("opacity", 0.3);
d3.selectAll(`.${"code-" + d.fipscode}`).selectAll("circle").attr("opacity", 1).attr("stroke", "black");
}).on("mouseout", function(){
console.log("mouseout")
d3.selectAll(`.dot`).selectAll("circle").attr("opacity", 0.6).attr("stroke", "unset");
});
dotgroups.append("circle")
.attr("fill", d=> d.wnv_incidence_cnt > threshold? colorScale(d.wnv_incidence_cnt): "lightgrey")
.attr("opacity", 0.6)
.attr("r", d=> sizeScale(d.wnv_incidence_cnt)) // make circle area scale
dotgroups.append("text")
.attr("class", "hover-label")
.text(d=> `${d.county} – ${d.year}`)
.attr("dy", d=> -sizeScale(d.wnv_incidence_cnt))
svg.append("g")
.attr("class", "axis x-axis")
.attr("transform", `translate(0, ${height- margin.bottom})`)
.call(xAxis)
.append("text")
.attr("class", "label")
.text("Avg. Temperature (∆ °C from mean)")
.attr("dy", "3em")
.attr("x", "50%");
svg.append("g")
.attr("class", "axis y-axis")
.attr("transform", `translate(${margin.left},0)`)
.call(yAxis)
.append("text")
.attr("class", "label")
.text("Precipitation (∆ cm from mean)")
.attr("y", "50%")
.attr("dx", "-3em")
.attr("writing-mode","vertical-lr");
// add quadrant lines
const annotationGroup = svg.append("g").attr("class", "annotations")
annotationGroup.append("path")
.attr("stroke","grey")
.attr("transform",`translate(${xScale(0)},0)`)
.attr("d", `M 0 ${margin.top} L 0 ${height - margin.bottom}`)
annotationGroup.append("text")
.attr("x", width -margin.right)
.attr("y", height* .9)
.style("text-anchor", "end")
.text("Hotter and Drier")
annotationGroup.append("path")
.attr("stroke","grey")
.attr("transform",`translate(0,${yScale(0)})`)
.attr("d", `M ${margin.left} 0 L ${width - margin.right} 0`)
annotationGroup.append("text")
.attr("x", margin.left * 1.5)
.attr("y", margin.top * 2)
.style("text-anchor", "start")
.text("Cooler and Wetter")
// TODO: labels above a certain value
return svg.node()
}