Public
Edited
Apr 24, 2024
2 stars
Insert cell
Insert cell
US Population by Race@1.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
chart = {
// SVG setup
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");

// Define your color scale
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"; // Fallback color

// State positions on the grid
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();
}
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more