leeoniya / uPlot

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

Top performance, Great work #56

Closed rubyzhao closed 4 years ago

rubyzhao commented 4 years ago

This isn't a issue. I just want say thanks. Hope more people use it.

To select the best line chart package for my project, especially when points are about 2 millions. uPlot becomes No.1. Even it is fast than direct lineTo for Canvas. It is amazing. Thanks for the great work. Please see the detail at https://github.com/rubyzhao/LineChartPerformanceCompare

leeoniya commented 4 years ago

awesome, thanks for testing! might be useful to add these additional numbers to a wiki page here :)

let me know if any of uPot's API is counter-intuitive, i'd like to get as much of it polished before 1.0. still have to do a lot of docs! https://github.com/leeoniya/uPlot/issues/48

leeoniya commented 4 years ago

btw, you can get slightly better performance if you fixate the scale range. this way uPlot does not need to scan 2e6 points to determine the min/max of the data. this will also prevent y-rescale during zoom, but that may be less important to you than speed.

see this demo: https://leeoniya.github.io/uPlot/demos/axis-control.html

leeoniya commented 4 years ago

@rubyzhao please let me know if you find something faster. i would like to add it to the perf table here.

rubyzhao commented 4 years ago

Sure @leeoniya. I am testing some commercial products also. I don't want publish here to make trouble. I will communicate this after I finish by end of the month.

leeoniya commented 4 years ago

ok, thanks!

CrashLaker commented 4 years ago

Hi @leeoniya

May I ask you how do one measure performance? Viser https://viserjs.github.io/demo.html#/viser/line/multi-line could be a good candidate to your perf table. To me it's fast like uPlot and not laggy like others but it doesn't have panning capabilities.

leeoniya commented 4 years ago

interesting, i've never seen Viser.

test perf by running these implementations:

https://github.com/leeoniya/uPlot/tree/master/bench

if you'd like to submit a PR for a Viser bench, i will test it and add it to the table.

the Vue version of the lib [1] is 690KB, so it won't win any awards there :D

[1] https://unpkg.com/viser-vue@2.4.8/umd/viser-vue.min.js

leeoniya commented 4 years ago

Viser will probably score poorly in the interaction metric.

if you move your mouse around on the chart, it's quite laggy:

https://viserjs.github.io/demo.html#/viser/line/nintendo-game-sales-trend

recording a perf profile in chrome devtools does not look great.

leeoniya commented 4 years ago

looks like https://viserjs.github.io/demo.html#/viser/line/operational-analysis-of-an-app would be more apples-to-apples with how uPlot works. the other one might just be a crappy tooltip impl.

the vanilla Viser [1] weighs 650KB. simply loading it in Chrome takes ~140ms just to parse and compile it. uPlot parses & compiles in ~4ms.

Viser has a lot of options and much of it is a-la-carte, so it's not obvious to me how to quickly implement a faithful bench that at least has the ideal data structure and date handling for that lib. if you want to contribute something, then i'll certainly take a look.

more detail about how i actually perform the tests: https://github.com/leeoniya/uPlot/issues/1#issuecomment-541961855

[1] https://unpkg.com/viser@2.4.8/umd/viser.min.js

CrashLaker commented 4 years ago

hi @leeoniya

i don't know much about the fine tunning on sizes and rendering. All I know was that it performed a a lot better than other canvas implementations i've tried (e.g. chartjs) and was prettier than some custom made d3js hacks.

image

image

i could try and run the same uplot dataset with > 150,000 points on and see how it goes.

leeoniya commented 4 years ago

i could try and run the same uplot dataset with > 150,000 points on and see how it goes.

yeah, for sure.

if you want to make a codesandbox using https://unpkg.com/viser@2.4.8/umd/viser.min.js and https://leeoniya.github.io/uPlot/bench/data.json, that would be a great starting point.

CrashLaker commented 4 years ago

if you want to make a codesandbox using https://unpkg.com/viser@2.4.8/umd/viser.min.js and https://leeoniya.github.io/uPlot/bench/data.json, that would be a great starting point.

will try to do it later

as for now i can only run with the same dataset and tell the performance results from an user experience pov plotting that same dataset (4 sources) went super smooth. image

but adding that other other dataset was enough to lag when hovering it. also... it displayed that same spanGaps: false behaviour.. wonder if there's a spanGaps: true in viser 😂 image

well done @leeoniya awesome work! :)

leeoniya commented 4 years ago

plotting that same dataset (4 sources) went super smooth.

except uPlot was not drawing values below 0 🤣

btw, if you like the cleaner look, uPlot provides a lot of control over the x/y grid style and tick granularity/spacing.

CrashLaker commented 4 years ago

btw, if you like the cleaner look, uPlot provides a lot of control over the x/y grid style and tick granularity/spacing.

thank you. i'll cross that bridge eventually : )

Another suggestion. What about Grafana's plotting system? I've no idea what's behind it though. At first I guess it wouldn't be a fair comparison because I think grafana compresses the data on the fly due to the "MaxDataPoints" variable. Also zooming in triggers a call to fetch "new" data to the backend.

Uplot's 65 line plot. arr[65] = [[959628] each, ....] image

Grafana 500 line plot. (didn't record its size) image

leeoniya commented 4 years ago

i think they use Flot (which is in the bench table).

https://github.com/grafana/grafana/search?utf8=%E2%9C%93&q=flot&type=

pre-processing the data would work well for all charts, since it would effectively limit the dataset size to the screen's pixel density (eg 1920x2 datapoints - high,low for each pixel). if the compression is done on the client, it has to allocate more ram for the compressed data array. if done on the server, then it may affect response times and backend server load/ram. since uPlot does on-the-fly compression directly in its drawing loop, it avoids additional mem allocations.

CrashLaker commented 4 years ago

thought this would be promising but it actually took over 2mins to render all // 55,550 data points x 3 series = 166,650 data points

image

prep: 33.447021484375ms
index.js:132 chart: 135557.19677734375ms

https://codesandbox.io/s/working-eui-y0lt8 https://elastic.github.io/elastic-charts/?path=/story/line-chart--stacked-with-axis-and-legend

leeoniya commented 4 years ago

i assume there are some knobs left to turn there. disabling the points may help a lot.

alexey-milovidov commented 1 year ago

Thank you for the great product! Unlike many other libraries, uPlot does not look wrong. Applied here: https://github.com/ClickHouse/ClickHouse/pull/38197