Recent

Author Topic: [SOLVED]Programmatically autoscaling one of several charts  (Read 704 times)

fmolina

  • New Member
  • *
  • Posts: 31
[SOLVED]Programmatically autoscaling one of several charts
« on: July 03, 2020, 11:29:22 pm »
Hi,
In a project I have several charts which share a common popup menu. There is a variable GrafAct which is set to the currently working chart via the OnMouseDown event. There is an Autoscale item in the popup menu. If I understand well, there should be a transformation for each chart. The question: is there a way to enable/disable the TAutoScaleAxisTransformation of the current chart in the Autoscale item event without testing one by one all the charts? Something like GrafAct.LeftAxis.Transformations.something?
Thanks
« Last Edit: July 05, 2020, 01:11:20 am by fmolina »

wp

  • Hero Member
  • *****
  • Posts: 7539
Re: Programmatically autoscaling one of several charts
« Reply #1 on: July 04, 2020, 12:45:30 am »
Are these separate charts? Or do you combine various axes within the same chart? In the former case you do not need Transformations at all.

it is not clear to me what you mean by "AutoScale". Automatic scaling of the minimum and maximum of an axis depending on the series displayed? The AutoScaleAxisTransform on the other hand means scaling of the data range to some part of the chart so that several axes can be used.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

fmolina

  • New Member
  • *
  • Posts: 31
Re: Programmatically autoscaling one of several charts
« Reply #2 on: July 04, 2020, 04:31:19 pm »
Hi,
I mean separate charts with different data, setting min and max of y (and/or x) axis. "You do not need transformations at all", how to do it then? I did not find anything else in the documentation.

wp

  • Hero Member
  • *****
  • Posts: 7539
Re: Programmatically autoscaling one of several charts
« Reply #3 on: July 04, 2020, 06:27:46 pm »
There are several properties which affect the axis limits. The one possibility with the highest priority is to use the elements of the Chart.Extent property. When you set Chart.Extent.YMin to 10 and turn on Chart.Extent.UseYMin the minimum of the y axis will always be 10 - no matter what the "real" minimum is. When you switch Chart.Extent.UseYMin back to false the axis minium will jump back to the minimum of the data. The maximum can be handled in the same way. But note that minimum and maximum must be in order, i.e. during switching values it must never happen that min > max - the chart does not like this.

In the demo I selected a different way based on the internal extents of the chart; these are rectangles (*) with the corner points of the chart area in axis units (well - not 100% exact: only when there are no axis transformations). The extent with axes scaled can be determined by Chart.GetFullExtent, and the data extent corresponding to the visible window is the Chart.LogicalExtent (there is also a Chart.CurrentExtent - it is almost the same but encloses also the margins around the sides of the chart). You can set the elements of this rectangle and force the corresponding axis limit to this value. Just study the attached demo and its code.

----
(*) The TDoubleRect, the data type of the extents, is a record containing the bottom/left and top/right corner points of the chart area as TDoublePoints a and b. And each TDoublePoint record has elements x and y for the x and y coordinates. So, when you have a TDoubleRect variable ext you can change the minium of the y axis by changing the element ext.b.y; and for, say, the maximum of the x axis you would need ext.b.x.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

fmolina

  • New Member
  • *
  • Posts: 31
Re: Programmatically autoscaling one of several charts
« Reply #4 on: July 05, 2020, 12:44:31 am »
Thank you! Nice example.
But I have a last question: if I want to make log scale, do I need transformations? If so, will colide with that way of autoscaling?

wp

  • Hero Member
  • *****
  • Posts: 7539
Re: Programmatically autoscaling one of several charts
« Reply #5 on: July 05, 2020, 12:51:33 am »
For a log axis you in fact need the LogAxisTransform. In this case, the extents refer to the transformed value -- TAChart calls them "graph units", opposed to "axis units" of the raw numbers. Suppose you have data ranging between 7.52 and 653, and you want the axis to start at 1 and end at 1000. In this case, set ext.a.y := 0 (= log10(1)) and ext.a.y := 3 (= log10(1000)). the same values are to be used in the Chart.Extent.YMin and Chart.Extent.YMax method.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

fmolina

  • New Member
  • *
  • Posts: 31
Re: Programmatically autoscaling one of several charts
« Reply #6 on: July 05, 2020, 01:10:45 am »
   ;)

wp

  • Hero Member
  • *****
  • Posts: 7539
Re: [SOLVED]Programmatically autoscaling one of several charts
« Reply #7 on: July 05, 2020, 12:51:05 pm »
To complete this thread and because it is usually more difficult to achieve a good log axis I am attaching also a modified version of the previous demo project in which the context menu contains options to switch between linear and logarithmic axes. You may have to play with the axis' Intervals parameters to achieve good settings, mainly the Tolerance, MaxLength and MinLength (in decreasing importance).

[EDIT]
Sorry - I forgot to take care of the min/max selection... Therefore, I replaced the project attached to this post by a more complete one-
« Last Edit: July 05, 2020, 04:35:16 pm by wp »
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

fmolina

  • New Member
  • *
  • Posts: 31
Re: [SOLVED]Programmatically autoscaling one of several charts
« Reply #8 on: July 06, 2020, 04:39:50 am »
Many thanks! :D

 

TinyPortal © 2005-2018