Creating forecast graph in weather app

We'll use our knowledge of React.js and Plotly.js to create a plot component that will show the weather forecast.

Now that we’ve our Plot component ready, we just need to pass in the weather data and we are done.

The problem is that we need the data for the x-axis and the y-axis to be separate, but the data we get from the OpenWeatherMap API doesn’t make that distinction. This means we need to shape our data a little bit to suit our needs. What we want is human readable dates on the x-axis, and the degrees at that time on the y-axis!

We’ll shape the data into a form we can use it in and save both the raw and the formed data in our component state. Remember, this is what the raw data looks like:

"city": {
  "id": 2761369,
  "name": "Vienna",
  "coord": {
    "lon": 16.37208,
    "lat": 48.208488
  },
  "country": "AT",
  "population": 0,
  "sys": {
    "population": 0
  }
},
"cod": "200",
"message": 0.0046,
"cnt": 40,
"list": [ /* Hundreds of objects here */ ]

With the list array containing objects of this form:

{
  "dt_txt": "2016-04-09 18:00:00",
  "main": {
    "temp": 6.94,
    "temp_min": 6.4,
    "temp_max": 6.94
  },
  "weather": [
    {
      "main": "Rain",
      /* …more data here */
    }
  ],
  /* …more data here */
}

What we really care about is data.list[element].dt_txt, a human-readable timestamp, and data.list[element].main.temp, the temperature at that time.

We’ll loop through all the weather information we have, making two arrays and fill one with the timestamps, and another array with the temperatures. (We’ll use the push method of arrays, which adds an element to the end of an array).

We’ll do that in the fetchData method, so we only recalculate the data when new one comes in and not on every render. (which would possibly mean shaping the data every second or more!) This is what happens when the data comes back in at the moment

Our xhr call to OpenWeatherMap will now look like this:

xhr({
      url: url
    }, () => (err, data) {
      var body = JSON.parse(data.body);
      var list = body.list;
      var dates = [];
      var temps = [];
      for (var i = 0; i < list.length; i++) {
        dates.push(list[i].dt_txt);
        temps.push(list[i].main.temp);
      }

      this.setState({
        data: body
      });
    });

We also need to add those new properties to our initial state:

class App extends React.Component {
  state = {
    location: '',
    data: {},
    dates: [],
    temps: []
  };

  fetchData = (evt) => { /* … */ };

  changeLocation = (evt) => { /* … */ };

  render() { /* … */ }
}

Now that we have that data saved in our component state, we can render our plot by passing this.state.dates as the x-axis data, this.state.temps as the y-axis data and we’ll also pass it a type prop of "scatter"!

Here’s the working example (reminder: you will need to update your OpenWeatherMap API key to make it work):

Get hands-on with 1400+ tech skills courses.