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
Chart zoom is not smooth #15569
Comments
Hi @govinda18 I am able to recreate this problem only when moving the cursor extremely fast. I can only imagine doing so for the sake of recreating the problem, so maybe there are some real-life scenarios that you could share when this would really be a problem? Only the mouse move events inside of the chart's container are registered for the drag, so you could also hold the zoom selection and go under the chart, exit the container while still dragging, and move horizontally under the chart - the zoom selection will not be changed until you return into the chart's container. |
Not related to Highcharts Stock only: https://jsfiddle.net/BlackLabel/4xdsr8ov/ Isn't that a problem that happens in jsFiddle? Events from the left iframe are not available in the results frame. It doesn't have to be a fast move to the left, simply move to the left, then release the mouse button (in the code tab), go back to the chart. The selection marker will still follow the mouse pointer. Regarding this:
We are limited by events processed by the browser. The same happens when you move your mouse really fast, out of the browser. Check this short description of why it happens: #12998 (comment) |
So we have build a wrapper to render highcharts in python frameworks such as JupyterLab. This problem scales up somehow there. It is a bad UX as it seems pretty natural for people not using range selector to view say the last 7 days of financial data and quickly move the mouse to the left or right edge of the chart. Even while moving slow, we have observed times when we are just not able to move to the very end of the chart. |
@pawelfus Can you look into this again? Maybe the mouseup position currently used is the last mouse position inside the plot area? Is that how mouseleave works? And if so, maybe we should look out the first mouse position outside too. |
Sure thing! @govinda18 could you try this plugin? Load this plugin after loading Highcharts and other plugins. (function(H) {
H.wrap(
H.Pointer.prototype,
'onContainerMouseDown',
function(proceed, e) {
const prevDef = e.preventDefault;
e.preventDefault = () => {};
const ret = proceed.call(this, e);
e.preventDefault = prevDef.bind(e);
return ret;
}
)
})(Highcharts); If this doesn't help, could you reupload the GIF? |
Hello @pawelfus , Our stakeholders have been stressing on this problem of unable to zoom to right-most points since a year back; and in the last week, they spot-lighted this bug once again as critical-immediate-fix because they almost misinterpreted their financial zoomed data, by saying:
I created a reproducer - See demo fiddle. When you try zooming (briskly), the selection skips points near the right-end as shown below: Is there a way to leverage into internal highcharts functionality to do the below:
To do the above, knowledge of internal highcharts working is required, that is why I'm requesting some help / assistance from highcharts developers. Thank You, |
Unable to zoom quickly is an issue, but the bigger issue is that, even if we zoom slowly, still the very last date point is dropped - See #18863. Just to mention: In the above example gif, I used |
Hi @rdp1414 Thank you for providing a great demo to reproduce this! In your case, it is a bit different issue: the mouseup happens inside the window, so we are able to change this. Please check this: https://jsfiddle.net/BlackLabel/ezxbpqmh/1/ Plugin: (function(H) {
H.wrap(
H.Pointer.prototype,
'onContainerMouseLeave',
function(proceed, e) {
this.onContainerMouseMove(e);
return proceed.apply(this, Array.prototype.slice.call(arguments));
}
)
})(Highcharts); Could you please test it and let us know the results? If that resolves the issue, we will implement this in the library too. Plugin: (function(H) {
H.wrap(
H.Pointer.prototype,
'setDOMEvents',
function(proceed) {
const ret = proceed.apply(this, Array.prototype.slice.call(arguments));
// Move mousemove event from container, to document:
const pointer = this;
pointer.chart.container.onmousemove = Highcharts.noop;
Highcharts.addEvent(
pointer.chart.container.ownerDocument,
'mousemove',
function() {
pointer.onContainerMouseMove(...arguments);
}
);
return ret;
}
)
})(Highcharts); |
Hello @pawelfus , First of all, thank you for replying back promptly. There are 3 sub-problems here which I explained in the code-comments and applied solutions given by you for 2 of them and 1 is still waiting- See demo fiddle.
Yes, I tested out both plugins provided by you in our highcharts project and faced following problems (we're using highstock Plugin-1When I try to zoom till the right-extreme end, the area is selected but zoom doesn't happen. While trying to zoom within the bounds of the chart, it works as normal: Plugin-2No matter where I hover mouse on the screen, even if not on the chart, Large number (more then 1000) of below errors are logged on the console: ←→1 of 126 errors on the page
TypeError: Cannot read properties of undefined (reading 'tooltip')
Pointer.onContainerMouseMove
.../node_modules/highcharts/highstock.src.js:27845
27842 | */
27843 | Pointer.prototype.onContainerMouseMove = function (e) {
27844 | var chart = this.chart,
> 27845 | tooltip = chart.tooltip,
27876 | ^ pEvt = this.normalize(e);
27847 | this.setHoverChartIndex();
27848 | // In IE8 we apparently need this returnValue set to false in order to
View compiled
HTMLDocument.mouseMoveHandler
<the file where this plugin was written>.js:76
73 | pointer.chart.container.onmousemove = Highcharts.noop;
74 | Highcharts.addEvent(pointer.chart.container.ownerDocument, 'mousemove', function mouseMoveHandler() {
75 | // eslint-disable-next-line prefer-rest-params
> 76 | pointer.onContainerMouseMove(...arguments);
77 | });
78 | return ret;
79 | }); |
Thanks for testing it @rdp1414
This won't work - dev tools don't fire The same when you do the You can fire document
.documentElement
.addEventListener(
'mouseleave',
(e) => document.dispatchEvent(new MouseEvent('mouseup', e))
);
Fixed plugin: https://jsfiddle.net/BlackLabel/1bwyj2et/2/ - should be fine now, however I would focus on solution 1 at this moment. |
Hello @pawelfus ,
Yes, stakeholders won't look at financial charts with dev-tools open. Plugin-1
Even with the code in this new demo, our charts still show the same problem - See gif: Plugin-2
Thank you for this plugin-2. Applying this in our project, zooming, no matter how fast it is done and the pointer moves out due to momentum of the hand, zooming works correctly - See gif: Had both plugins worked correctly for us, then I think, you would have suggested plugin-1 and not plugin-2, is that true? But given that only plugin-2 works for us, so, we have to go with plugin-2 only - See final fiddle. |
Now, this leaves us with the only bug / issue - #18863 which is dropping only the very last date-point. Zooming, briskly or slowly, till the extreme ends of the chart functions correctly. Still, there is one particular case - Highstock chart in which the very last-date is dropped while trying to zoom till the right-end of the Highstock chart. This error does NOT happen for the very first-date while trying to zoom till the left-end of the Highstock chart. Also, for other cases, Highcharts numeric and Highcharts datetime, this error does NOT happen. |
Good to hear the second solution works better, thanks for the info! The second issue seems to be a bug, very specific to the dataset - answered in #18863 |
Hello @pawelfus ,
This regression has started to show-up in our production charts, so, this bug is PRIORITY for us. Thank you, |
From the previous Comment,
In that
I narrowed down that this tooltip issue is happening due to the second plugin, commenting out second plugin fixes the tooltip issue - See fiddle: Maybe this will help your debugging. |
Thank you for reporting the issue! That means we have to resign from the second solution, and polish the first one: (function(H) {
H.wrap(
H.Pointer.prototype,
'onContainerMouseLeave',
function(proceed, e) {
this.onContainerMouseMove(e);
return proceed.apply(this, Array.prototype.slice.call(arguments));
}
)
})(Highcharts); Replaced the second plugin with the above and it works fine: https://jsfiddle.net/BlackLabel/zusLdb7y/ - it will still not capture events when leaving the browser (eg reaching Chrome's dev-tools). I know you said it still doesn't solve the problem: #15569 (comment) - but I'm not able to reproduce this. Could you try reproducing the issue? Thanks! |
A tooltip issue can be reproduced in the demo which you provided https://jsfiddle.net/BlackLabel/zusLdb7y/. In this demo, the charts are placed one-below-other. If the charts are placed one-beside-other, then tooltip issue is happening- See fiddle. Tooltips on both the charts are visible simultaneously. When the chart is hovered on the second chart, the first chart's tooltip is still visible. See below gif. |
Hello @pawelfus , In this update, you said
When I used the first one in our environment, then zoom is not happening when pointer is released outside chart. See the below gif from in our environment: In your update, the above issue was not reproducible. But, when the charts in your demo are placed side-by-side, and you zoom on the first chart and pointer goes out of the chart, exactly the same bug is seen which is seen in our environment - See reproducer fiddle. See gif: In the above reproducer fiddle, if the pulgin is commented out, then the above problem is resolved. Zoom happens correctly on the first chart - See plugin removed fiddle. This is a production issue which we're facing since a long time. Stakeholders have complained multiple times. Please give some suggestions/solutions to address this issue. Thank you, |
Hi @rdp1414 Thank you for the details! It was a mistake in my plugin, fixed version: https://jsfiddle.net/BlackLabel/Lz5txbe3/ Fixed part: (function(H) {
H.wrap(
H.Pointer.prototype,
'onContainerMouseLeave',
function(proceed, e) {
this.onContainerMouseMove(e);
return proceed.apply(this, Array.prototype.slice.call(arguments, 1)); // missing "1" in arguments
}
);
})(Highcharts); Please let us know if you find any issues with a given solution. |
Hello @pawelfus ,
Yes, the zoom problem explained in this update is still occurring even with your given solution. But the tooltip issue explained in this update is fixed with your solution. |
Hello @rdp1414, I have created this pull request (#19083) so that we can add and run tests on the branch, and fix the issues mentioned in that topic one by one. Right now, to test new fixes you can pull the transpiled code directly from the brach, just like in this example: https://jsfiddle.net/BlackLabel/vwrb1u8y/ Here are the notes for the current state of the code: Quick mouse drag to zoom works fine (chart is zoomed to the last point) The only issue that remains is zooming when two charts are side by side: https://jsfiddle.net/BlackLabel/vwrb1u8y/ Is it the only issue that we have to fix, or do you see any other problems on code from the aforementioned branch? |
Hello @kamil-musialowski, There are few issues with our setup of Highcharts. Let me explain our situation:
Can you please give some advice and suggestions? Regards, |
Hi Rajdeep, I think option 3 is most practical for both parties. @kamil-musialowski what if we create snippets that contain all the changes, then give them version numbers to keep track of it until the various facets of the issue are fixed? |
@TorsteinHonsi I also think that creating code snippets with the changes will be the best option. I'll prepare them :) |
Working in parallel here... Anyway, here's the drop-in snippet for the current state of the fix, also tested on v10: /*
Drop-in fix for #15569, drag-zoom issues.
Version: 2023-06-07
*/
(function(H) {
const { pick, Pointer, wrap } = H;
wrap(
Pointer.prototype,
'onContainerMouseLeave',
function(proceed, e) {
this.onContainerMouseMove(e);
return proceed.apply(this, Array.prototype.slice.call(arguments, 1)); // missing "1" in arguments
}
);
wrap(
Pointer.prototype,
'onContainerMouseMove',
function(proceed, e) {
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
this.setHoverChartIndex(e);
}
);
Pointer.prototype.setHoverChartIndex = function (e) {
const chart = this.chart;
const hoverChart = H.charts[pick(Pointer.hoverChartIndex, -1)];
if (
hoverChart &&
hoverChart !== chart
) {
hoverChart.pointer.onContainerMouseLeave(
e || { relatedTarget: chart.container }
);
}
if (
!hoverChart ||
!hoverChart.mouseIsDown
) {
Pointer.hoverChartIndex = chart.index;
}
};
})(Highcharts); https://jsfiddle.net/highcharts/Loqywrv4/ @rdp1414 Please test and advice |
We made a legacy theme for this exact situation, see https://www.highcharts.com/samples/highcharts/members/theme-v10 . It was announced in the changelog. It is not a perfect representation of the v10 design, but close. |
Expected behaviour
Chart zoom should be smooth
Actual behaviour
We have encountered this issue mostly with stock charts with large dataset. When we zoom into the chart with a relatively faster mouse movement, the selection often gets stuck.
Right now, mouse-zooming charts is done by dragging the mouse inside the axes area. Unfortunately, dragging beyond the edge of that area stops the JS code from receiving events (or something like that) and it's extremely hard to get the selection to go all the way to the left or right edge. When we move the mouse slowly, we are able to select that. Refer the following gif:
Live demo with steps to reproduce
https://jsfiddle.net/o3pnxkjw/
Product version
Highstock 9.0.1
Affected browser(s)
Browser
The text was updated successfully, but these errors were encountered: