viz = {
const svg = d3.create("svg").attr("width", width).attr("height", height);
const visualizationKeys =
vizTopic == "Females vs Males"
? ["femaleDifficultyPercentage", "maleDifficultyPercentage"]
: ["hearingDifficultyPercentage", "visionDifficultyPercentage"];
svg
.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height)
.attr("fill", bgColor);
svg
.append("g")
.attr("transform", "translate(0," + (height - margin) + ")")
.call(xAxis)
.call((g) => {
g.selectAll("line");
});
svg
.append("g")
.attr("transform", "translate(" + margin + ")")
.call(yAxis)
.call((g) => {
g.select(".domain").remove();
g.selectAll("line").attr("stroke-dasharray", "2,4");
});
//style axes
svg
.selectAll(".tick text")
.attr("font-size", "10px")
.attr("fill", "#566270")
.attr("font-family", "menlo");
svg.selectAll("line").attr("stroke", "#566270");
//create line *behind* the circles
svg
.selectAll(".dumbell")
.data(disabilityStates, (d) => d.fips)
.enter()
.append("line")
.attr("x1", (d) => abbreviationToPixelsX(d.abbreviation))
.attr("y1", (d) => percentToPixelsY(d[visualizationKeys[0]]))
.attr("x2", (d) => abbreviationToPixelsX(d.abbreviation))
.attr("y2", (d) => percentToPixelsY(d[visualizationKeys[1]]))
.attr("alt", "red")
.attr("stroke", (d) =>
//check which key is larger, and use the appropriate color for the line. ternary!!!
d[visualizationKeys[0]] > d[visualizationKeys[1]]
? colorFemaleHearing
: colorMaleVision
)
.attr("stroke-width", 2)
.attr("class", "dumbell");
//standard data binding - no for loop!!!
svg
.selectAll(".circlesCategoryA")
.data(disabilityStates, (d) => d.fips)
.enter()
.append("circle")
.attr("cx", (d) => abbreviationToPixelsX(d.abbreviation))
.attr("cy", (d) => percentToPixelsY(d[visualizationKeys[0]]))
.attr("r", 5)
.attr("fill", colorFemaleHearing)
.attr("class", "circlesCategoryA")
//disregard the next two lines for interactivity -- that's next week's focus!
.on("mouseover", (event, datum) => tooltipShow(event, datum, 0))
.on("mouseout", (event, datum) => tooltipHide(event, datum));
svg
.selectAll(".circlesCategoryB")
.data(disabilityStates, (d) => d.fips)
.enter()
.append("circle")
.attr("cx", (d, i) => abbreviationToPixelsX(d.abbreviation))
.attr("cy", (d) => percentToPixelsY(d[visualizationKeys[1]]))
.attr("r", 5)
.attr("fill", colorMaleVision)
.attr("class", "circlesCategoryB")
//disregard the next two lines for interactivity -- that's next week's focus!
.on("mouseover", (e, d) => tooltipShow(e, d, 1))
.on("mouseout", (event, datum) => tooltipHide(event, datum));
svg
.append("text")
.text("")
.attr("y", margin / 2)
.attr("id", "tooltip")
.attr("opacity", 0)
.attr("font-family", "menlo")
.attr("font-size", "10px")
.attr("text-anchor", "middle");
//show visualization in Observable
return svg.node();
}