Recent

Author Topic: [Implemented] How to auto-scale an axis depending on the shown extent  (Read 24024 times)

Muso

  • Sr. Member
  • ****
  • Posts: 356
I have a program that displays sensor data. At the beginning the sensor needs some time until it is in full operation. Therefore the sensor data starts at zero and then raises to e.g. 10. Then real measurements can start. The range of the interesting data is therefore in the range 10 - e.g. 20.

Therefore i implemented chart scrolling by setting a logical extent to the e.g. last 5 minutes.

The y-axis has and also should have the whole time the feature to auto-scale the range. At the moment when showing the full chart, this means the y-range us automatically 0 - 20, but since only the last 5 min are shown, the range should be 10 - 20 or whatever the y-data in this x-range is.

I could scan all data line series to find the min/max in the last 5 min and then set the axis min/max accordingly. But maybe there is a better solution?
« Last Edit: July 21, 2021, 04:36:41 am by Muso »

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: How to auto-scale an axis depending on the shown extent
« Reply #1 on: July 07, 2021, 10:21:42 am »
I could scan all data line series to find the min/max in the last 5 min and then set the axis min/max accordingly. But maybe there is a better solution?
The series has a method FindYRange for this purpose:
Code: Pascal  [Select][+][-]
  1. procedure TChartSeries.FindYRange(AXMin, AXMax: Double;  var AYMin, AYMax: Double);  

Muso

  • Sr. Member
  • ****
  • Posts: 356
Re: How to auto-scale an axis depending on the shown extent
« Reply #2 on: July 07, 2021, 04:55:18 pm »
I could scan all data line series to find the min/max in the last 5 min and then set the axis min/max accordingly. But maybe there is a better solution?
The series has a method FindYRange for this purpose:
Code: Pascal  [Select][+][-]
  1. procedure TChartSeries.FindYRange(AXMin, AXMax: Double;  var AYMin, AYMax: Double);  

Yes, this is what I meant with scan all series. I thought that there is maybe a method for the chart itself that one can adjust to take e.g. only the data of the current extent to set the axis range when the axis range setting is "Auto".

