View Issue Details

IDProjectCategoryView StatusLast Update
0035002LazarusTAChartpublic2019-06-11 22:27
ReporterMarcin WiazowskiAssigned Towp 
PrioritynormalSeverityminorReproducibilityalways
Status assignedResolutionopen 
Product Version2.1 (SVN)Product Build60312 
Target VersionFixed in Version 
Summary0035002: TAChart: potential improvements in zooming and panning
DescriptionI created this topic here, to continue a discussion about zooming and panning, that arisen in 0034896.

A test program is attached to this report - by using it and the instructions below, some issues with zooming and panning can be observed; the instruction was written by "wp" and comes from 0034896. The test program has been slightly modified when comparing to the original test program in 0034896, so the instruction below could be shortened a bit.

-----------------



According to documentation, zooming and panning are intended to do nothing else than setting the LogicalExtent
(http://wiki.lazarus.freepascal.org/TAChart_documentation#Extents [^]):

* For zooming the user can paint the new LogicalExtent on the chart by dragging a rectangle from the top/left to bottom/right corners (using the left mouse button). When the mouse is released this rectangle will become the new LogicalExtent.

* For Panning the user drags the viewport to a new location (using the right mouse button).


Panning
=======
* Press the RIGHT mouse button somewhere in the chart and drag it around.

* When marks are off everything behaves as expected, the entire chart nicely follows the mouse, no size changes.

* Click into the chart (with left button) to restore the original position.

* Now turn on the 2nd (huge) mark. Drag the mouse (right button) a bit towards the top --> suddenly the bar becomes much larger (because the guaranteed_space mechanism is turned off). Or drag the mouse down so that the top of the bar disappears below the bottom axis --> suddenly the mark disappears (because the Chart.IsPointInViewPort is no longer true)
  
* Both effects are not expected by the user and should be avoided.


Zooming
=======
* At first, in order to see the effect of "correct" zooming have both marks turned off and drag the zoom rect closely around the first bar --> when the mouse button is released the bar grows to closely fill the viewport. That's correct.

* Restore the original unzoomed state by clicking with the left button into the chart.

* Turn on the mark of the first bar. Drag a rectangle again closely around the bar without the mark --> the bar increases in size, but the mark is visible. Well - basically I would not expect to see the mark, but with AutoMargins active that's probably how it should be because the chart always tries to show the mark; and since normally the marks are small the zooming effect is clear and appears to be correct.

* But: after resetting the zoom drag a larger rectangle which tightly encloses the bar and the mark --> the bottom part of the mark is expected to be near the x axis, but it turns out to be somewhere in the center of the chart. This is disturbing although this behaviour has been there all the time.

* Reset the zoom again, turn off the the mark of the first bar, and turn on the mark of the second bar, the one with the very high mark. Again drag the zoom rect around the bar only --> the size of the bar does not change because due the size reserved for the margin it can only be drawn in the narrow MinDataSpace. This is not expected.

* Drag a larger zoom rect which encloses the last mark row ('mmmm') and reaches down to the lower end of the bar --> the bar becomes smaller. Again, not expected, some kind of "anti-zooming"...


I did not spend much work on these phenomena, but is seems to me that they are a consequence of the fact that the zoomed region is defined by the LogicalExtent, not by the CurrentExtent.
TagsNo tags attached.
Fixed in Revision
LazTarget
WidgetsetWin32/Win64
Attached Files

Activities

Marcin Wiazowski

2019-02-03 23:59

reporter  

Test.zip (3,759 bytes)

Marcin Wiazowski

2019-02-04 02:01

reporter   ~0113845

> I did not spend much work on these phenomena, but is seems to me that they are a consequence of the fact that the zoomed region is defined by the LogicalExtent, not by the CurrentExtent.

Same observations here. LogicalExtent gets moved or zoomed, and then CurrentExtent is recalculated, basing on LogicalExtent - and it is either expanded to make some space for marks (when needed), or it's not expanded. This causes some strange effects.

For example: In the attached Test program, bars occupy vertical range -20 .. 70 (so LogicalExtent's vertical range will be -20 .. 70). When second bar has some mark, this range is expanded to, let's say, -20 .. 230. Finally, top and bottom margins (these pink areas) must be also applied, so range may become -21 .. 231. So CurrentExtent becomes -21 .. 231 (but LogicalExtent is still -20 .. 70).

Now the user uses panning to move the chart by +2 units. In this case, LogicalExtent changes from -20 .. 70 to -18 .. 72. Second bar's top is no longer visible, so mark is also not visible - so no margin for mark is applied. Finally pink margins must be applied, so CurrentExtent becomes -19 .. 73.

So moving the chart by +2 units changes CurrentExtent (i.e. displayed range) from -21 .. 231 to -19 .. 73. This can't look nice.

This could be potentially avoided by modifying BOTH LogicalExtent and CurrentExtent by +2 units, and DISABLING any further recalculations.



> [Panning] Now turn on the 2nd (huge) mark. Drag the mouse (right button) a bit towards the top --> suddenly the bar becomes much larger (because the guaranteed_space mechanism is turned off)...

It seems that it is as I described above: second bar's top becomes invisible, so mark becomes invisible, so no margin for mark is applied, so there is suddenly enough space for painting and guaranteed_space has nothing to do anymore.



> ... Or drag the mouse down so that the top of the bar disappears below the bottom axis --> suddenly the mark disappears (because the Chart.IsPointInViewPort is no longer true)

Similar behavior as when dragging to top.

Also when dragging to left or right, mark disappears immediately when left or right half of the bar becomes invisible.



> [Zooming] But: after resetting the zoom drag a larger rectangle which tightly encloses the bar and the mark --> the bottom part of the mark is expected to be near the x axis, but it turns out to be somewhere in the center of the chart. This is disturbing although this behaviour has been there all the time.

This look strange, but is easy to explain: when zooming, we expect the bar to become, let's say, 3x higher, but we do NOT expect the MARK to become higher - we expect it to have still same font's size. As a consequence, mark is not enlarged, so we receive some spare space below the mark. We could assume, that the user's intention was just to zoom the bar along with its mark - so, after zooming, the extent could be cut at the bottom - but this cutting is allowed to remove only blank space, and not any other data point / line / bar (that may belong to some other series and might also be selected along with our mark).



> [Zooming] Reset the zoom again, turn off the the mark of the first bar, and turn on the mark of the second bar, the one with the very high mark. Again drag the zoom rect around the bar only --> the size of the bar does not change because due the size reserved for the margin it can only be drawn in the narrow MinDataSpace. This is not expected.

I can't agree: the bar's height changes, but only a bit, so it's hard to see. In the data source, change Y of the first point from -20 to -70 - then it will be better visible, that the second bar becomes higher.



> [Zooming] Drag a larger zoom rect which encloses the last mark row ('mmmm') and reaches down to the lower end of the bar --> the bar becomes smaller. Again, not expected, some kind of "anti-zooming"...

This can be also reproduced when there is only one bar on the chart, having a simple, 1-line mark, under normal conditions - when there is enough space for painting the bar and its mark (i.e. MinDataSpace has nothing to do). But for a mark having only 1 line, the behavior becomes same as that behavior that you described above: "the bottom part of the mark is expected to be near the x axis, but it turns out to be somewhere in the center of the chart". I replied there, that, after zooming, the extent could be made smaller to avoid holding unused space - in this case, the bar would become larger again - there would be no "antizooming" anymore.

Marcin Wiazowski

2019-05-30 19:37

reporter   ~0116465

Here come some additional observations, that I promised (in some other report) to describe.



When zooming, all the chart elements are zoomed in or out - but with the exception of data point labels (marks) - their dimensions remain always same. This has some advantages and some disadvantages.



Let's take a look at the attached ZoomingCases.png:

a) Selection frame is made tightly above the label, but, after zooming in, there is a lot of space above the label - this is because the label has not been enlarged proportionally.

b) Selection frame is made tightly around the label only, but, after zooming in, nothing is shown - this is because data point, to which the label belongs, has not been selected - the point became invisible, so its label has not been drawn at all.

