### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: [SOLVED] How to get min-max values of zoomed TAChart bottom-axis  (Read 712 times)

#### munair

• Hero Member
• Posts: 696
• keep it simple
##### [SOLVED] How to get min-max values of zoomed TAChart bottom-axis
« on: August 12, 2019, 05:11:44 pm »
I have a TAChart with zoom tool attached to it. The bottom axis values are dates. When zooming into a specific part of the chart, is it possible to get the first and last date of the zoomed part so that they can be displayed in a separate label?
« Last Edit: August 12, 2019, 10:36:50 pm by Munair »

#### munair

• Hero Member
• Posts: 696
• keep it simple
##### Re: How to get min-max values of zoomed TAChart bottom-axis
« Reply #1 on: August 12, 2019, 10:36:35 pm »
As I had to do a quick job on this one, I came up with a dirty hack, but at least it works. If anybody knows a more elegant way (e.g. accessing marks by index), please let me know.
Code: Pascal  [Select][+][-]
1. // ..
2. Marking: boolean;
3. FirstMark, LastMark: double;
4. // ...
5. procedure TfrmMain.Chart1AfterDraw(ASender: TChart; ADrawer: IChartDrawer);
6. begin
7.   lbSelectedTimeValue.Caption := FormatDateTime('YYYY-MM-DD, hh:nn', FirstMark)
8.     + ' - ' + FormatDateTime('YYYY-MM-DD, hh:nn', LastMark);
9.   Marking := false;
10. end;
11.
12. procedure TfrmMain.Chart1AxisList1MarkToText(var AText: String; AMark: Double);
13. begin
14.   if Marking = false then
15.     begin
16.       FirstMark := AMark;
17.       Marking := true;
18.     end
19.   else
20.     LastMark := AMark;
21. end;

#### wp

• Hero Member
• Posts: 7353
##### Re: [SOLVED] How to get min-max values of zoomed TAChart bottom-axis
« Reply #2 on: August 13, 2019, 12:10:23 am »
You mean the first and last axis labels? Hmmm, I don't know a better solution.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

#### munair

• Hero Member
• Posts: 696
• keep it simple
##### Re: [SOLVED] How to get min-max values of zoomed TAChart bottom-axis
« Reply #3 on: August 13, 2019, 06:31:35 am »
Yes, first and last axis label, so that when zoomed in to a level of only days/hours, the full date range can still be displayed.

#### wp

• Hero Member
• Posts: 7353
##### Re: [SOLVED] How to get min-max values of zoomed TAChart bottom-axis
« Reply #4 on: August 13, 2019, 10:11:48 am »
Hmmm.... When you want to display information on the visible viewport, wouldn't it be better to use the "true" begin and end of the axis? The position of the axis labels is not under your full control, and depending on the label density the first label may be placed after the first data point.

In order to get the "true" zoomed axis range you can call Chart.CurrentExtent which is a rectangle structure with TDoublePoint records a and b at the left/bottom and right/top corners, respectively. There is also a LogicalExtent which does not consider Margins and data point labels; this is essentially the zoomed rectangle, but I think you need the CurrentExtent here. The begin and end of the x axis, therefore, can be determined like this:

Code: Pascal  [Select][+][-]
1. procedure GetXAxisRange(Chart: TChart; out FirstX, LastX: double);
2. var
3.   ex: TDoubleRect;  // requires TAChartUtils in "uses"
4. begin
5.   ex := Chart.CurrentExtent;
6.   FirstX := ex.a.x;
7.   LastX := ex.b.x;
8. end;

Of course, you still must convert FirstX and LastX to date/time strings as needed.

You can call this function in the OnExtentChanged event of the Chart.
Mainly Lazarus trunk / fpc 3.2.0 / all 32-bit on Win-10, but many more...

#### munair

• Hero Member
• Posts: 696
• keep it simple
##### Re: [SOLVED] How to get min-max values of zoomed TAChart bottom-axis
« Reply #5 on: August 13, 2019, 11:24:06 am »
Thanks wp, I'll give that a try.

#### munair

• Hero Member
• Posts: 696
• keep it simple
##### Re: [SOLVED] How to get min-max values of zoomed TAChart bottom-axis
« Reply #6 on: August 13, 2019, 11:47:29 am »
YES. Works much better. The range is more accurate and when zooming/panning, it is updated down to the second. To illustrate this, the data set starts on August 1 at 20:12, which is returned by the CurrentExtent approach. My initial solution returns July 31, 0:00.
Code: Pascal  [Select][+][-]
1. procedure TfrmMain.Chart1ExtentChanged(ASender: TChart);
2. begin
3.   GetXAxisRange(ASender, FirstMark, LastMark);
4.   lbSelectedTimeValue.Caption := FormatDateTime('YYYY-MM-DD, hh:nn', FirstMark)
5.     + ' - ' + FormatDateTime('YYYY-MM-DD, hh:nn', LastMark);
6. end;