If there is no such method, I will go on and implement the series scan solution.

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: How to auto-scale an axis depending on the shown extent
« Reply #3 on: July 07, 2021, 06:20:01 pm »
When I answered your very first question to this overall topic, I was not aware that you are using trunk, and pushed you on the track with the extents. However, not so long ago there was a similar request, and it ended that I added a TChartLiveView component to trunk which does most of the scrolling automatically, controlled by a few properties (https://wiki.lazarus.freepascal.org/TAChart_documentation#Live_View). I am not sure if it is sufficient for your overall, more complex, needs, but you should have a look a the liveview demo in the TAChart demo folder.

Muso

  • Sr. Member
  • ****
  • Posts: 356
Re: How to auto-scale an axis depending on the shown extent
« Reply #4 on: July 07, 2021, 07:39:00 pm »
that I added a TChartLiveView component to trunk

This is amazing and exactly what I need. I will try if and how I can use it for ma real-life program because it is almost ready.

Concerning the liveview demo, I think there is an issue:
- start program
- go to live mode
- add at least 6 data points (so that you get the scrolling effect)
- leave the live mode
- add more data points

result: you don't see any change. I thought when leaving the live mode one sees the full x-range

Muso

  • Sr. Member
  • ****
  • Posts: 356
Re: How to auto-scale an axis depending on the shown extent
« Reply #5 on: July 07, 2021, 09:39:56 pm »
I implemented the Live view feature and it works so far, except of one thing that seems to be a bug:

- see attached a screenshot without the live view. You can see that the data jumped from zero to around 7
- I turn now the Live view on and display only the last minute. But then the y-axis range is wrong, see attached. I have as extent "lveAuto".

My expectation that then the y-axis range is the min/max of the currently displayed data. But my max overall data is 10 while the y-axis range max is in Live view 200.
I have for the left axis an auto scale axis transformation. The data series is connected in y to the y-axis and in x to the x-axis.

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: How to auto-scale an axis depending on the shown extent
« Reply #6 on: July 07, 2021, 10:28:01 pm »
Can you post a project so that I can see exactly what is happening?

Muso

  • Sr. Member
  • ****
  • Posts: 356
Re: How to auto-scale an axis depending on the shown extent
« Reply #7 on: July 07, 2021, 11:40:05 pm »
Can you post a project so that I can see exactly what is happening?

- use the attached project
- start it and do nothing but wait 15 seconds
- then switch to live mode

result: the y-axis range is now -1500 to 1500 8at least on my PC.

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: How to auto-scale an axis depending on the shown extent
« Reply #8 on: July 08, 2021, 06:01:42 pm »
You also have a right axis in the chart, and it does not have an AxisTransformations component. When I add another TChartAxisTransformations with AutoScaleTransfrom and assign it to the right axis, the chart behaves correctly.

Muso

  • Sr. Member
  • ****
  • Posts: 356
Re: How to auto-scale an axis depending on the shown extent
« Reply #9 on: July 09, 2021, 12:22:36 am »
You also have a right axis in the chart, and it does not have an AxisTransformations component. When I add another TChartAxisTransformations with AutoScaleTransfrom and assign it to the right axis, the chart behaves correctly.

Does not work for me. Attached is an example program showing this. I attached now also a screencast of what I see. (using Lazarus 2.3.0 r65422 FPC 3.2.2 x86_64-win64-win32/win64)

But also without the additional axis transformation - the right axis is not connected to any data series, so it cannot be the reason that the LeftAxis is totally wrong.
« Last Edit: July 09, 2021, 01:25:25 am by Muso »

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: How to auto-scale an axis depending on the shown extent
« Reply #10 on: July 09, 2021, 01:20:29 am »
In mode ExtentY=lveAuto the axis transformation was not applied to the determined y extent. Should be fixed in r65423

Muso

  • Sr. Member
  • ****
  • Posts: 356
Re: How to auto-scale an axis depending on the shown extent
« Reply #11 on: July 09, 2021, 02:15:27 am »
In mode ExtentY=lveAuto the axis transformation was not applied to the determined y extent. Should be fixed in r65423

Many thanks! I can confirm this bug is fixed.

However my initial problem remains:
- take the example project from my previous post
- enable Live mode
- wait at least 16 seconds

result: all 3 ExtentY settings show you an y-axis range 0 - 9

expected: when the ExtentY setting is "Auto" I get an y-axis range of e.g. 8.1 - 9.9 (-/+10% of the minimal/maximal value within the viewport time)


wp

  • Hero Member
  • *****
  • Posts: 11916
Re: How to auto-scale an axis depending on the shown extent
« Reply #12 on: July 09, 2021, 11:25:23 am »
Fixed in r65429.

Muso

  • Sr. Member
  • ****
  • Posts: 356
Re: How to auto-scale an axis depending on the shown extent
« Reply #13 on: July 09, 2021, 01:59:06 pm »
Fixed in r65429.

Many thanks. However, the bug is not fixed for me because I have in my program a second LineSeries connected to the right axis and then the y-axis range is completely wrong even for the left axis.

Attached is a small example program showing the issue:
- start the program, switch to Live mode
- wait 16 seconds

p.s. could you please have a quick look at: https://forum.lazarus.freepascal.org/index.php/topic,55292.0.html

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: How to auto-scale an axis depending on the shown extent
« Reply #14 on: July 09, 2021, 09:20:26 pm »
I am afraid, the TChartLiveView was not designed for multiple axes because for this the auto extenty mode should modify the Range of each vertical axis, but it modifies the logical extent instead - this is the visible part of the entire chart

I think the component can be rewritten to do this but it requires a clear mind... The problem I see is: what happens if the user intentionally modifies the axis.Range himself - but when the ChartLiveview becomes active this setting will be lost.

 

TinyPortal © 2005-2018