zakodium-oss / react-plot

Library of React components to render SVG 2D plots. You can check the story book https://react-plot.pages.dev/ or have a look to the extensive documentation
https://react-plot.zakodium.com
MIT License
12 stars 6 forks source link

react-plot and series containing 500000 points #316

Open lpatiny opened 2 years ago

lpatiny commented 2 years ago

React plot zoom slows down when there are too many points.

At least in http://react-plot.zakodium.com/experimental/nmr (spectrum in the bottom).

Here is an example of file:

nmr13c.json.zip

This file contains 520000 points. It is in the form {x:[], y:[]} and can be converted to {x,y}[] using https://github.com/mljs/spectra-processing/blob/master/src/xy/xyToXYObject.ts

I would propose to use the following code in order to reduce the number of points if required. This has shown very good results in NMRium:

https://github.com/aiday-mar/spectra-processing/blob/0572f5c047ab23ac233a482ff00127c09c811a09/src/xy/xyReduce.ts#L9-L18

This function requires {x:[], y:[]} and you can always convert it using:

https://github.com/mljs/spectra-processing/blob/master/src/xyObject/xyObjectToXY.ts

Because the original data may contain extra information (other properties than x and y) this reduced version should only be used for SVG and not for tracking for example.

@stropitek Seems to me that visually there is no difference with this reduced version of the data and I think this could be the default behaviour before trying to generate the SVG we should try to reduce the number of points based on the current display width and the current from / to zoom factor (use a Memo for this and a local state ???).

lpatiny commented 2 years ago

@stropitek just edit this issue so that it makes more sense at the implementation point of view if we are going in this direction.

stropitek commented 2 years ago

It seems like the method to reduce the points is preserving the original points which is good. @lpatiny can you confirm it's the case?

However we cannot use this method as is because it returns the points and not the indices of the points that were preserved. Therefore any additional data linked to a point (for example error bar), or other data we potentially want to show to the user is lost.

lpatiny commented 2 years ago

This reduction of number of points should only be applied if xIsMonotone https://github.com/mljs/spectra-processing/blob/master/src/x/xIsMonotone.ts

lpatiny commented 2 years ago

We would rather add a new property that could reduce the number of points if the user wants.

onBeforePlot( points, from, to ) => points

targos commented 2 years ago

Maybe we should reconsider this for later, after we implement the multi-svg layer optimizations?

lpatiny commented 2 years ago

LineSeries could accept a callback as data but in this case it would requires boundary.

<LineSeries data=( {x: {min,max}, y:{min,max}}, width, height ) => [{x,y,errorX,...}] boundary={ {x: {min,max}, y:{min,max}} }>