Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Available graph types and callbacks (documentation) #103

Closed
jjech opened this issue Jan 27, 2020 · 8 comments
Closed

Available graph types and callbacks (documentation) #103

jjech opened this issue Jan 27, 2020 · 8 comments

Comments

@jjech
Copy link

jjech commented Jan 27, 2020

Hello, very interesting project here!

We are currently using dygraphs, and it has been very good for our project. My favorite thing about it is the excellent documentation, which makes it easy to utilize the extensive callback library and to know what is available for use:

http://dygraphs.com/options.html
http://dygraphs.com/new-site/jsdoc/symbols/Dygraph.html

Unfortunately, as you know, the dygraphs project has been inactive for quite some time. Some of the stale PRs in the dygraphs repository are relevant to our use case, so we're considering the possibility of migrating to a different charting library such as uPlot that is actively being maintained. However, it is unclear if it will suit our purposes in its current state.

Here are my questions:

  • Is uPlot currently capable of drawing different types of charts such as scatter plot, candlestick, etc?
  • Does uPlot offer callbacks such as pointClickCallback, zoomCallback, etc?

Thanks so much for your time, great project here!

@leeoniya
Copy link
Owner

leeoniya commented Jan 27, 2020

hi @jjech

Is uPlot currently capable of drawing different types of charts such as scatter plot, candlestick, etc?

currently no (which i also believe is the case for dygraphs =).

candlestick & ohlc can be done via a simple plugin which draws on uPlot's canvas, for which i have an open issue. (#98). if you'd like to try authoring one, you can use this hooks demo as a guide: https://leeoniya.github.io/uPlot/demos/draw-hooks.html

i have some post-v1.0 plans to add bar/column and scatter plots, mostly because i consider those to be fundamentally different than line/area charts and useful. v1.0 is close, but i won't start on the other types immediately, so there's no specific timeline at the moment.

Does uPlot offer callbacks such as pointClickCallback, zoomCallback, etc?

yes, setScale is the zoomCallback. there's currently no pointClickCallback because uPlot does not have any non-drag click functionality (besides cursor locking, which is disabled by default). however, it's quite easy to add your own click listener to the canvas, and then use uPlot's utility methods to get back scale or data values at the mouse position. as mentioned above, the draw-hooks demo makes use of quite a few of these hooks.

docs take a lot of time, and i'm trying to find more time, but this is a hobby project and i have a life outside of my 9-5 and github. so i welcome doc contributions from uPlot's users after they've had some experience and i've answered questions in various issues for them. you can get an overview from what's already in the readme, issue #48. plus, most of the API can be sampled by reading through the substantial amount of demo code [1] and maybe browsing the closed issues, especially with the question tag.

if you're considering switching from dygraphs to uPlot, keep in mind that uPlot is unlikely to support numerous features in the core - in part due to philosophical differences, in part due to avoiding the "kitchen sink" and maintaining perf and a small codebase. the general rule-of-thumb is that if something can be done as a plugin, then it will not be included in the core. i encourage you to first play with all the demos to make sure there's enough functionality & possibilities there for your use cases.

[1] https://github.com/leeoniya/uPlot/tree/master/demos

@jjech
Copy link
Author

jjech commented Jan 28, 2020

Thanks very much! I like your plugin-based approach, and it really shines in the performance.

Yes, you're right --- dygraphs doesn't really offer a proper scatter plot either --- another reason why we're interested in migrating to something else. Currently we're using Chart.js for scatter plots, and the performance there is not good with our large data sets.

It's great to see that you have so many examples available, thank you for pointing me in that direction. I'm excited to continue exploring uPlot and assess whether it's a good fit for our project. If we end up making the switch, we may be able to work on a scatter plot PR in the near future... would also be happy to contribute documentation once we're more familiar with what uPlot has to offer.

Regardless, very nice work here! Thank you for sacrificing some of your free-time to create and maintain an alternative to dygraphs.

I'll close this issue now, as you've answered my questions quite thoroughly.

@jjech jjech closed this as completed Jan 28, 2020
@leeoniya
Copy link
Owner

great, thanks for checking it out and feel free to open question issues if you need any pointers for your testing.

cheers!

@leeoniya
Copy link
Owner

@jjech out of curiosity, how many scatter-plot points are you dealing with? and what are your thoughts on interactivity? do all of them need to be clickable/hoverable? which ones should get labels, if any?

with a line chart the points are not critical, but with scatter they are. right now, the hover points are all dom based, and there's only one per series. but if i had to display thousands of points per line chart, then the DOM solution becomes untenable and anything more than few hundred points (dom elements) will become visibly problematic, requiring a canvas-based rendering solution.

i will likely use https://github.com/mourner/kdbush or https://github.com/mourner/flatbush for the spatial index and the underlying data structure for the scatter plot.

