Plotly.js with millions of datapoints - repeated API calls to get finer resolution data

I am part of a small team that is looking to use plotly.js as part of an online circuit simulation effort. Our simulation engine runs on a server and can generate waveforms with millions of data points. We have an API to access the simulation data when the simulation completes, but I don’t think it will be practical to request all of the data points if the requested waveform has millions of data points - it will take too long to transfer all of the data from the server to the local client and it may consume too much memory on the client side. Because of this, we have an option to our API to only get as many data points as are needed to accurately display the waveform for the specified x range that will be used.

For example, assume the simulation runs from 0 to 1s and generates 1 million data points. If we want to display the entire x range from 0 to 1s, we don’t need all 1 million data points on the client since the pixel resolution of the graph cannot display that many points. Instead, we can return a subset of the points that is sufficient to accurately display the waveform for that x range. So far, that is easy to do.

The question I have is whether plotly.js has a way to make a follow-up API call to get more data if I zoom in to a smaller area of the x axis? Using the example above, assume I zoom in to an area that is only 10us wide. In this case, the data points that I used to draw the entire waveform from 0 to 1s will not likely include enough resolution to display this 10us window so I need to go back to the server to get the data points for this 10us window.

Has anyone handled a situation like this before? Does anyone have any thoughts on the best way to deal with this?

Thanks,
David

plotly.js exposes all d3 (version 3) api method through Plotly.d3. So, you could call Plotly.d3.json or Plotly.d3.csv to grab your data.

I’d try listening to the plotly_relayout event. Something like:

var gd = document.getElementById('graph')

Plotly.newPlot(gd, /* initial data */, /* initial layout */)

gd.on('plotly_relayout', evt => {
  // check the relayout call was initiated from a zoom event
  if (evt['xaxis.range[0]'] || evt['xaxis.range[1]']) {
    Plotly.d3.json(/* url to database */, d => {
       Plotly.restyle(gd, {
         x: [/* new x data */],
         y: [/* new y data */]
       })
    })
  }
})

Thanks for the thorough answer, Etienne. I will give this a try.

David

1 Like