{ const width = 800;
const height = 800;
const marginLeft = 50;
const marginRight = 50;
const marginBottom = 50;
const marginTop = 10;
const smallFont = 12;
const medFont = 14;
const bigFont = 20;
const svg = d3
.create("svg")
.attr("viewBox", [0, 0, width*1.2, height*1.2]);
const xScale = d3
.scaleLinear()
.domain([0,100])
.range([marginLeft, width - marginRight]);
const yScale = d3
.scaleLinear()
.domain([100,0])
.range([marginTop+50, height - marginBottom]);
const xAxis = d3.axisBottom(xScale);
svg
.append("g")
.attr("class", "axis x-axis")
.attr("transform", `translate(0,${height-marginBottom})`)
.call(xAxis)
.append("text")
.attr("class", "axis-label")
.attr("x", "50%")
.attr("dy", "3em")
.text("Share of State Population")
.attr("fill", "#777");
const yAxis = d3.axisLeft(yScale);
svg
.append("g")
.attr("class", "axis y-axis")
.attr("transform", `translate(${marginLeft},${marginTop-10})`)
.call(yAxis)
.append("text")
.attr("class", "axis-label")
.attr("y", "50%")
.attr("dx", "-3em")
.attr("writing-mode", "vertical-rl")
.text("Share of Shooting Population")
.attr("fill", "#777")
const point = svg
.selectAll("circle")
.data(scatterBW)
// .data(scatterAll.flat())
.enter()
.append("circle")
.attr("class", (d) => "circle " + d.state + " " + d.race)
.attr("cy", (d) => yScale(d.shootingPct))
.attr("cx", (d) => xScale(d.demoPct))
.attr("r", 4)
.attr("fill", d => colorScale(d.race))
.attr("opacity", 1)
.on("mouseover", function(d) {
d3.select(this)
.attr("stroke", "black")
})
const groups = svg
.selectAll(“g”)
.data(d=> [d])
.join(“g”)
const lines = svg
.selectAll("line")
.data(scatterAll)
.join("line")
// .attr("CL", d => console.log(d))
.attr("x1", d => d.has("B") && xScale(d.get("B").demoPct))
.attr("x2", d => d.has("W") && xScale(d.get("W").demoPct))
.attr("y1", d => d.has("B") && yScale(d.get("B").shootingPct))
.attr("y2", d => d.has("W") && yScale(d.get("W").shootingPct))
.attr("stroke", "black")
// const lines = svg
// .selectAll((d) => "circle " + d.state)
// .filter(function (d) { return d.state, console.log("d", d.state)} )
// .append('line')
// .attr("stroke", "red")
// .attr('x1', function(d) { return xScale(d.demoPct)}) // return the point value
// //.attr('x2', function(d) { if (d.race === "B") find (d.race === "W"); return xScale(d.demoPct),
// // else if (d.race === "W") find (d.race === "B"); return xScale(d.demoPct)})
// // return the point value for the same state but the other race ^^
// .attr('y1', function(d) { return xScale(d.shootingPct)})
// //.attr('y2', function(d) { if (d.race === "B") find (d.race === "W"); return xScale(d.shootingPct),
// else if (d.race === "W") find (d.race === "B"); return xScale(d.shootingPct)})
//lines.attr(console.log("lines", lines))
//TODO:
// on click, add stroke to all dots in that state
// point color legend
/*
const legend = svg.append("g")
.attr("fill", "#777")
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.selectAll("g")
.data(colorScale)
.join("g")
.attr("transform", (d, i) => `translate(${width*.95 - (i + 1) * 25}, ${height*.87})`);
legend.append("circle")
.attr("fill-opacity", 1)
.attr("fill", d => (colorScale(d)))
.attr("r", 4)
legend.append("text")
.attr("dy", "2em");
//legend label
svg.append("text")
.attr("fill", "#777")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("transform", `translate (${width*.78}, ${height*.92})`)
.text("shootings by race");
*/
const legendBW = svg.append("g")
.attr("fill", "#777")
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.selectAll("g")
.data(["#7fc97f", "#beaed4"])
.join("g")
.attr("transform", (d, i) => `translate(${width*.77}, ${height*.93 - (i + 1) * 25})`);
legendBW.append("circle")
.attr("fill-opacity", 1)
.attr("fill", d => (d))
.attr("r", 4)
//legendBW label
svg.append("text")
.attr("fill", "#777")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("transform",`translate (${width*.79}, ${height*.872})`)
.text(`Black shootings per state`);
svg.append("text")
.attr("fill", "#777")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("transform",`translate (${width*.79}, ${height*.903})`)
.text(`White shootings per state`);
// line y=x
svg.append("line")
.attr("x1", xScale(0))
.attr("y1", yScale(0))
.attr("x2", xScale(100))
.attr("y2", yScale(100))
//.attr("stroke", "dashed")
.style("stroke-dasharray", ("3, 3"))
.attr("stroke", "#777")
// annotations
// y=x annotation
svg.append("text")
.text("Police shooting demographics match state population demographics")
.attr("transform", `translate(${width*.6}, ${height*.38}) rotate(-45)`)
.attr("fill", "#888")
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", smallFont);
// over rep
svg.append("text")
.text("Overrepresented as victims of police violence")
.attr("transform", `translate(${width*.3}, ${height*.25})`)
.attr("fill", "#888")
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", smallFont);
// under rep
svg.append("text")
.text("Underrepresented as victims of police violence")
.attr("transform", `translate(${width*.8}, ${height*.65})`)
.attr("fill", "#888")
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", smallFont);
// title
svg.append("text")
.attr("fill", "#777")
.attr("font-family", "sans-serif")
.attr("font-size", bigFont)
.attr("transform",
`translate(${width*.2}, 40)`
)
.text("Police Shooting Deaths by state and race, Jan 2015 - Aug 2020");
const tooltip2 = svg.append("g");
svg
.selectAll(".circle")
.on("mouseover", function(d) {
tooltip2.call(callout, `${d.state}
${d.absoluteNum} ${raceLookup[d.race]} people shot by police`)
tooltip2.attr("transform", `translate(${xScale(d.demoPct)}, ${yScale(d.shootingPct)})` )
.transition()
.duration(500)
.attr("fill-opacity", 0.8) //add stroke to circle and remove on mouseout
})
return svg.node();
}