[BUG] Hover is slow in line graphs when there are many points
See original GitHub issueChart.js becomes very slow when we create a line graph of 5 000 points or more.
Expected Behavior
5 000 points is not a big graph. There shouldn’t be any performance problems when used on a modern computer or even a cell phone.
Current Behavior
By looking at the code quickly, it seems that the problem lies in the way the hover behavior calculates intersections. Currently, in core.interaction.js, it seems that getIntersectItems evaluates every visible item which is not ideal in a line chart. Idealy, you want to do a binary search on the x-axis since the data should be x-sorted before graphing.
Possible Solution
Calculate the intersection using a binary search on the x-axis instead of looking at every visible point for line graphs. This intersection calculation occurs every mouse move over the canvas and so happens very frequently. A binary search would mean a reduction, for 5000 visible elements, from 5000 iterations to log2(5000) ~= 13
iterations.
Steps to Reproduce (for bugs)
The following copepen ( https://codepen.io/anon/pen/WjMgVw ) show that there are performance problems when we have 5000 points in a line graph.
Context
Because of this issue, our company has had to use a different graphing library since we need to be able to graph 16k or so points.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:2
- Comments:10 (4 by maintainers)
Top GitHub Comments
Hello, would like to add a few observations, maybe it can help detect where the problem is…
I’ve noticed slow performance with horizontal bars when there’s a lot of items (13 so far).
Item being a product, with 2 datasets: Gross sales and quantity sold. (This is for a sales report, so it could go up to 100-200 items depending on the period it is generated).
I’m using responsive approach, so it resizes with the window, it’s height is dynamically set depending on products length, (something like
40px * products.length
). This works perfectly well for 5-6 items, but with perhaps 10 or more, it becomes really slow.If I resize however, making the bars short. It becomes fast again.
that’s a tough one to answer, considering uPlot does 0 redraw by delegating interactive elements to dom-land. if you guys are not drawing interactive elements on their own dedicated canvas and instead redrawing all the paths (and text labels) every 16ms, i would consider that excessive. if you do redraw all paths, you should at minimum be caching them in Path2D objects and simply repainting them without reconstructing them.
i don’t know the specifics of what chart.js does internally, i just see that the end result spins up my laptop’s cpu fan during series toggling and mousemoves.