Published
Edited
Sep 21, 2021
1 fork
Insert cell
Insert cell
Insert cell
languageData = await d3.json(
"https://api.census.gov/data/2019/acs/acs1?get=NAME,B01001_001E,B16001_105E,B16001_003E&for=state:*"
)
Insert cell
Insert cell
languageStates = {
const data = [];

for (let i = 1; i < languageData.length; i++) {
const state = languageData[i];
data.push({
name: state[0],
totalPopulation: parseInt(state[1]),
arabic: state[3] == null ? 0 : parseInt(state[2]),
arabicPercent:
state[3] == null ? 0 : parseInt(state[2]) / parseInt(state[1]),
spanish: state[3] == null ? 0 : parseInt(state[3]),
spanishPercent:
state[3] == null ? 0 : parseInt(state[3]) / parseInt(state[1]),
fipsCode: state[4]
});
}
return data;
}
Insert cell
Insert cell
{
const height = width;
const margin = 120;
const svg = d3.create("svg").attr("width", width).attr("height", width);

svg
.append("rect")
.attr("width", width)
.attr("height", width)
.attr("fill", "#282c37");

const gridCount = 10;
const lineSpacing = (width - margin * 2) / gridCount;

for (let i = 0; i <= gridCount; i++) {
svg
.append("line")
.attr("x1", margin)
.attr("x2", width - margin)
.attr("y1", margin + i * lineSpacing)
.attr("y2", margin + i * lineSpacing)
.attr("stroke", "white")
.attr("opacity", 0.5);

svg
.append("line")
.attr("y1", margin)
.attr("y2", width - margin)
.attr("x1", margin + i * lineSpacing)
.attr("x2", margin + i * lineSpacing)
.attr("stroke", "white")
.attr("opacity", 0.5);
}

const spanishScale = d3
.scaleLinear()
.domain(d3.extent(languageStates, (d) => d.spanish))
.range([margin, width - margin]);

const arabicScale = d3
.scaleLinear()
.domain(d3.extent(languageStates, (d) => d.arabic))
.range([height - margin, margin]);

const colorScale = d3
.scaleLinear()
.domain(d3.extent(languageStates, (d) => d.totalPopulation))
.range([0, 1]);

for (let i = 0; i < languageStates.length; i++) {
const state = languageStates[i];
svg
.append("circle")
.attr("cx", spanishScale(state.spanish))
.attr("cy", arabicScale(state.arabic))
.attr("r", 6)
.attr("stroke", "white")
.attr("fill", d3.interpolateViridis(colorScale(state.totalPopulation)));

svg
.append("text")
.attr("x", 10 + spanishScale(state.spanish))
.attr("y", arabicScale(state.arabic))
.text(state.name)
.attr("font-family", "courier")
.attr("font-size", 14)
.attr("fill", "white")
.attr("alignment-baseline", "middle");
}

svg
.append("text")
.attr("x", width - margin)
.attr("y", height - margin / 2)
.text("+ Spanish-Speaking People")
.attr("text-anchor", "end")
.attr("fill", "white")
.attr("font-family", "courier")
.attr("font-size", 14);

svg
.append("text")
.attr("x", margin / 2)
.attr("y", margin)
.text("+ Arabic-Speaking People")
.attr("text-anchor", "end")
.attr("fill", "white")
.attr("font-family", "courier")
.attr("font-size", 14)
.attr("transform", "rotate(-90 " + margin / 2 + "," + margin + ")");

svg
.append("text")
.attr("x", width / 2)
.attr("y", margin / 2)
.text("Population that Speaks Spanish Compared to Arabic")
.attr("text-anchor", "middle")
.attr("fill", "white")
.attr("font-family", "courier")
.attr("font-size", 16);

return svg.node();
}
Insert cell
Insert cell
{
const height = width;
const margin = 120;
const svg = d3.create("svg").attr("width", width).attr("height", width);
svg
.append("rect")
.attr("width", width)
.attr("height", width)
.attr("fill", "#282c37");

const gridCount = 10;
const lineSpacing = (width - margin * 2) / gridCount;

for (let i = 0; i <= gridCount; i++) {
svg
.append("line")
.attr("x1", margin)
.attr("x2", width - margin)
.attr("y1", margin + i * lineSpacing)
.attr("y2", margin + i * lineSpacing)
.attr("stroke", "white")
.attr("opacity", 0.5);

svg
.append("line")
.attr("y1", margin)
.attr("y2", width - margin)
.attr("x1", margin + i * lineSpacing)
.attr("x2", margin + i * lineSpacing)
.attr("stroke", "white")
.attr("opacity", 0.5);
}

const spanishPercentScale = d3
.scaleLinear()
.domain(d3.extent(languageStates, (d) => d.spanishPercent))
.range([margin, width - margin]);

const arabicPercentScale = d3
.scaleLinear()
.domain(d3.extent(languageStates, (d) => d.arabicPercent))
.range([height - margin, margin]);

const colorScale = d3
.scaleLinear()
.domain(d3.extent(languageStates, (d) => d.totalPopulation))
.range([0, 1]);

for (let i = 0; i < languageStates.length; i++) {
const state = languageStates[i];
svg
.append("circle")
.attr("cx", spanishPercentScale(state.spanishPercent))
.attr("cy", arabicPercentScale(state.arabicPercent))
.attr("fill", d3.interpolateViridis(colorScale(state.totalPopulation)))
.attr("stroke", "white")
.attr("r", 5);

svg
.append("text")
.attr("x", 10 + spanishPercentScale(state.spanishPercent))
.attr("y", arabicPercentScale(state.arabicPercent))
.text(state.name)
.attr("fill", "white")
.attr("font-family", "courier")
.attr("font-size", 14)
.attr("alignment-baseline", "middle");
}

svg
.append("text")
.attr("x", width - margin)
.attr("y", height - margin / 2)
.text("+ Spanish Percentage")
.attr("text-anchor", "end")
.attr("fill", "white")
.attr("font-family", "courier")
.attr("font-size", 14);

svg
.append("text")
.attr("x", margin / 2)
.attr("y", margin)
.text("+ Arabic Percentage")
.attr("text-anchor", "end")
.attr("fill", "white")
.attr("font-family", "courier")
.attr("font-size", 14)
.attr("transform", "rotate(-90 " + margin / 2 + "," + margin + ")");

svg
.append("text")
.attr("x", width / 2)
.attr("y", margin / 2)
.text("Percentage of Population that Speaks Spanish Compared to Arabic")
.attr("text-anchor", "middle")
.attr("fill", "white")
.attr("font-family", "courier")
.attr("font-size", 16);

return svg.node();
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more