TAChart: lack of cooperation between zooming tools and chart's ExtentSizeLimit
Original Reporter info from Mantis: Marcin Wiazowski
-
Reporter name:
Original Reporter info from Mantis: Marcin Wiazowski
- Reporter name:
Description:
I'm attaching a patch, that solves some problem with the (lack of) cooperation between chart's ExtentSizeLimit and zooming tools.
Let's make an experiment first: launch the attached "extent_limit_test_mod3" application, enable "Use XMin = 0.9" and "Use XMax = 1.1" options, and try to use zoom click or zoom wheel tool - nothing happens. Then enable also "Animation (all zoom tools)" option - now some zooming occurs.
Explanation: when we look into TChart.SetLogicalExtent() we can see, that chart's ExtentSizeLimit works in the following way: when trying to assign some new value to LogicalExtent, width and height of the requested new extent are verified - and, if some of them is below or above the allowed limit, no change in the logical extent is performed at all - the whole request is rejected.
The general idea of zooming tools is quite simple: they set LogicalExtent to needed values - thus performing zooming in or out. As a consequence, if the requested LogicalExtent doesn't conform chart's ExtentSizeLimit, zooming just fails.
In our case, the initial horizontal extent is 0 .. 1 (so its width is 1), the allowed minimum width is 0.9, and the allowed maximum width is 1.1. Zoom click and zoom wheel tools have ZoomFactor set to 1.2, so - when zooming out, if animations are off - they just try to set the new horizontal extent to -0.1 .. 1.1 (so width is 1.2). This operation fails.
When animation is enabled, 10 steps of animation are used - this means, that the following consecutive extents are requested:
- 0 .. 1 (initial extent)
- -0.01 .. 1.01 (width = 1.02)
- -0.02 .. 1.02 (width = 1.04)
- -0.03 .. 1.03 (width = 1.06)
- -0.04 .. 1.04 (width = 1.08)
- -0.05 .. 1.05 (width = 1.1)
- -0.06 .. 1.06 (width = 1.12)
- -0.07 .. 1.07 (width = 1.14)
- -0.08 .. 1.08 (width = 1.16)
- -0.09 .. 1.09 (width = 1.18)
- -0.1 .. 1.1 (width = 1.2)
In this case, requests 1) .. 5) are within the allowed range, so these animation steps can be applied and seen, and requests 6) .. 10) are above the allowed range, so they are ignored (and the animation finishes prematurely).
The solution is: we should check, if the requested new extent is within the allowed range; if not, we should downscale it - in our case this means, that our one step (if animation is off) or 10 steps (if animation is on) should be applied to achieve not transformation from 0 .. 1 to -0.1 .. 1.1, but from 0 .. 1 to -0.05 .. 1.05.
In the example above, some final animation steps fail. It is also possible, that some initial steps may fail - this can occur, for example, when we are zooming in, and ExtentSizeLimit's maximum width is smaller than the full extent (full extent can be successfully applied always, regardless of the ExtentSizeLimit settings) - well, this isn't very clever setting, but can occur.
So, finally, the patch should verify both initial and final extents, and - if needed - adjust both of them, to be within the allowed ExtentSizeLimit's minimum and maximum ranges.
In report #35344 (closed), LimitToExtent functionality has been introduced in zooming tools. The patch attached here is a bit similar - in both cases, maximum extent's width is applied if needed. Differences are:
- here, we must take care not only about the maximum extent's width, but also minimum extent's width,
- when dealing with ExtentSizeLimit, the requested (i.e. assigned to LogicalExtent) ranges must be contained strictly within ExtentSizeLimit - if our request is under/oversized even only due to lack of precision of the floating-point calculations, our request will be rejected.
The attached code isn't very complicated, although it must handle four limits (XMin, XMax, YMin, YMax), both of them when zooming in and out - so similar code must be used several times.
After applying the patch, zooming just works - in one step (if animation is off) or in the requested number of steps (if animation is on) - zooming no longer can finish prematurely (or start with some delay, which could occur without the patch, when failing to apply some initial animation steps).
Similarly as in the #35344 (closed) patch, there is a special handling for zooming out, to allow showing the full extent back - if one of the dimensions can no longer be zoomed out, the proportionality rule is relaxed, to allow achieving the full extent's size also by the another dimension.
Mantis conversion info:
- Mantis ID: 35634
- Build: 61292
- Version: 2.1 (SVN)