Public
Edited
May 12
Insert cell
Insert cell
data = await FileAttachment("Final - Women in African legislatures.csv").csv();
Insert cell
d3.version
Insert cell
filteredData = data.map(d => ({
year: new Date(d.Date).getFullYear(), // Code 1-4 reformats data to JavaScript style
country: d.Country,
chamber: d.Chamber,
femaleYoungerMPs: d["Female MPs 45 years of age or younger (percentage)"]
}));
Insert cell
filteredData.slice (0,5);
Insert cell
filteredData.map (d=> typeof d.femaleyoungerMPs);
Insert cell
Object.keys(filteredData[0]);
Insert cell
filteredData.map(d=> d.femaleYoungerMPs);
Insert cell
xScale = d3.scaleLinear()
.domain([0, d3.max(filteredData, d => d.femaleYoungerMPs)])
.range([50, 800]);
Insert cell
yScale = d3.scaleBand()
.domain(filteredData.map(d => d.country)) // Defines country positions
.range([50, 500]) // Vertical space where bars will be drawn
.padding(0.1); // Adds space between bars for better readability
Insert cell
svg = d3.create("svg")
.attr("width", 900)
.attr("height", 600);
Insert cell
svg.selectAll(".bar")
.data(filteredData)
.enter()
.append("rect")
.attr("class", "bar") // Assigns a class for styling
.attr("x", 50) // Bars start 50px from the left
.attr("y", d => yScale(d.country)) // Position bars based on country
.attr("width", d => xScale(d.femaleYoungerMPs)) // Scale width according to female MP percentage
.attr("height", yScale.bandwidth()) // Ensures bars are evenly spaced
.attr("fill", "#4CAF50"); // Colors bars green
Insert cell
svg.selectAll(".label")
.data(filteredData)
.enter()
.append("text")
.attr("class", "label")
.attr("x", d => xScale(d.femaleYoungerMPs) + 15) // Slightly outside the bar
.attr("y", d => yScale(d.country) + yScale.bandwidth() / 2) // Align text with bars
.attr("dy", "0.35em") // Centers text vertically
.text(d => d.country) // Displays country name
.attr("fill", "black")
.attr("font-size", "14px");
Insert cell
svg.selectAll(".chamber-label")
.data(filteredData)
.enter()
.append("text")
.attr("class", "chamber-label")
.attr("x", d => xScale(d.femaleYoungerMPs) + 5) // End of bar
.attr("y", d => yScale(d.country) + yScale.bandwidth() / 2)
.attr("dy", "0.35em")
.text(d => d.chamber) // Chamber name at the end of the bar
.attr("fill", "black")
.attr("font-size", "14px");
Insert cell
svg.append("text")
.attr("x", 400) // Centered horizontally
.attr("y", 580) // Positioned below the chart
.attr("text-anchor", "middle")
.attr("font-size", "16px")
.attr("fill", "black")
.text("Percentage of Female Younger MPs");
Insert cell
colorScale=d3.scaleOrdinal(d3.schemeCategory10);
Insert cell
svg.selectAll(".bar")
.style("fill", d => colorScale(d.country)); // Assign colors using `.style()` instead of `.attr()`
Insert cell
updateBars = function(newData) {
yScale.domain(newData.map(d => d.country));

svg.selectAll(".bar")
.data(newData, d => d.country)
.transition()
.duration(1000)
.attr("width", d => xScale(d.femaleYoungerMPs))
.attr("y", d => yScale(d.country));

svg.selectAll(".label")
.data(newData, d => d.country)
.transition()
.duration(1000)
.attr("x", d => xScale(d.femaleYoungerMPs) + 10)
.attr("y", d => yScale(d.country) + yScale.bandwidth() / 2);
};
Insert cell
yearIndex=0;
Insert cell
function runRace(data, years, initialYearIndex = 0, interval = 1500) {
let yearIndex = initialYearIndex;

function raceStep() {
if (yearIndex >= years.length) {
console.log("Race complete!");
return; // Stop when all years are shown
}

const newData = data.filter(d => d.year === years[yearIndex]); // Get data for current year

try {
updateBars(newData); // Update visualization
} catch (error) {
console.error("Error in updateBars:", error);
return; // Stop the race on error
}

yearIndex++; // Move to the next year
setTimeout(raceStep, interval); // Run again after the specified interval
}

raceStep(); // Start the race
}

// Example usage:
// Assuming 'allData', 'yearsArray', and 'updateBars' are defined elsewhere:
// runRace(allData, yearsArray, 0, 1000); // Start the race with a 1-second interval
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