chart = {
const svgWidth = 1000;
const svgHeight = 800;
const svg = d3
.create("svg")
.attr("viewBox", [0, 0, svgWidth, svgHeight])
.style("font", "10px sans-serif");
svg
.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "#efece9");
const customColorScale = {
White: "#779ecc",
Black: "#dfd04c",
Hispanic: "#c270ab",
Asian: "#6ec4bc",
"Multiple Races": "#b0c769",
"American Indian / Alaska Native": "#264b4c",
"Native Hawaiian / Other Pacific Islander": "#e58852"
};
const getColor = (race) => customColorScale[race] || "#ccc";
const statePositions = {
Alabama: { x: 5, y: 7 },
Alaska: { x: 1, y: 1 },
Washington: { x: 2, y: 3 },
Idaho: { x: 3, y: 3 },
Montana: { x: 4, y: 3 },
"North Dakota": { x: 5, y: 3 },
Minnesota: { x: 6, y: 3 },
Illinois: { x: 7, y: 3 },
Wisconsin: { x: 8, y: 3 },
Michigan: { x: 9, y: 3 },
"New York": { x: 10, y: 3 },
"Rhode Island": { x: 11, y: 3 },
Vermont: { x: 11, y: 2 },
"New Hampshire": { x: 12, y: 2 },
Maine: { x: 12, y: 1 },
Oregon: { x: 2, y: 4 },
Nevada: { x: 3, y: 4 },
Wyoming: { x: 4, y: 4 },
"South Dakota": { x: 5, y: 4 },
Iowa: { x: 6, y: 4 },
Indiana: { x: 7, y: 4 },
Ohio: { x: 8, y: 4 },
Pennsylvania: { x: 9, y: 4 },
"New Jersey": { x: 10, y: 4 },
Connecticut: { x: 11, y: 4 },
Massachusetts: { x: 12, y: 3 },
California: { x: 2, y: 5 },
Utah: { x: 3, y: 5 },
Colorado: { x: 4, y: 5 },
Kansas: { x: 5, y: 6 },
Missouri: { x: 6, y: 5 },
Kentucky: { x: 7, y: 5 },
"West Virginia": { x: 8, y: 5 },
Virginia: { x: 9, y: 5 },
Maryland: { x: 10, y: 5 },
Delaware: { x: 11, y: 5 },
Arizona: { x: 3, y: 6 },
"New Mexico": { x: 4, y: 6 },
Texas: { x: 5, y: 8 },
Oklahoma: { x: 5, y: 7 },
Arkansas: { x: 6, y: 6 },
Tennessee: { x: 7, y: 6 },
"North Carolina": { x: 8, y: 6 },
"South Carolina": { x: 9, y: 6 },
Georgia: { x: 9, y: 7 },
Alabama: { x: 8, y: 7 },
Florida: { x: 10, y: 8 },
Alaska: { x: 1, y: 1 },
Hawaii: { x: 1, y: 8 },
"Puerto Rico": { x: 12, y: 9 },
Nebraska: { x: 5, y: 5 },
Mississippi: { x: 7, y: 7 },
Louisiana: { x: 6, y: 7 },
"District of Columbia": { x: 12, y: 8 }
};
// Define cell size and padding between cells
const cellSize = 60;
const cellPadding = 15;
// Function to get grid position for a state
function getGridPosition(state) {
if (statePositions[state]) {
const pos = statePositions[state];
return {
x: pos.x * (cellSize + cellPadding),
y: pos.y * (cellSize + cellPadding)
};
}
return { x: 0, y: 0 };
}
const tooltip = d3
.select("body")
.append("div")
.attr("class", "tooltip")
.style("position", "absolute")
.style("visibility", "hidden")
.style("background", "#efece9")
.style("border", "1px solid #ccc")
.style("border-radius", "5px")
.style("padding", "10px")
.style("box-shadow", "2px 2px 10px rgba(0,0,0,0.3)")
.style("pointer-events", "none")
.style("font-size", "10px");
// Draw cells for each state
const cells = svg
.selectAll("g")
.data(data)
.join("g")
.attr("transform", (d) => {
const position = getGridPosition(d.State);
return `translate(${position.x}, ${position.y})`;
});
// Draw rectangles for each demographic within the state cell
cells.each(function (d) {
const node = d3.select(this);
const races = [
"White",
"Black",
"Hispanic",
"Asian",
"Multiple Races",
"American Indian / Alaska Native",
"Native Hawaiian / Other Pacific Islander"
];
let x0 = 0;
races.forEach((race) => {
const width = d[race] * cellSize;
node
.append("rect")
.attr("x", x0)
.attr("width", width)
.attr("height", cellSize)
.attr("fill", getColor(race));
x0 += width;
});
});
cells
.on("mouseover", (event, d) => {
tooltip.html(generateTooltipHtml(d)).style("visibility", "visible");
})
.on("mousemove", (event) => {
tooltip
.style("top", event.pageY - 10 + "px")
.style("left", event.pageX + 10 + "px");
})
.on("mouseout", () => {
tooltip.style("visibility", "hidden");
});
// Generate tooltip HTML content
function generateTooltipHtml(d) {
let html = `<strong>${d.State}</strong><br/>`;
const races = [
"White",
"Black",
"Hispanic",
"Asian",
"Multiple Races",
"American Indian / Alaska Native",
"Native Hawaiian / Other Pacific Islander"
];
races.forEach((race) => {
const color = getColor(race);
html += `<span style="display:inline-block; width:12px; height:12px; margin-right:4px; background-color:${color};"></span>${race}: ${(
d[race] * 100
).toFixed(0)}%<br/>`;
});
return html;
}
// Add state labels
cells
.append("text")
.attr("x", cellSize / 2)
.attr("y", cellSize / 2)
.attr("dy", "3.8em")
.attr("text-anchor", "middle")
.text((d) => d.State)
.style("font-family", "Manrope")
.style("font-weight", "bold")
.attr("fill", "black");
// Add a title to the SVG
svg
.append("text")
.attr("x", svgWidth / 2)
.attr("y", 90)
.attr("text-anchor", "middle")
.style("font-size", "35px")
.style("font-weight", "bold")
.style("font-family", "Manrope")
.style("fill", "black")
.text("America's Racial Breakdown by State");
svg
.append("text")
.attr("x", svgWidth / 2)
.attr("y", 130)
.attr("text-anchor", "middle")
.style("font-size", "15px")
.style("font-family", "Manrope")
.style("font-style", "italic")
.style("font-weight", "bold")
.text("We become not a melting pot but a beautiful mosaic.");
svg
.append("text")
.attr("x", svgWidth / 2)
.attr("y", 160)
.attr("text-anchor", "middle")
.style("font-size", "15px")
.style("font-family", "Manrope")
.style("font-style", "italic")
.style("font-weight", "bold")
.text(
"Different people, different beliefs, different yearnings, different hopes, different dreams."
);
svg
.append("text")
.attr("x", svgWidth / 2)
.attr("y", 770)
.attr("text-anchor", "middle")
.style("font-size", "12px")
.style("font-family", "Manrope")
.text(
"Data Source:US Pouplation by Race Visual Capitalist Graphic: Deepali Kank"
);
svg
.append("text")
.attr("x", svgWidth / 2)
.attr("y", 200)
.attr("text-anchor", "left")
.style("font-size", "15px")
.style("font-family", "Manrope")
.text("—Jimmy Carter, 39th President of the U.S");
const hawaiiPosition = getGridPosition("Hawaii");
// Add detailed text for Hawaii below its grid square
svg
.append("text")
.attr("x", hawaiiPosition.x)
.attr("y", hawaiiPosition.y + cellSize + 20)
.attr("text-anchor", "right")
.style("font-size", "11px")
.style("font-family", "Manrope")
.text("Hawaii is home to the largest share of Asian populations at 39%.");
svg
.append("text")
.attr("x", hawaiiPosition.x)
.attr("y", hawaiiPosition.y + cellSize + 35)
.attr("text-anchor", "right")
.style("font-size", "11px")
.style("font-family", "Manrope")
.text(
"It also has one of the most diverse racial breakdowns in the nation overall,"
);
svg
.append("text")
.attr("x", hawaiiPosition.x)
.attr("y", hawaiiPosition.y + cellSize + 50)
.attr("text-anchor", "right")
.style("font-size", "11px")
.style("font-family", "Manrope")
.text("including the highest proportion of mixed race individuals.");
return svg.node();
}