Public
Edited
Apr 28
Insert cell
Insert cell
Insert cell
parteien_chart = Plot.plot({
height: 700,
width,
marginRight: 50,
marginLeft: 60,
marginBottom: 20,

y: {
axis: null
},

x: {
label: null,
grid: true,
axis: "top",
ticks: [0, 10, 20, 30]
},

facet: {
data: parteien,
y: "Partei",
label: null
},

fy: {
padding: 0.1,
axis: null,
domain: [
"CSU",
"SPD",
"Freie Wähler",
"CDU",
"FDP",
"Grüne",
"BSW",
"Linke"
]
},

marks: [
// Label Parteien
Plot.text(new Set(parteien.map((d) => d.Partei)), {
fy: (d) => d,
x: 0,
dx: -10,
textAnchor: "end",
text: (d) => d.replace("Freie Wähler", "FW")
}),

// Punkte
Plot.dot(
parteien,
Plot.dodgeY({
fy: "Partei",
x: "Erfahrung",
fill: (d) => hochburgen.get(d.Partei),
fillOpacity: 0.4,
r: 4,
padding: 0.2,
tip: false,
anchor: "middle"
})
),

// Punkte Durchschnitt
Plot.dot(
parteien,
Plot.dodgeY(
Plot.groupY(
{ x: "mean" },
{
x: "Erfahrung",
y: (d) => d.Partei,
r: 14,
stroke: "#fff",
strokeWidth: 1.5,
anchor: "middle",
stroke: (d) => hochburgen.get(d.Partei),
sort: { y: "x" }
}
)
)
),

// Label Durchschnitt
Plot.text(
parteien,
Plot.dodgeY(
Plot.groupY(
{
x: "mean",
text: (d) =>
d3.mean(d).toLocaleString("de", {
minimumFractionDigits: 1,
maximumFractionDigits: 1
})
},
{
x: "Erfahrung",
y: (d) => d.Partei,
anchor: "middle",
fill: "#0f151a",
stroke: "#fff",
text: "Erfahrung",
sort: { y: "x" }
}
)
)
),

// hervorgehobener Text
Plot.text(
parteien,
Plot.dodgeY({
x: "Erfahrung",
fillOpacity: (d) =>
[
"Reiner Haseloff",
"Joachim Herrmann",
"Boris Pistorius",
"Stephan Weil",
"Winfried Kretschmann",
"Katja Wolf"
].includes(d.Name)
? 1
: 0,
strokeOpacity: (d) =>
[
"Reiner Haseloff",
"Joachim Herrmann",
"Boris Pistorius",
"Stephan Weil",
"Winfried Kretschmann",
"Katja Wolf"
].includes(d.Name)
? 1
: 0,
r: 4,
dy: -7,
padding: 0.2,
stroke: isDarkMode() ? "#657482" : "#ffffff",
fill: isDarkMode() ? "#ffffff" : "#657482",
lineAnchor: "bottom",
textAnchor: "middle",
text: (d) => `${d.Nachname}`,
anchor: "middle" ?? undefined
})
),

// hervorgehobene Kreise
Plot.dotX(
parteien,
Plot.dodgeY({
x: "Erfahrung",
fillOpacity: 0,
r: 4,
stroke: (d) => hochburgen.get(d.Partei),
strokeWidth: 0.75,
strokeOpacity: (d) =>
[
"Reiner Haseloff",
"Joachim Herrmann",
"Boris Pistorius",
"Stephan Weil",
"Winfried Kretschmann",
"Katja Wolf"
].includes(d.Name)
? 1
: 0,
padding: 0.2,
tip: false,
anchor: "middle" ?? undefined
})
),

// Tooltip
Plot.text(
parteien,
Plot.dodgeY(
Plot.pointer({
x: "Erfahrung",
r: 4,
padding: 0.2,
stroke: isDarkMode() ? "#657482" : "#ffffff",
fill: isDarkMode() ? "#ffffff" : "#657482",
lineAnchor: "top",
textAnchor: "middle",
dy: 7,
text: (d) =>
`${d.Vorname} ${d.Nachname}\n${d.Amt}\n${
d.Gebietskörperschaft
}\n${d.Erfahrung.toLocaleString("de", {
minimumFractionDigits: 1,
maximumFractionDigits: 1
})} Jahre`,
anchor: "middle" ?? undefined
})
)
),

// Hover
Plot.dotX(
parteien,
Plot.dodgeY(
Plot.pointer({
x: "Erfahrung",
fillOpacity: 0,
r: 4,
strokeWidth: 0.75,
padding: 0.2,
tip: false,
stroke: (d) => hochburgen.get(d.Partei),
anchor: "middle" ?? undefined
})
)
)
]
})
Insert cell
Insert cell
stand = new Date(today)
.getDate()
.toString()
.concat(".")
.concat((new Date(today).getMonth() + 1).toString())
.concat(".")
.concat(new Date(today).getFullYear().toString())
Insert cell
today = new Date(2025, 3, 29).toJSON().slice(0, 10).replace(/-/g, "-")
Insert cell
hochburgen = new Map([
["CDU", isDarkMode() ? "#99AFC2" : "#333"],
["CSU", isDarkMode() ? "#99AFC2" : "#333"],
["Union", isDarkMode() ? "#99AFC2" : "#333"],
["SPD", "#f44647"],
["Grüne", "#6abf4a"],
["FDP", "#ffd600"],
["Linke", "#c72767"],
["AfD", "#5fb1bf"],
["BSW", "#312783"],
["PARTEI", "#C63141"],
["Freie Wähler", "#E99939"],
["FW", "#E99939"],
["Piraten", "#FFC02F"]
])
Insert cell
parteien_data = read(
"https://docs.google.com/spreadsheets/d/1Pksx4Nj3FwkWiCBis0NdmMkGrZHlg7UTrYbYgkzNs6s/edit?gid=752732988#gid=752732988",
"regierung_bund_land"
)
Insert cell
parteien = parteien_data.map((d) => ({
...d,
Partei: d.Partei,
Erfahrung: +d.Erfahrung,
Erfahrung_bis_Amt: +d.Erfahrung_bis_Amt
}))
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