@jjech
Copy link
Author

jjech commented Jan 28, 2020

A ballpark estimate for one of our standard scatter plots is about 10,000 data points. Chart.js is pretty much unusable at that scale, probably for the reason you explained (every point is a DOM element?)

In an ideal world, we'd be able to display and interact with all 10,000 data points. Every point would be clickable and hoverable with labels, and we could update the graph by clicking on the items in the legend to toggle visibility.

These are the two most relevant demos for our interests:
https://leeoniya.github.io/uPlot/demos/focus-cursor.html
https://leeoniya.github.io/uPlot/demos/tooltips.html

Key features to our graphs are the ability to display hover data, to toggle visibility of series via legend, and to highlight the closest series on hover. We also would like to be able to click on points to "stick" the data point to the legend so that users can do things like open Snipping Tool and take a screenshot of the data for a target point.

So far it looks like uPlot can do all of this for line graphs (not entirely sure about "click on points to 'stick' the data point to the legend" yet, but the rest is showcased in your demos linked above). If it's possible to offer the same functionality with uPlot scatter plots displaying 10,000 data points, that would be a major win. But if we have to use a different solution for our scatter plots due to the large number of data points, that's not the end of the world (we're already using two different charting libraries due to dygraphs not supporting scatter plots).

@leeoniya
Copy link
Owner

Chart.js is pretty much unusable at that scale, probably for the reason you explained (every point is a DOM element?)

chart-js is purely canvas-based. but they have some pretty large inefficiencies in the core. they've been making a lot of progress though while watching uPlot, so their current master (which will become v3) is already a lot faster for initial render, at least for lines - you might want to try it out. their interaction is still slow though.

In an ideal world, we'd be able to display and interact with all 10,000 data points. Every point would be clickable and hoverable with labels, and we could update the graph by clicking on the items in the legend to toggle visibility.

with 10k points, i don't see how you can physically interact with all 10k at a fully-zoomed-out level (even when there's only moderate clustering). it's not so much an issue of performance, but of a usable UI. i think the chart lib would have to prioritize which points to make interactive somehow, otherwise it can easily turn into a dancing soup on mousemove. the same goes for labels. can you show me a screenshot of x/y scatter with 10k labels in a single display?

if you look at scatter plots, very few have labels - even selective labels - prior to hover.

for high density plots like you're describing you cannot possibly expect hover interaction with anything that you cannot unambiguously target with a mouse - which excludes 99% of the dataset in many cases:

i think some visuals of your current UI would be helpful for me.

We also would like to be able to click on points to "stick" the data point to the legend so that users can do things like open Snipping Tool and take a screenshot of the data for a target point.

cursor locking (via click) kinda gets you this. it'll free up the mouse and lock the cursor at its position (and by extension the values displayed in the legend). you can turn it on via {cursor: {lock: true}}.

@jjech
Copy link
Author

jjech commented Jan 28, 2020

with 10k points, i don't see how you can physically interact with all 10k at a fully-zoomed-out level (even when there's only moderate clustering). it's not so much an issue of performance, but of a usable UI.

Absolutely, we need to zoom in to interact with the majority of actual points on the graph. If we had some way to detect if points were visually overlapping at the current zoom level, we wouldn't actually need to draw or attempt to offer interaction with all 10,000.

if you look at scatter plots, very few have labels - even selective labels - prior to hover.
for high density plots like you're describing you cannot possibly expect hover interaction with anything that you cannot unambiguously target with a mouse - which excludes 99% of the dataset in many cases:

For the labels on the points, we're only looking for something to appear on hover. And yes, this isn't really possible for the majority of data points until the user has zoomed in quite a bit for the reason you sourced.

Some of our scatter plots would look similar to this: https://files.knime.com/sites/default/files/styles/inline_medium/public/5-2_scatter_plot_solution.png
...but with many more series (10-20 types of wine instead of just white and red).

We also would like to be able to click on points to "stick" the data point to the legend so that users can do things like open Snipping Tool and take a screenshot of the data for a target point.

cursor locking (via click) kinda gets you this. it'll free up the mouse and lock the cursor at its position (and by extension the values displayed in the legend). you can turn it on via {cursor: {lock: true}}.

This looks like it will achieve the effect we're looking for, so that's excellent! I'm definitely looking forward to testing out uPlot with our tool later this week.

@leeoniya
Copy link
Owner

If we had some way to detect if points were visually overlapping at the current zoom level, we wouldn't actually need to draw or attempt to offer interaction with all 10,000.

yeah, this may end up being more expensive/complex than simply doing the interaction (no matter how useless). certainly worth benchmarking and will depend heavily on the performance of the underlying spatial index.

i opened #107 for scatterplot thoughts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants