Recent

Author Topic: How to automatically fit data while using multiple panes  (Read 652 times)

Andries

  • Newbie
  • Posts: 4
How to automatically fit data while using multiple panes
« on: August 25, 2022, 12:53:09 pm »
Dear forum members,

I'd like to plot the measurement data from our sensors in a chart with multiple panes stacked on top of each other while sharing the same x-axis. We would like to have a scrolling chart that automatically adjusts each y-axis range to always fit the incoming data.

Following the great instructions on the Lazarus Wiki pages we have been able to achieve this. We have set the axis Marks.AtDataOnly property to true to prevent overlap of the marks of one y-axis with the marks of the other a-axes.

However, the result is not exactly what we had in mind.

With these settings, a part of the data extends above and below the horizontal grid lines, making it harder to estimate the values of the peaks of our data.

My question is: is there a simple setting to have autoscaling AND make sure the traces never extend above or below the horizontal grid lines for each axis? Or is this only possible by calculating the maximum range ourselves?

When we would calculate and set the y-axis range ourselves, then because of using the property UseNiceStep=true, the data can still extend beyond the grid lines. (e.g. data point has value 50, horizontal grid line is at 40 and not at 60). See middle pane in attached picture "TracesExtending.png".

I have attached two pictures to illustrate what we are looking for. The picture "TracesExtending.png" is what we have right now. The picture "TracesIncluded.png" shows what we would like to achieve.

Any help is much appreciated.

dje

  • Full Member
  • ***
  • Posts: 124
Re: How to automatically fit data while using multiple panes
« Reply #1 on: August 25, 2022, 01:48:48 pm »
I'm not an expert on TTAChart's, so this was found from trial and error. You would have a better understanding of these options. Hope it helps.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   LIndex: integer;
  4.   LLineSeries: TLineSeries;
  5. begin
  6.   for LIndex := 0 to Chart1.Series.Count - 1 do begin
  7.     if Chart1.Series[LIndex] is TLineSeries then begin
  8.       LLineSeries := TLineSeries(Chart1.Series[LIndex]);
  9.       Chart1.AxisList[LLineSeries.AxisIndexY].Intervals.Options :=
  10.         [aipGraphCoords, aipUseCount(*, aipUseMaxLength, aipUseMinLength*)];
  11.       if LLineSeries.MaxYValue > 10 then begin
  12.         Chart1.AxisList[LLineSeries.AxisIndexY].Marks.Format := '%0:.0f';
  13.       end else begin
  14.         Chart1.AxisList[LLineSeries.AxisIndexY].Marks.Format := '%0:.1f';
  15.       end;
  16.     end;
  17.   end;
  18. end;  

Andries

  • Newbie
  • Posts: 4
Re: How to automatically fit data while using multiple panes
« Reply #2 on: August 25, 2022, 02:27:50 pm »
Thanks dje, for your quick response. This certainly does help my understanding of the charting possibilities. I appreciate your help.

Your solution doesn't completely solve our problem, unfortunately. Our sensor data can span different orders of magnitude which means this approach does not make it completely auto-scaling.

wp

  • Hero Member
  • *****
  • Posts: 10288
Re: How to automatically fit data while using multiple panes
« Reply #3 on: August 25, 2022, 11:23:22 pm »
With these settings, a part of the data extends above and below the horizontal grid lines, making it harder to estimate the values of the peaks of our data.
This is not a bug. TAChart does not scale the axes such that there are labels at the begin and end of the axis. It always scales the data to cover the full range provided by the chart. Therefore, the first and last labels usually can only be placed INSIDE the axis range.

I don't know of an easy way how to avoid this.

As a workaround you could turn off the Frame of the chart (Chart.Frame.Visible := false), turn on the AxisPens of the axes (Chart.AxisList[0].AxisPen.Visible := true, chart.AxisList[1].AxisPen.Visible := true, etc) and set the AtDataOnly of the axes to true (in addition to the Marks.AtDataOnly; Chart.AxisList[0].AtDataOnly := true, Chart.AxisList[1].AtDataOnly := true, etc). Then the y axis lines will only be drawn for the ranges defined by the data. Due to the gaps between the pane axes it is easier to distinguish the individual panes.
« Last Edit: August 25, 2022, 11:25:52 pm by wp »

Andries

  • Newbie
  • Posts: 4
Re: How to automatically fit data while using multiple panes
« Reply #4 on: August 26, 2022, 05:03:18 pm »
Many thanks wp, for your reply. I didn't think it was a bug. I just hoped there was a smart combination of settings that would give us the desired result.

I have tried your workaround. Indeed the separation of the pane axes does make the individual panes easier to distinguish (see picture). The grid lines remain in the same places however. What else can we try?

wp

  • Hero Member
  • *****
  • Posts: 10288
Re: How to automatically fit data while using multiple panes
« Reply #5 on: August 26, 2022, 08:09:11 pm »
I think that breaking the grid lines between the panes is a very difficult job because the vertical grid lines are drawn by the x axis, but the breaks are defined by the y axes.

Either turn the grid off, or use three separate charts and take advantage of a TChartExtentLink to link the x axes.

Andries

  • Newbie
  • Posts: 4
Re: How to automatically fit data while using multiple panes
« Reply #6 on: September 06, 2022, 01:53:24 pm »
Thanks for your suggestion, wp. Breaking the grid lines between the panes is fortunately not really needed.

For now we have chosen to manually adjust the range of each vertical axis.

Every time new data is added to the chart, we calculate the range of the data points and use that range so set the vertical axis extends. We add an extra 10% of that range at the top and the bottom to force the horizonal grid lines to show up above and below the series.

Now, when we zoom in on the data, the series will always be between the horizontal grid lines. This work fine for us.




 

TinyPortal © 2005-2018