I'm building a Gantt milestone chart that shows certain milestones from multiple projects, and each of the projects can be considered part of a "group".
When the chart initially loads, I show all the projects, and I set a custom zoom level of Jan 1 of "this year" to Jan 1 five years in the future by calling chart.xAxis[0].setExtremes()
.
There is a control to allow filtering by project group. Every time a new filtering selection is made, the chart reloads, and I reset the zoom to that same range.
However, with some of the data, the setExtremes
is not respected, and Highcharts decides on it's own what range to show, and I can't figure out why. Especially because if I show data from one group (eg "Group 4"), the zoom is respected, but then if I add in another group (eg show "Group 4" and "Group 2"), the the zoom is not respected.
BUT - if I try the same thing with a different set of data (eg show "Group 5", then add in "Group 2"), then the zoom is maintained correctly after adding in what seems to be the "suspect" data.
Very confusing.
I set up a code sandbox with fake project and group names, but with the actual date data.
Also might be easier to see if you load the sandbox outside of the editor: https://g26rq.csb.app/
What is it about the data that's causing this behavior?
Update to address the comment:
All data required is fetched from the server on initial component mount and is stored in state in a way that I can just pull from that when the filter settings change so I don't have to keep going back to the server.
That being said, the order of operations are set up like this:
- Any "change" event on the group filter select control sets the overall component state in such a way that the Highcharts chart component should be unmounted/destroyed. (Basically the bit of state where I store the series data is cleared/emptied.)
- After all selections have been finalized, the "blur" event on the select control starts the process of data transformation/application.
- Data that corresponds to the filter settings is pulled from where the overall data is stored in state, transformed into the necessary Highcharts series format, and then the series data is set into state.
- After the component re-renders with the series data present in state, the Highcharts component is allowed to render, and I specify a callback function in the Highcharts component props which corresponds to a
chart.events.load
event handler. Since the previous chart was destroyed and is now essentially being created anew, theload
event will occur. - The callback/load event handler is what calls
setExtremes
.
I see that the console.log
added to the render
event occurs after the console.log
I put in the function where I call setExtremes
, but that is to be expected. According to the Higcharts documentation on the load
and render
events:
load: Highcharts.ChartLoadCallbackFunction
Fires when the chart is finished loading.
...
There is also a second parameter to the chart constructor where a callback function can be passed to be executed on chart.load.
(I'm guessing that the Highcharts React component is using that to pass in the callback function I am specifying in the component's callback
prop.)
render: Highcharts.ChartRenderCallbackFunction
Fires after initial load of the chart (directly after the
load
event), and after each redraw (directly after theredraw
event).
So it's no surprise that the render
happens after I setExtremes
, but that doesn't necessarily mean that I'm calling setExtremes
before the chart is ready. Considering that I'm destroying/re-creating the chart every time the filter settings change, and that render
might be fired by any manual zoom change by users (not to mention probably fires after my own forced setExtremes
), it would seem to me that doing my setExtremes
from the load
event is exactly where it should happen.