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

Behavior of y-scale zoom #343

Closed
martincheco opened this issue Oct 23, 2020 · 9 comments
Closed

Behavior of y-scale zoom #343

martincheco opened this issue Oct 23, 2020 · 9 comments

Comments

@martincheco
Copy link

Great and blazing-fast library, indeed!

I have implemented a graph that displays real-time spectra (1024 points each), 20FPS are no problem at all!
the program uses setData(newdata) to update the graph. By using opts: scales: {x: {time: false,auto:false}, I can get the desired behavior of the X-scale, which is autoscale at graph reation and a fixed range zoom after a X zoom event, persisting over the setData call. Doubleclick autoscales the X, which is perfect.

BUT the same strategy does not work for the Y scale (y:{auto:false})
The Y scale does not autoscale on graph creation and defaults to 0..100 range, which cannot be autoscaled even by doubleclick.
Tried auto:true and setData(newdata, false), but the graph does not update at all!

Not sure if this is an issue or just my ignorance, however the documentation and the demos are rather sketchy on this one..
Thanks for any hints in advance!

@GitHubLionel
Copy link

Hi,

I am not sure but do you remove the series before setting new data ?
Something like
for (var i = plot.series.count-1; i = 0; i--) plot.delSeries(i);

Regards,
Lionel

@leeoniya
Copy link
Owner

leeoniya commented Oct 23, 2020

@martincheco

i'm in the process of removing the [0,100] defaults from the lib, since it causes more problems that it solves (see #334 (comment)) and expanding auto-ranging to be more flexible (see #328).

The Y scale does not autoscale on graph creation and defaults to 0..100 range, which cannot be autoscaled even by doubleclick.

i think it's worth figuring out exactly how auto true/false should work before attempting to fix this.

one of the purposes of auto: false is for performance reasons, so the data does not need to be scanned to find the min/max, which would be a good savings when scanning a million datapoints, especially so on init creation. x auto-ranging is cheap, because the data format requires min to be at data[0][0] and max to be at data[0][data[0].length - 1].

x auto-ranging may happen on:

  1. init
  2. setData
  3. zoom reset

y auto-ranging may happen on:

  1. init
  2. setData
  3. any setScale, including zoom reset

if we force y to auto-scale on init, you lose the ability to avoid that min/max scanning cost.

should double-clicking also ignore auto: false? seems inconsistent. the fact that it works for x despite auto: false is inconsistent, too.

i hope there's an easy and consistent solution, but i'm not sure what that is.

maybe a callback signature can be added for scale.auto so it can make a decision dynamically as to whether min/max scanning should be performed or not. this way you can return true during init but false after. this still does not solve the issue of inconsistent behavior in the boolean case.

@martincheco
Copy link
Author

Thanks for the answer. I finally solved it by invoking redraw(true/false) separately for each frame. I guess it would be possible also by changing the opts on the go (?)

Agree that the minmax search could be a performance hit, however I still did not get the logic behind the different behavior of X and Y auto:true/false. Just imagine parametric graphs where X are not given in ascending order.

I'd definitely vote for auto:true/false consistency between both axes and x+y autoscaling function of the doubleclick, both controllable by opts for the subsequent invoking of redraw (or is it already controllable?).

Btw. default setting of X as time feels a bit arbitrary, although it does not hurt to switch it off.

@leeoniya
Copy link
Owner

leeoniya commented Oct 24, 2020

however I still did not get the logic behind the different behavior of X and Y auto:true/false. Just imagine parametric graphs where X are not given in ascending order.

uPlot is fundamentally a timeseries plotting lib. its internals require X to be strictly ascending, and a good amount of its perf is derived from this assumption, along with x-alignment of every series' data. x is special, which is why arbitrary scatter and X/Y plots are tricky to add support for.

Btw. default setting of X as time feels a bit arbitrary, although it does not hurt to switch it off.

does it still seem arbitrary given the above explanation?

@leeoniya
Copy link
Owner

leeoniya commented Oct 24, 2020

maybe adding some variant of auto: (self, implicit) => shouldFindMinMax to the api where implicit is true for init and doubleclick.

the default behavior for both x and y scales would be to return true when implicit is true.

@leeoniya
Copy link
Owner

leeoniya commented Nov 2, 2020

@martincheco i just pushed a commit that adds a callback signature to scale.auto.

try it out and see if that works for you (in combo with scale.range, of course). something like this will only auto-scale on init and when double-clicking (scale reset):

scales: {
    y: {
    	auto: (self, ready, resetScales) => resetScales || !ready;
    }
}

@leeoniya
Copy link
Owner

leeoniya commented Nov 2, 2020

i've adjusted the API so that ready would be available to more functions, so the new form is this:

scales: {
    y: {
    	auto: (self, resetScales) => resetScales || self.status != 1;
    }
}

@leeoniya
Copy link
Owner

leeoniya commented Nov 5, 2020

closing this as resolved. let me know if you have any issues.

@martincheco
Copy link
Author

I just tested with the y scales opts you suggested

somehow it seems to work, however now zooming of the X-axis is broken, do you see the same behavior? Y-axis zoom still works fine.

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

3 participants