c) Selection frame is made around two labels, where one of them is partially drawn above the other - after zooming in, labels are not enlarged proportionally, so they are now both fully visible (which is nice).



Ad a) Maybe labels should be scaled proportionally? I prepared a small demo - see ScaledLabel.png and ScaledLabel.zip. Well, this looks rather terribly for me... I'm not a fan of this idea. We should also note, that scaling the label proportionally means, that the label may become very small when zooming out.



Now the question is: why may the user make a selection just around the label(s)? Because he wants to see the label better (not everyone's eyes work perfectly...) - these are our cases a) and b). Or because he can see some label, that is hidden below some other label - this is our case c).



The conclusion is: maybe a solution would be to create a new tool: LABEL ZOOMING tool? I prepared a simulation showing, how this could work: see the attached ZoomLabelSimulation.gif.

ZoomingCases.png (28,679 bytes)
ZoomingCases.png (28,679 bytes)
ScaledLabel.png (8,906 bytes)
ScaledLabel.png (8,906 bytes)
ScaledLabel.zip (2,539 bytes)
ZoomLabelSimulation.gif (73,007 bytes)
ZoomLabelSimulation.gif (73,007 bytes)

wp

2019-05-31 12:23

developer   ~0116471

Last edited: 2019-05-31 12:26

View 2 revisions

Nice idea, I like it.

It will be difficult, however, to correctly handle the case that a smaller label is completely covered by a larger one -> introduce a "secondary index" for painting the labels? Maybe such a rearranged label painting order is needed even without the tool. And what when two labels exactly overlap because they have the same size and their data points are at the same coordinates? How will the tool select the hidden one?

There is other functionality that should be available in a label tool, and maybe this can be combined with the LabelZoom tool: Similar to the other GUI tools that I added recently ("Axis click" etc) there should be a LabelClickTool which fires an OnClick event in which the user would have the possibility to edit the label text. (Or the Datapoint click tool could be extended by this functionality and provide some "HitInfo" parameter to differentiate between data point and label clicks - but there's the additional complexity of data point label overlaps which could probably be handled more easily with separate tools).

Marcin Wiazowski

2019-06-11 22:27

reporter   ~0116678

> It will be difficult, however, to correctly handle the case that a smaller label is completely covered by a larger one -> introduce a "secondary index" for painting the labels? Maybe such a rearranged label painting order is needed even without the tool.

Good question. Secondary index might be a partial solution - labels could be sorted by size for drawing purposes (like bubbles in bubble series demo in 0035356). This would make label painting better, although not ideal.

Maybe overlapping labels should be drawn simultaneously, one above the other?



> And what when two labels exactly overlap because they have the same size and their data points are at the same coordinates? How will the tool select the hidden one?

Two data points at SAME coordinates may generate DIFFERENT label areas - one of the series may have MarkPositions = lmpPositive, while the other MarkPositions = lmpNegative.

Two data points at DIFFERENT coordinates may generate SAME label areas - one of the points may be below/above the other, but may have different Marks.Distance value.

So the only factor, to take into account, should be a position/shape of the selected label.



There is one more thing to think over: for non-rotated series, only label's height is included in series extent (for rotated ones - width). This means that label, that is placed at the right or left chart's edge, may be partially truncated - and will become even more truncated after zooming. Maybe also label's width should be (optionally) taken into account? Alternatively, label zooming tool could enlarge chart extent's width in some other way.

Issue History

Date Modified Username Field Change
2019-02-03 23:59 Marcin Wiazowski New Issue
2019-02-03 23:59 Marcin Wiazowski File Added: Test.zip
2019-02-04 02:01 Marcin Wiazowski Note Added: 0113845
2019-02-04 18:49 wp Assigned To => wp
2019-02-04 18:49 wp Status new => assigned
2019-05-30 19:37 Marcin Wiazowski File Added: ZoomingCases.png
2019-05-30 19:37 Marcin Wiazowski File Added: ScaledLabel.png
2019-05-30 19:37 Marcin Wiazowski File Added: ScaledLabel.zip
2019-05-30 19:37 Marcin Wiazowski File Added: ZoomLabelSimulation.gif
2019-05-30 19:37 Marcin Wiazowski Note Added: 0116465
2019-05-31 11:59 wp File Added: Reproduce2a.zip
2019-05-31 11:59 wp File Added: Reproduce2a.png
2019-05-31 12:00 wp File Deleted: Reproduce2a.zip
2019-05-31 12:00 wp File Deleted: Reproduce2a.png
2019-05-31 12:23 wp Note Added: 0116471
2019-05-31 12:26 wp Note Edited: 0116471 View Revisions
2019-06-11 22:27 Marcin Wiazowski Note Added: 0116678