Recent

Author Topic: ChartExtentLink update error when empty charts are linked  (Read 6088 times)

wp

  • Hero Member
  • *****
  • Posts: 13398
ChartExtentLink update error when empty charts are linked
« on: January 17, 2013, 09:55:20 pm »
Maybe I am doing something wrong, but it seems that there is a bug in TChartExtentLink: if two charts are linked before the charts contain data the axes do not update if series are added later.

Run the attached demo. At first select the radio button "enabled (x axis linked)". Then add a series to the top chart by clicking on "Add data top". When you add data to the bottom chart by clicking on "Add data bottom" you will see that the y axis of the bottom chart does not update.

The behavior is correct if the charts are unlinked after starting the demo and the link is enabled after adding a few series.

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: ChartExtentLink update error when empty charts are linked
« Reply #1 on: January 18, 2013, 08:33:42 am »
In addition to the logical/current extent, chart has IsZoomed property, which is set to true by any LogicalExtent change, and to false by ZoomFull procedure.

Adding series modify full extent of the chart, but not the current extent.
When the chart is repainted and IsZoomed property is false, LogicalExtent is updated to match full extent. So, adding new series while the chart is not zoomed updates current extent automatically.

When you link charts, changing extent of any one of them propagates LogicalExtent to others, setting their IsZoomed property to true.
This is the reason for the behavior you see.
You can add AChart.ZoomFull call after AddSeries to fix that in your demo.

It can be argued that AddSeries should always perform ZoomFull,
but there are applications where it is desirable to preserve viewport while adding series.

wp

  • Hero Member
  • *****
  • Posts: 13398
Re: ChartExtentLink update error when empty charts are linked
« Reply #2 on: January 19, 2013, 05:21:51 pm »
Yes, the demo is running now. Unfortunately, my main project still does not, still the same issue.

When stripping down the project to a simple demonstration of the problem I obviously had stopped too early after having found the test case of the previous posting. My project, however, is a bit different: ChartExtentLink is disabled at program start, but is turned on depending on the settings in an ini file. Series are already created at designtime and are populated after loading data from file. Then I notice that the y-extent of one of the x-axis-linked charts is not updated according to the data.

The attached project is a better demonstration of the issue. Run the program. Check the option "Link charts" and press "Create data". The y range of the top chart should go from -2 to +2, but is stays at -1 to +1. Only after clicking into the chart the y extent is correct.

If you leave "Link charts" unchecked before creating data the behavior is correct.

Note that the demo code calls ZoomFull for both charts - before or after creating data does not matter because IsZoomed is false already when the procedure is entered.

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: ChartExtentLink update error when empty charts are linked
« Reply #3 on: January 19, 2013, 11:31:00 pm »
The problem is that ZoomFull procedure is lazy -- it sets a flag and calls Invalidate, but does not by itself recalculate the extent.
So by the time the painting message reaches Chart1, it already has received extent change notification from Chart2 via the link, and has IsZoomed = false.

You can work around this by replacing ZoomFull with the direct assignment:
Code: [Select]
Chart1.LogicalExtent := Chart1.GetFullExtent;
I am not sure how to fix it at TAChart level -- perhaps a boolean argument to ZoomFull to make it eager? Alternatively, separate IsZoomedX and IsZoomedY properties?

wp

  • Hero Member
  • *****
  • Posts: 13398
Re: ChartExtentLink update error when empty charts are linked
« Reply #4 on: January 20, 2013, 11:05:21 pm »
Thank you - assigning the extent was the solution.

Quote
I am not sure how to fix it at TAChart level -- perhaps a boolean argument to ZoomFull to make it eager?
Yes that would be fine. Calling "ZoomFull(true)" (with a boolean parameter for immediate or delayed zooming) is much more understandable code than "Chart.LogicalExtent := Chart.GetFullExtent".

Quote
It can be argued that AddSeries should always perform ZoomFull, but there are applications where it is desirable to preserve viewport while adding series.
I agree, unzooming whenever a new series is added may not be desirable. But can't the extent be calculated without unzooming?

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: ChartExtentLink update error when empty charts are linked
« Reply #5 on: January 21, 2013, 07:16:36 am »
Quote
Calling "ZoomFull(true)"
Done in r39926

Quote
But can't the extent be calculated without unzooming?
It can, this is what GetFullExtent function does.

wp

  • Hero Member
  • *****
  • Posts: 13398
Re: ChartExtentLink update error when empty charts are linked
« Reply #6 on: January 21, 2013, 01:07:57 pm »
Quote
this is what GetFullExtent function does.
What is the problem when TChartExtentLink.SynWith calls GetFullExtent for each linked chart? Shouldn't this solve the initial problem?

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: ChartExtentLink update error when empty charts are linked
« Reply #7 on: January 22, 2013, 10:31:17 am »
Depending on the order in which linked charts receive "repaint" events, this might still cause some double calculation, but overall you are right.
Done so in r39930.

wp

  • Hero Member
  • *****
  • Posts: 13398
Re: ChartExtentLink update error when empty charts are linked
« Reply #8 on: January 23, 2013, 12:25:56 am »
Thank you. Works perfectly now.

 

TinyPortal © 2005-2018