Public
Edited
May 13
Paused
2 forks
Importers
Insert cell
Insert cell
numbers = Array.from({ length: 800 }, (_, i) => i)
Insert cell
Insert cell
klimawidget = html`

${klimawidget_title}
<div class="box">

<div class="box_one" style="display: ${first_box_one}">
${emission_reduced}
</div>

<div class="box_one" style="display: ${first_box_two}">
${forest_reduced}
</div>

<div class="box_two" style="display: ${second_box_two}">
${ice_reduced}
</div>

<div class="box_two" style="display: ${second_box_one}">
${anomaly_reduced}
</div>

</div>

`
Insert cell
klima_button = html`
<div style="height:40px;padding-top: 20px;"><a href="https://www.rnd.de/klima/" target="_blank" style="text-decoration: none;"><span class="klima">mehr zur Klimakrise</span></a></div>
`
Insert cell
first_box_one = {
if (((timer >= 0) & (timer < 200)) | ((timer >= 400) & (timer < 600))) {
return "inline";
} else {
return "none";
}
}
Insert cell
first_box_two = {
if (((timer >= 200) & (timer < 400)) | ((timer >= 600) & (timer <= 800))) {
return "inline";
} else {
return "none";
}
}
Insert cell
second_box_one = {
if (
((timer >= 700) & (timer < 800)) |
((timer >= 0) & (timer < 100)) |
((timer >= 300) & (timer < 500))
) {
return "inline";
} else {
return "none";
}
}
Insert cell
second_box_two = {
if (((timer >= 100) & (timer < 300)) | ((timer >= 500) & (timer < 700))) {
return "inline";
} else {
return "none";
}
}
Insert cell
Insert cell
height = 180
Insert cell
emission_opacity = isDarkMode() ? 0.8 : 0.2
Insert cell
emission_color = isDarkMode() ? "#eff3f5" : "#293845"
Insert cell
grey_color = isDarkMode() ? "#435b70" : "#eff3f5"
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// https://nsidc.org/data/seaice_index/data-and-image-archive
url = "https://docs.google.com/spreadsheets/d/1Jss8jkdNOIQ4JptDUoV4z3pUVlLaENIa9CD2Yiqv8wg/edit?gid=1253017609#gid=1253017609"
Insert cell
rawdata_ice = d3.csv(getCsvUrl(url), d3.autoType)
Insert cell
data_ice = rawdata_ice
.map((d) => ({
year: +d.Year,
month: +d.Month,
day: +d.Day,
extent: +d.Extent,
date: roundUTCDay(new Date(d.Year + "-" + d.Month + "-" + d.Day)),
date_repeat: roundUTCDay(new Date("2023" + "-" + d.Month + "-" + d.Day)),
day_of_year:
Math.floor(
(roundUTCDay(new Date(d.Year + "-" + d.Month + "-" + d.Day)) -
new Date(
roundUTCDay(
new Date(d.Year + "-" + d.Month + "-" + d.Day)
).getFullYear(),
0,
0
)) /
86400000
) - 1
}))
.filter((d) => (d.year != "YYYY") & (d.year >= start) & (d.day <= 364))
Insert cell
Insert cell
Insert cell
data_ice
SELECT year, date, extent FROM data_ice
WHERE month == ${max_month_ice}
AND day == ${max_day_ice}
ORDER BY year desc
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
carbon_2023 = [{ year: 2023, total: 40.9 }]
Insert cell
Insert cell
Insert cell
Insert cell
anomaly_reduced = Plot.plot({
width: chart_width,
height: height,
marginTop: 70,
marginLeft: 0,
marginRight: 0,
marginBottom: 40,

y: {
axis: null
},

x: {
axis: null
},

marks: [
// Balken
Plot.barY(global_monthly_filtered, {
y: "Anomalie",
x: "Jahr",
strokeWidth: 0,
fill: (d) =>
(d.Jahr == 2025) | (d.Jahr == start) ? "#e84f1c" : grey_color,
fillOpacity: (d) => (d.Jahr == start ? 0.2 : 1)
}),

// Monat
Plot.text(anomaly_text, {
x: (d) => d.year,
y: "max_anomaly",
text: (d) => d.month + " " + d.year,
textAnchor: "end",
fill: "#e84f1c",
fontSize: 12,
fontFamily: "InterRegular",
dy: -60,
dx: 0
}),

// große Zahl
Plot.text(anomaly_text, {
x: "year",
y: "max_anomaly",
text: (d) =>
"+" +
d.text.toLocaleString("de", {
minimumFractionDigits: "2",
maximumFractionDigits: "2"
}) +
"°C",
textAnchor: "end",
fill: "#e84f1c",
fontSize: 22,
fontWeight: 600,
fontFamily: "DIN Next LT Pro",
dy: -40,
dx: 0
}),

// Definition
Plot.text(anomaly_text, {
x: "year",
y: "max_anomaly",
text: (d) => `globale Durchschnittstemperatur\nAbweichung von 1991-2000`,
textAnchor: "end",
fontFamily: "InterRegular",
dy: -15,
dx: 0
}),

// kleine Zahl
Plot.text(anomaly_text_2, {
x: "year",
y: "min_anomaly",
text: (d) =>
d.text.toLocaleString("de", {
minimumFractionDigits: "1",
maximumFractionDigits: "1"
}) +
"°C im " +
d.month +
" " +
d.year,
textAnchor: "start",
fill: "#e84f1c",
fillOpacity: 0.8,
fontSize: 12,
fontWeight: 600,
fontFamily: "InterRegular",
dy: 10,
dx: 0
}),

// Quelle
Plot.text(anomaly_text, {
x: "year",
y: "min_anomaly",
text: (d) => `Quelle: Copernicus Climate Change Service`,
textAnchor: "end",
fill: "#99AFC2",
fontFamily: "InterRegular",
dy: 30,
dx: 0
})
]
})
Insert cell
anomaly_text = [
{
year: 2025,
max_anomaly: 0.67,
min_anomaly: -0.15,
text: 0.6,
month: "April"
}
]
Insert cell
anomaly_text_2 = [
{
year: 2001,
max_anomaly: 0.67,
min_anomaly: -0.15,
text: -0.15,
month: "April"
}
]
Insert cell
global_monthly_filtered_data = FileAttachment(
"klimawidget_anomaly_april_2025.csv"
).csv()
Insert cell
global_monthly_filtered = global_monthly_filtered_data.map((d) => ({
Jahr: +d.Jahr,
Anomalie: +d.Anomalie
}))
Insert cell
Insert cell
forest_reduced = Plot.plot({
width: chart_width,
height: height,
marginTop: 70,
marginLeft: 10,
marginRight: 10,
marginBottom: 40,

x: {
axis: null
},

y: {
axis: null
},

marks: [
// Fläche
Plot.areaY(forest_loss_data, {
x: "year",
y: "loss",
curve: "monotone-x",
fill: grey_color
}),

// Linie
Plot.lineY(forest_loss_data, {
x: "year",
y: "loss",
curve: "monotone-x",
stroke: "#6bb024"
}),

// Punkte
Plot.dot(forest_loss_data, {
x: "year",
y: "loss",
stroke: "#6bb024",
strokeOpacity: (d) => ((d.year == 2023) | (d.year == 2001) ? 1 : 0),
fillOpacity: (d) => ((d.year == 2023) | (d.year == 2001) ? 1 : 0),
fill: "#ffffff"
}),

// Jahr
Plot.text(forest_text, {
x: (d) => d.year,
y: "max_forest",
text: (d) => d.year.toString(),
textAnchor: "end",
fill: "#6bb024",
fontSize: 12,
fontFamily: "InterRegular",
dy: -60,
dx: 0
}),

// große Zahl
Plot.text(forest_text, {
x: "year",
y: "max_forest",
text: (d) =>
d.text.toLocaleString("de", {
minimumFractionDigits: "0",
maximumFractionDigits: "0"
}) + " km²",
textAnchor: "end",
fill: "#6bb024",
fontSize: 22,
fontWeight: 600,
fontFamily: "DIN Next LT Pro",
dy: -40,
dx: 0
}),

// Definition
Plot.text(forest_text, {
x: "year",
y: "max_forest",
text: (d) => `Waldverluste weltweit\n(ohne Waldgewinne)`,
textAnchor: "end",
fontFamily: "InterRegular",
dy: -15,
dx: 0
}),

// kleine Zahl
Plot.text(forest_text_2, {
x: "year",
y: 0,
text: (d) =>
d.text.toLocaleString("de", {
minimumFractionDigits: "0",
maximumFractionDigits: "0"
}) +
" km² im Jahr " +
d.year,
textAnchor: "start",
fill: "#6bb024",
fillOpacity: 0.8,
fontSize: 12,
fontWeight: 600,
fontFamily: "InterRegular",
dy: 10,
dx: 0
}),

// Quelle
Plot.text(forest_text, {
x: "year",
y: "min_forest",
text: (d) => `Quelle: Global Forest Watch`,
textAnchor: "end",
fontFamily: "InterRegular",
fill: "#99AFC2",
dy: 30,
dx: 0
})
]
})
Insert cell
forest_loss_data = FileAttachment("wald_global_time_2023@2.csv")
.csv()
.then(function (data) {
data.forEach(function (d) {
d.loss = +d.loss;
d.year = +d.year;
});
return data;
})
Insert cell
forest_text = [
{
year: year_forest_last,
max_forest: max_forest,
min_forest: 0,
text: recent_forest
}
]
Insert cell
year_forest_last = d3.max(forest_loss_data.map((d) => d.year))
Insert cell
recent_forest = +forest_loss_data[0].loss
Insert cell
max_forest = d3.max(forest_loss_data.map((d) => d.loss))
Insert cell
min_forest = forest_loss_data[forest_loss_data.length - 1].loss
Insert cell
forest_text_2 = [
{
year: year_forest_first,
max_forest: max_forest,
min_forest: min_forest,
text: first_forest
}
]
Insert cell
year_forest_first = d3.min(forest_loss_data.map((d) => d.year))
Insert cell
first_forest = +forest_loss_data[forest_loss_data.length - 1].loss
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

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