leeoniya / uPlot

📈 A small, fast chart for time series, lines, areas, ohlc & bars
MIT License
8.51k stars 371 forks source link

Wrapping muplot with OffScreenCanvas #848

Closed ddublon closed 11 months ago

ddublon commented 11 months ago

hi there

think muplot does all its updates on the main thread of the UI I was looking for technologies that might solve this problem and came across the offscreen canvas https://devnook.github.io/OffscreenCanvasDemo/keep-ui-responsive.html

how can I implement such a thing into wrapping it in muplot? let me know what do you think

leeoniya commented 11 months ago

this was discussed previously in https://github.com/leeoniya/uPlot/issues/733

do you have a runnable example where the current main thread strategy is causing issues for you?

ddublon commented 11 months ago

yes I have

https://neuro-omega-react-nyqkz3q6q-alpha-omega-github.vercel.app/graphpage

image

number 1 generated graphs using muplot number 2 generate graphs using recharts and other tools

ddublon commented 11 months ago

i think this link is better demonstrate because it has more graphs

https://neuro-omega-react-nyqkz3q6q-alpha-omega-github.vercel.app/graphpage

leeoniya commented 11 months ago

that's quite a lot of data :)

i guess i'm not understanding exactly what the animation is supposed to show in terms of usefulness?

what's the significance of the gap width or the rate of the gap movement?

ddublon commented 11 months ago

sorry for my late response I was trying to compress the files into a small example to show you without luck...

the gap/graph needs to show something similar to a heart beat monitor at a surgery room, we are rebuilding the monitors in ReactJS and want to know if that is possible to do in JavaScript

ddublon commented 11 months ago

so the gap needs to visualize to the doctor what is the most newest data

ddublon commented 11 months ago

the rates are: 44khz of samples taken, so like for each seconds 44k points are generated, and the graph need to show data of length of 5 seconds , so thats 220,000 points and because the sampling rate is 2,200 something like that the null gap moves in each loop this number to the right to illustrate the diffrence between the old data and the new data

leeoniya commented 11 months ago

it sounds like this is just a visual indicator of liveness, then? something like a blinker/spinner? (the data isn't changing)

dolev146 commented 11 months ago

The data of the y axis change, the x axis doesn't

dolev146 commented 11 months ago

Have you ever came across such senario or know someone who did?

leeoniya commented 11 months ago

The data of the y axis change, the x axis doesn't

i don't see it changing in the provided links, are they just a prototype and the real thing will actually load new data over websocket where the gap is currently drawn?

Have you ever came across such senario or know someone who did?

i'm still trying to figure out exactly what the intent is here :sweat_smile:

i will say that redrawing millions of datapoints multiple times per second is not going to give you great results with uPlot. as mentioned in the intro [1], you may want to look into WebGL/WebGPU for oscilloscope/live-signal type applications.

[1] https://github.com/leeoniya/uPlot#introduction

leeoniya commented 11 months ago

if you want to use uPlot, my recommendation is to down-sample the raw data on the server before sending it to the client. you graphs are only a couple hundred px wide, so you have 1000x more resolution than you actually need in the browser.

if you send 500 downsampled datapoints to each chart instead of 250k, you'll have a lot more runway, performance-wise.

image

dolev146 commented 11 months ago

i don't see it changing in the provided links, are they just a prototype and the real thing will actually load new data over websocket where the gap is currently drawn?

exactly!

if you want to use uPlot, my recommendation is to down-sample the raw data on the server before sending it to the client. you graphs are only a couple hundred px wide, so you have 1000x more resolution than you actually need in the browser.

can you say it more simple please?

this is very good for line chart-type data: https://github.com/pingec/downsample-lttb

this looks amazing! i was thinking about doing it but didn't have the time to think about a mechanism, they used muplot in the readme?


I dont really mind what to use, its just that muplot had a reactjs wrapper and it was for me the easiest to start with, maybe in the end i will end up buying a license from the tools you specified in the readme because the libraries that are free are not in active development I think webplot-gl is really good https://danchitnis.github.io/webgl-plot-examples/vanilla/index.html but they also say they stopped the development and they are working on something else but i cant find it

image

and I also dont know how to add it into a reactjs project

Thank you a lot for all the tips!

dolev146 commented 11 months ago

if you have the options that i have: please confirm that what i do is good

1.first i will try the downsampling library ,

  1. second if not work will try webplot-gl because its free
  2. if noting worked will look over to paid solutions

or you would do things diffrently?

is that a good idea or should i go to the paid solutions first? because in your comparison on time it took to draw you clearly say that muplot is really fast in comparison to lightingCharts doesnt it what the comparison said? in the readme?

leeoniya commented 11 months ago

for your size charts (200px), i would downsample on the server using LTTB to maybe 400-800 points per chart, this will give the best improvement for the least amount of effort. reducing the browser load by sending 500x less data is always going to be the most effective optimization strategy. you should be able to continue using uPlot without any performance issues after this.