Klimawandel verstehen

Eine Website, die D3.js nutzt, um Klimawandeldaten visuell zu analysieren. Visualisierungen umfassen Linien- und Stacked-Area-Charts globaler Klimadaten sowie eine detaillierte Choropleth-Karte und weitere Darstellungen kanadischer Wetterdaten.


Klimawandel verstehen

Typ

D3.js Website

Jahr

2018

Angewandte Fähigkeiten

  • D3.js
  • Front-End

Team

  • Eigenes Projekt
<h2>Die Aufgabe</h2>
<p>Als Übung interaktiver Datenvisualisierung planten wir, Klimawandeldaten umfassend zu visualisieren. Unser Ziel war, komplexe Datensätze in einfache Diagramme zu verdichten, die Mechanismen, Ursprünge und lokale Auswirkungen des Klimawandels in Kanada vermitteln. Um Nutzer anzusprechen, entwickelten wir einfache Interaktionen wie Pop-up-Tooltips sowie komplexere wie Brushing, Darstellungswechsel und Animation.</p>
Liniendiagramm globaler CO₂-Emissionen
Liniendiagramm der atmosphärischen CO₂-Konzentration
Stacked-Area-Chart der CO₂-Emissionen nach Region

Das Ergebnis

Klimawandel verstehen

Vier farbcodierte Liniendiagramme globaler CO₂-Emissionen und atmosphärischer Konzentration sowie ein Stacked-Area-Chart der CO₂-Emissionen nach Region.

<h3>Auswirkungen des Klimawandels verstehen</h3>
<p>Mit der Choropleth-Karte Kanadas und seiner Provinzen und Territorien können Nutzer kanadische Wetterdaten – einschließlich Temperatur und Niederschlag – nach Jahr, Monat und Provinz erkunden. Zusätzlich gibt es ein Spider-Chart der globalen Temperaturanomalie über die Zeit. Beide Diagramme sind dynamisch abfragbar und animierbar.</p>

<h3>Zusammenfassung der Klimawandelauswirkungen</h3>
<p>Die Summary-Charts zeigen einen Zusammenhang – oder dessen Fehlen – zwischen CO₂-Emissionen und Wetteranomalien. Vier Liniendiagramme der mittleren kanadischen Wettertemperatur, des Niederschlags und deren Anomalien sind mit einem Liniendiagramm globaler CO₂-Emissionen gruppiert.</p>
Interaktive Choropleth-Karte kanadischer Wetterdaten
Spider-Chart der globalen Temperaturanomalie

Prozess

Wir entwickelten das Projekt zu zweit über zwei Monate hinweg – unsere erste Erfahrung mit D3.js. Früh definierten wir zwei zentrale Fragen, die das Projekt beantworten sollte:

  1. Was sind die Beitragsfaktoren zum Klimawandel?
  2. Da der Klimawandel das Wetter beeinflusst: Gibt es Anzeichen dafür, dass sich das kanadische Wetter abnormal verhält?

Nach der Fragestellung suchten wir relevante Daten. Die meisten mussten von Ausreißern und fehlerhaften Werten bereinigt werden. Am komplexesten war der kanadische Wetterdatensatz: Mehrere große Datensätze mussten manuell zusammengeführt, bereinigt, sortiert und monatliche sowie jährliche Durchschnitte berechnet werden.

In der finalen Phase entwickelten wir die D3.js-gesteuerten Visualisierungen und bauten die Website, die zugleich als Projektbericht dient. Die meisten Diagramme – einschließlich Linien- und Stacked-Area-Charts – waren relativ unkompliziert. Mit Abstand am komplexesten war die Choropleth-Karte kanadischer Wetterdaten. Die visuelle Zuordnung von Daten zu Geografie und Farbe war anspruchsvoll, das Ergebnis lohnte sich: Die Karte bietet eine ansprechende, interaktive Möglichkeit, einen großen Wetterdatensatz schnell zu durchsuchen und lokale sowie bundesweite Beobachtungen zu machen.

Korrelationsdiagramm von CO₂-Emissionen und Wetteranomalien in Kanada

Der Code

