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.
We'll cover the following
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.