Recent

Author Topic: [SOLVED] Problem with custom Max Min in a right axis.  (Read 4988 times)

donnie

  • Jr. Member
  • **
  • Posts: 72
[SOLVED] Problem with custom Max Min in a right axis.
« on: May 06, 2016, 03:08:41 pm »
Hi there,

I have a chart with some line series. I added a right axes and I want to put custom values to min an max of this axis. I have also added an axistransorfmation and the RightAxisAutoScaleTransform min and max set an area with the values of the right axis. Let's say that the left axis has values min=-10 and max=10. If the RightAxisAutoScaleTransform has min 2 and max 5, it will drawn the lineseries (that belongs to right axis) into the area between 2 and 5 from the left axis. I want to have custom min and max at the right axis. So I did this:
Code: Pascal  [Select][+][-]
  1. RightAxisAutoScaleTransform.Enabled := True;
  2. RightAxisAutoScaleTransform.MinValue := -10 //MyChartLeftAxesYMin;
  3. RightAxisAutoScaleTransform.MaxValue := 10 //MyChartLeftAxesYMax;
  4.  
  5. MyChart.AxisList.Axes[2].Range.UseMax := True;
  6. MyChart.AxisList.Axes[2].Range.UseMin := True;
  7. MyChart.AxisList.Axes[2].Range.Min := -5;
  8. MyChart.AxisList.Axes[2].Range.Max := 60;
  9.  

The above fits the lines to the limits of the y axis and set the limits of the right axis to the desired ones. And this is exactly what I know.
The major problem is that I get sometimes access violation which I don't know why.
After lot of hours of debug one error is at the TAChartUtils line 529 procedure UpdateMinMax  and
at the TACustomSeries line 408 procedure GetGraphBounds at the
TransformByAxis(FChart.AxisList, AxisIndexX).UpdateBounds(a.X, b.X);
 TransformByAxis(FChart.AxisList, AxisIndexY).UpdateBounds(a.Y, b.Y);

I believe that I have confused the limits and I don't know how to get that result.
« Last Edit: May 11, 2016, 08:47:02 am by dony »

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: Problem with custom Max Min in a right axis.
« Reply #1 on: May 06, 2016, 04:17:26 pm »
Whatever is displayed on the visible axes, each chart has two invisible axes; their units are called "GraphUnits", in contrast to "Axis units" on the visible axes. The "graph units" axes are an x axis and a y axis, just like on good old graph paper. Using AutoscaleAxisTransforms you define the unit range for each of the two axis; if there are several AutoScaleAxisTransforms for the same axis their graph units are just added.

Suppose you want to have two "real" vertical axes, one on the left, the other one at the right of the chart.  At first you have to decide whether the series assign to the left and the right axis are allowed to overlap, and to which degree.

Suppose, you want to restrict the series of the left axis to the lower half, that on the right axis to the upper half of the chart. Then you must divide the GraphUnits into two equal parts. Maybe allow the AutoScaleAxistranform assigned to the left axis range between 0 and 5, and that of the right axis between 5 and 10. Now when you plot, the series attached to left axis is automatically in the lower haft, the other one in the upper half of the chart.

If, on the other hand, you allow both series to overlap over the entire chart then give both AutoScaleTransforms equal min and max values, say from 0 to 10 (or 1, or whatever...).

The next decision is how you want the "real" labels on both axes. Normally they are determined automatically such that the series expand over the range allowed for them by the AutoscaleTransform and are continued into the adjacent part reserved for the other axis. You can restrict this by defining the Range of the axis. So, if you specify the Axis.Range to be between -10 and 10, labels will only be drawn between these limits. If the corresponding series has larger values, this part will be unabelled.

I hope you did catch the point. Maybe you should have a look at the Multiple panes in one chart tutorial which covers exactly this stuff. Or look at the examples in (lazarus)\components\tachart\demo\panes and ...\panes-2

If you'd still be stuck you should upload a short example (please, not the full project, only pas, lfm, lpi and lpr files packed into a single zip file). Then I could give you more specific advice.

donnie

  • Jr. Member
  • **
  • Posts: 72
Re: Problem with custom Max Min in a right axis.
« Reply #2 on: May 09, 2016, 09:49:08 am »
Thanks again for your reply wp.
I have understood your comments. In fact I had them in mind. The project is too big to send you. I try to make a smaller one and send it to you. I have a very weird access violation. Sometimes it runs ok and sometimes it doesn't. I can't understand what is the problem with the limits that I give to the axis. I give to autoscale min and max the min and max of the left axis in order the new lineseries to be in my diagram. After that I give to the right axis again the desired min and max. And I believe that here is the access violation. It's like I want to fit let's say from 10 to  - 10 (left axis min and max) the -3 to 50 the desired min and max from the right. It works ok most of the times but sometimes I have this access violation which I don't know why.

donnie

  • Jr. Member
  • **
  • Posts: 72
Re: Problem with custom Max Min in a right axis.
« Reply #3 on: May 10, 2016, 08:41:46 am »
I have placed Application.ProcessMessages after the scale min max and everything is ok. No access violation until now after many many debugs.
So I have placed the right access being scaled at the limits of the left but having the desired min and max values at the right.

Code: Pascal  [Select][+][-]
  1. RightAxisAutoScaleTransform.Enabled := True;
  2. Application.ProcessMessages;
  3. RightAxisAutoScaleTransform.MinValue := -10        //Left Axes Y Min
  4. RightAxisAutoScaleTransform.MaxValue := 10        //Left Axes Y Max
  5. Application.ProcessMessages;
  6.  
  7. MyChart.AxisList.Axes[2].Range.UseMax := True;
  8. MyChart.AxisList.Axes[2].Range.UseMin := True;
  9. MyChart.AxisList.Axes[2].Range.Min := -5;             //Desired min at the right axes
  10. MyChart.AxisList.Axes[2].Range.Max := 60;           //Desired max at the right axes
  11.  

The above fits the -5 to 60(right axes) at the -10 to 10(left axes).
And it works fine. The problem seems to be that there was not enough time for the bounds to be updated.

 

TinyPortal © 2005-2018