Recent

Author Topic: [solved] how to change axis number format  (Read 251 times)

Muso

  • Sr. Member
  • ****
  • Posts: 347
[solved] how to change axis number format
« on: July 14, 2022, 04:17:08 pm »
(This thread is a spin-off from https://forum.lazarus.freepascal.org/index.php/topic,59909.msg447407.html#msg447407)

I need to change the number format of the x-axis to day:hour:minute on demand.

The XY data are in a TLineSeries and its x-values are minutes.

So I am looking for a method, that the user can choose to display the time instead of in minutes also in the format day.hour:minute
How can this be achieved?
« Last Edit: July 18, 2022, 02:46:53 pm by Muso »

wp

  • Hero Member
  • *****
  • Posts: 10046
Re: how to change axis number format
« Reply #1 on: July 14, 2022, 10:05:01 pm »
You can provide a handler for the OnGetMarkText event of the x axis. It gets the x value (minutes, in your case) and returns the displayed text. So, if the user wants to see minutes, don't use this handler. But if he wants to see days.hours:minutes you can hook the handler to the event, do the conversion and return the result in the handler. Not 100% sure, but you may have to adjust the Chart.BottomAxis.Intervals.MaxLength to avoid overlapping labels when switching between these two cases.

Muso

  • Sr. Member
  • ****
  • Posts: 347
[solved] Re: how to change axis number format
« Reply #2 on: July 18, 2022, 02:46:38 pm »
You can provide a handler for the OnGetMarkText event of the x axis. It gets the x value (minutes, in your case) and returns the displayed text.

Many thanks!

For the case someone else needs this too, here is my solution:

Notes:
name of the chart is "SIXCH", I have 3 context menu items *MI with which the user can select if the time should be in days, minutes or hours. I also have an option to output the time in the format [day:hour:minute]

Here is the main procedure:

Code: Pascal  [Select][+][-]
  1. procedure TSIXControl.SCSIXCHAxisList1GetMarkText(Sender: TObject;
  2.   var AText: String; AMark: Double);
  3. begin
  4.  if MainForm.TimeDaysHoursMinMI.Checked then
  5.  begin
  6.   AText:= SIXControl.CalcDaysHoursMins(AMark);
  7.   MainForm.SIXCH.BottomAxis.Intervals.MaxLength:= 100;
  8.   MainForm.SIXCH.BottomAxis.Title.Caption:= 'Time [dd:hh:mm]';
  9.  end
  10.  else
  11.  begin
  12.   // do nothing
  13.   AText:= Format(MainForm.SIXCH.BottomAxis.Marks{%H-}.Format, [AMark]);
  14.   // use the default width for labels
  15.   MainForm.SIXCH.BottomAxis.Intervals.MaxLength:= 50;
  16.   if MainForm.TimeMinuteMI.Checked then
  17.    MainForm.SIXCH.BottomAxis.Title.Caption:= 'Time [min]'
  18.   else if MainForm.TimeHourMI.Checked then
  19.    MainForm.SIXCH.BottomAxis.Title.Caption:= 'Time [hour]'
  20.   else if MainForm.TimeDayMI.Checked then
  21.    MainForm.SIXCH.BottomAxis.Title.Caption:= 'Time [day]';
  22.  end;
  23. end;

And here is the function that performs the formatting:
Code: Pascal  [Select][+][-]
  1. function TSIXControl.CalcDaysHoursMins(x : double) : string;
  2. // reformats x to the format day:hour:minute
  3. var
  4.  days, hours, minutes : integer;
  5. begin
  6.  // only if the data format is actually used, we do the calculation
  7.  if not MainForm.TimeDaysHoursMinMI.checked then
  8.  begin
  9.   if MainForm.TimeMinuteMI.checked then
  10.    // we explicitly want decimals here
  11.    result:= Format('%.2f', [x])
  12.   else
  13.    // take the chart's formatting
  14.    result:= Format(MainForm.SIXCH.BottomAxis.Marks{%H-}.Format, [x]);
  15.   exit;
  16.  end;
  17.  
  18.  days:= 0; hours:= 0; minutes:= 0;
  19.  if MainForm.TimeMinuteMI.Checked then
  20.  begin
  21.   days:= floor(x / 1440);
  22.   hours:= floor((x / 1440 - days) * 24);
  23.   minutes:= round(((x / 1440 - days) * 24 - hours) * 60);
  24.  end
  25.  else if MainForm.TimeHourMI.Checked then
  26.  begin
  27.   days:= floor(x / 24);
  28.   hours:= floor((x / 24 - days) * 24);
  29.   minutes:= round(((x / 24 - days) * 24 - hours) * 60);
  30.  end
  31.  else if MainForm.TimeDayMI.Checked then
  32.  begin
  33.   days:= floor(x);
  34.   hours:= floor((x - days) * 24);
  35.   minutes:= round(((x - days) * 24 - hours) * 60);
  36.  end;
  37.  
  38.  result:= Format('%.2d',[days]) + ':'
  39.           + Format('%.2d',[hours]) + ':' + Format('%.2d',[minutes]);
  40. end;

 

TinyPortal © 2005-2018