Public
Edited
May 9
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
combinedChart = (() => {
const classificationColors = {
"ecological": "#00CC00",
"socialist": "#FF0000",
"social democratic": "#FF9500",
"liberal": "#FFCC00",
"christian democratic": "#99CCFF",
"conservative": "#1E90FF",
"nationalist": "#8B0000",
"agrarian": "#F5DEB3",
"ethnic/regional": "#FF8C00",
"special issue": "#9400D3",
"electoral alliances without a dominant party": "#00CCCC",
"missing information": "#808080"
};
//pretty self explanatory function
function capitalizeWords(str) {
if (!str) return "";
return str
.split(/[\s/]+/)
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ");
}
//another text parsing function, returns lowercase name
function normalizeCountry(name) {
return name ? name.trim().toLowerCase() : "";
}
const selectedYear = YearSlider;
const clickedCountry = (selectedCountry || "Austria").split(" | ")[0];
const normalizedSelectedCountry = normalizeCountry(clickedCountry);
console.log("Normalized Selected Country:", normalizedSelectedCountry);
console.log("Selected Year:", selectedYear);
//filter political dataset by year and country selection to get party share-of-vote values
const filteredData = ActualDataTwo.filter(d =>
normalizeCountry(d.Country) === normalizedSelectedCountry &&
+d.Year === selectedYear);
console.log("Filtered Data:", filteredData);
if (filteredData.length === 0) {
return md`No election data for **${clickedCountry}** in **${selectedYear}**.`;
};
const style = document.createElement('style');
style.textContent = `
.plot-tooltip {
background: rgba(0, 0, 0, 0.8) !important;
color: white !important;
padding: 15px 20px !important;
border-radius: 8px !important;
font-size: 16px !important;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3) !important;
min-width: 200px !important;
max-width: 300px !important;
white-space: pre-wrap !important;
font-family: sans-serif !important;
line-height: 1.5 !important;
}
`;
document.head.appendChild(style);
const plotChart = Plot.plot({
width: 450,
height: 350,
marginTop: 20,
marginRight: 20,
marginBottom: 100,
marginLeft: 40,
x: {
label: "Political Party",
tickRotate: -45,
tickSize: 0
},
y: {
label: "Seats Won"
},
marks: [
Plot.barY(
filteredData,
{
x: "Party Initials",
y: "Seats Won",
sort: { x: "y", reverse: true },
fill: d => {
if (!d || !d["Party Classification"]) return "#ccc";
return classificationColors[d["Party Classification"].toLowerCase()] || "#ccc";
},
tip: true,
title: d => {
if (!d) return "No data";
const initials = d["Party Initials"] || "N/A";
const partyName = d["Party Name (English)"] || "Unknown";
const seats = d["Seats Won"] || "0";
const classification = d["Party Classification"] ? capitalizeWords(d["Party Classification"]) : "Unknown";
return `${partyName}\n\n${classification}\n\nSeats Won: ${seats}\n\n `;
}
}
),
Plot.ruleY([0])
]
});
return plotChart;
})();
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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