Das Projekt ist in HTML, CSS und JS entwickelt; für die Visualisierungen nutzen wir die datengetriebene Bibliothek D3.js. Die Umsetzung aller Visualisierungen war anspruchsvoll, da D3 für uns neu war – besonders die Ketten-Syntax war anfangs umständlich. Der allgemeine Workflow lädt Daten, wählt DOM-Elemente aus und fügt SVG-Elemente mit bestimmten, an die Daten gebundenen Attributen ein. Im Auszug unten wird das kanadische Wetterdaten-Diagramm in drawMap() gerendert; die Farbe jeder Provinz wird Temperatur- oder Niederschlagsdaten je nach Nutzereingabe zugeordnet. Der Auszug enthält ab Zeile 58 auch Hover-Interaktionen für einzelne Provinzen: Die Provinz wird hervorgehoben und die Legende über updateDataData() aktualisiert (im Beispiel nicht gezeigt).

CanadaMap.js
// CODE SNIPPET, NOT THE FULL FILE /////////////////////////////////////////////////////////////////////////////////////// DRAW MAP (called on load and on interactions)var gTopo;function ready(error, topo) {  gTopo = topo;  updateDate();  drawMap();}////////////////////////// drawMap() - draws map comprised of individual provinces, styled according to current interaction statefunction drawMap() {  //clear old map  if (d3.selectAll(".oldChart")) {        d3.selectAll(".oldChart").remove();    }  //--------------------------------------------- Draw the map  svg.append("g")    .attr("class", "oldChart")    .selectAll("path")    .data(gTopo.features)    .enter()    .append("path")      //----------------------------------------- Draw each province      .attr("d", d3.geoPath()        .projection(projection)      )      // Set the color of each province      .attr("fill", function (d, i) {        var output;        if (usingMonth){          switch(curColorCode){              case colorCoding.T: output = colorScaleT(-getValueByMonth(dataNest, convertName(d.properties.NAME), curYear, curMonth, "tMean")); break;              case colorCoding.TD: output = colorScaleTD(-getValueByMonth(dataNest, convertName(d.properties.NAME), curYear, curMonth, "tDiff")); break;              case colorCoding.P: output = colorScaleP(getValueByMonth(dataNest, convertName(d.properties.NAME), curYear, curMonth, "pMean")); break;              case colorCoding.PD: output = colorScalePD(getValueByMonth(dataNest, convertName(d.properties.NAME), curYear, curMonth, "pDiff")); break;          }        } else {          switch(curColorCode){              case colorCoding.T: output = colorScaleT(-getValueByYear(dataNest, convertName(d.properties.NAME), curYear, "tMean")); break;              case colorCoding.TD: output = colorScaleTD(-getValueByYear(dataNest, convertName(d.properties.NAME), curYear, "tDiff")); break;              case colorCoding.P: output = colorScaleP(getValueByYear(dataNest, convertName(d.properties.NAME), curYear, "pMean")); break;              case colorCoding.PD: output = colorScalePD(getValueByYear(dataNest, convertName(d.properties.NAME), curYear, "pDiff")); break;          }        }        return output;      })      .style("stroke", "transparent")      .attr("class", function(d){ return "Country" } )      .style("opacity", 1)      // Listen for mouse interactions      .on("mouseover", mouseOver )      .on("mouseleave", mouseLeave );}///////////////////////////////////////////////////////////////////////////////////////////////////// Hoverlet mouseOver = function(d) {  // Interact with individual provinces only if toggled to Provincial data  if (!showingCanada){    // To highlight the province, set all others to .5 opacity    d3.selectAll(".Country")    .transition()    .duration(200)    .style("opacity", .5)    d3.select(this)      .transition()      .duration(200)      .style("opacity", 1)    // Update province label in the legend, call updateDateData() to update t and p values in the legend    curProvince = d.properties.NAME;    lblProvince.text(d.properties.NAME);    updateDateData(false);  } else {    // If toggled to Canadian data, highlight Provincial data button while hovering    document.getElementById("canadaMapShowProvincial").classList.add("highlightPbtn");  }}let mouseLeave = function(d) {  d3.selectAll(".Country")    .transition()    .duration(200)    .style("opacity", 1)  d3.select(this)    .transition()    .duration(200)    .style("stroke", "transparent")  if (showingCanada) document.getElementById("canadaMapShowProvincial").classList.remove("highlightPbtn");}

View gist on GitHub

Diese Portfolio-Website wurde entwickelt mit Astro. Urheberrecht © 2026 Robert Michels. Alle Rechte vorbehalten.
Lebenslauf Datenschutz