Handling clicks on our forecast graph

We'll learn how to handle clicks on a Plotly.js graph and how to update our weather app in React.js to show the temperature of the day/time where the user has clicked.

Let’s add one more feature to our weather application. When clicking on a specific point of our graph, we want to show the user in text the temperature at that date!

Setting up the click handler

The first thing we need to do is add an event listener to our graph. Thankfully, Plotly gives us a handy plotly_click event to listen to, like so:

// Called when a plot inside the DOM element with the id "someID" is clicked
document.getElementById('someID').on('plotly_click', function(data) {
  /* …do something here with the data… */
});

The nice thing about plotly_click is that it doesn’t pass you the event, it passes you a very useful data object. We care about two particular properties of that data object:

{
  "points": [{
    "x": "2016-07-29 03",
    "y": 17.4,
    /* …more data here… */
  }]
}

These tell us which date was clicked on and what the relevant temperature was, exactly what we want! We’ll pass a function down to the Plot component called onPlotClick that will get called when the plotly_click event is fired, i.e. when a point on our forecast is clicked on.

Let’s start off by binding that event listener in our Plot component. In our drawPlot method bind the plotly_click event to this.props.onPlotClick!

// Plot.js

class Plot extends React.Component {
  drawPlot = () => {
    Plotly.newPlot( /* … */ );
    document.getElementById('plot').on('plotly_click', this.props.onPlotClick);
  };

  componentDidMount() { /* … */ }
  componentDidUpdate() { /* … */ }
  render() { /* … */ }
}

Perfect, but running this will not work since we don’t pass an onPropClick prop to Plot. Let’s jump to our App component and change that. First, we pass an onPlotClick prop to our Plot component calling our App component’s (currently missing) this.onPropClick method:

// App.js

class App extends React.Component {
  state = { /* … */ };
  fetchData = (evt) => { /* … */ };
  changeLocation = (evt) => { /* … */ };

  render() {
    /* … */
    return (
      { /* … */ }
      <Plot
        xData={this.state.dates}
        yData={this.state.temps}
        onPlotClick={this.onPlotClick}
        type="scatter"
      />
      { /* … */ }
    );
  }
}

Then we add a first version of the onPlotClick method to our App component where we only log out the passed data:

Get hands-on with 1400+ tech skills courses.