How to make the X scale show hour, minutes and seconds? lazarus / 55-TAChart ---------------------------------------------------------------------- CM630 · 2014-07-21 10:29 Haw can I make the X scale show hours, minutes and seconds? For example if I have a curve starting from 0 to 10000 seconds, I want to have on the curve to have displayed 0:30:00; 1:000:00; 1:30:00... 10 000 seconds should be displayed as 2:26:40. I remember that I tried this a long time ago and I had no success.  TAchart converted seconds to some absolute time... I do not remember exactly, but if someone tells me the straight way I will be thankful. ---------------------------------------------------------------------- CM630 · 2014-07-23 13:33 I have some partial success. The following code: Code: [Select]uses ... TAGraph, TAIntervalSources, TASeries, TAChartUtils, TACustomSource... procedure TForm1.Button2Click(Sender: TObject); var   MyChart: TChart;   MySeries: TLineSeries;   MyScaleXMarks: TDateTimeIntervalChartSource;   i:integer; begin   MyChart:= TChart.Create(Self);   MyChart.Parent:= Self;   MyScaleXMarks:=TDateTimeIntervalChartSource.Create(Self);   MyScaleXMarks.Params.Count:=5;   MyScaleXMarks.Params.Options:=[aipUseCount,aipUseNiceSteps];   MyScaleXMarks.Steps:=[dtsHour,dtsMinute,dtsSecond,dtsMillisecond]; MyScaleXMarks.DateTimeFormat:='hh:mm:ss.ss';   MyChart.BottomAxis.Marks.Format:='%2:s';   MyChart.BottomAxis.Marks.Source:=MyScaleXMarks;   MySeries:=TLineSeries.Create (MyChart);   MyChart.AddSeries(MySeries);   for i:= 0 to 3600 do     MySeries.AddXY(i/(3600*24),5*sin(i/100)); end;  Scales are shown, but: 1. One X unit does not correspond to 1 sec, but to 3600*24 seconds, so I have to divide the X values. 2. Milliseconds are separated by a dot, instead of a comma, I wrote hh:mm:ss.ss by memory, maybe I did something wrong. ---------------------------------------------------------------------- wp · 2014-07-23 17:37 I must admit that I never fully understood what the TDateTimeIntervalChartSource does... Usually, when I have special formatting requirements for axis labels I create the labels manually in a TListChartSource, then I have full control. The code below, for example, places labels, according to your selection, every minute, 2 minutes, 5 minutes, etc. Code: [Select]const   ONE_MINUTE = 1.0/(24*60); type   TMinutesInterval = (mi1Min, mi2Min, mi5Min, mi10Min, mi15Min, mi20Min, mi30Min, mi60Min); const   Minutes: array[TMinutesInterval] of Word = (1, 2, 5, 10, 15, 20,30, 60); procedure PopulateTimeSource(AMin, AMax: TTime; MinutesInterval: TMinutesInterval;   AListSource: TListChartsource); var   t, dt: TTime;   timeStr: String;   hr, min, sec, ms: Word; begin   t := AMin;   DecodeTime(t, hr, min, sec, ms);   dt := ONE_MINUTE * Minutes[MinutesInterval];   t := EncodeTime(hr, round(trunc(min/dt)*dt), 0, 0);   AListSource.Clear;   repeat     timeStr := FormatDateTime('hh:nn:ss,zzz', t);     AListSource.Add(t, t, timeStr);     t := t + dt;   until (t > AMax) and (abs(t-AMax)>ONE_MINUTE/60); end; procedure TForm1.Button1Click(Sender: TObject); var   MyChart: TChart;   MySeries: TLineSeries;   MyScaleXMarks: TListChartSource;   i:integer; begin   MyChart:= TChart.Create(Self);   MyChart.Parent:= Self;   MyChart.Align := alClient;   MyScaleXMarks := TListChartSource.Create(self);   MyChart.BottomAxis.Marks.Style := smsLabel;   MyChart.BottomAxis.Marks.Source:=MyScaleXMarks;   MySeries:=TLineSeries.Create (MyChart);   MyChart.AddSeries(MySeries);   for i:= 0 to 10000 do     MySeries.AddXY(i/(3600*24),5*sin(i/100));   PopulateTimeSource(MySeries.GetXMin, MySeries.GetXMax, mi15Min, MyScaleXmarks); end;                                        The only - sometimes severe - drawback of this code is that the label interval does not change when you zoom. To get this you have to consider also the extent of the x axis and select the minute interval accordingly, for example in the OnMouseUp event of the Zoomtool: Code: [Select]procedure TForm1.ZoomToolAfterMouseUp(ATool: TChartTool;   APoint: TPoint); var   dt: double;   mi: TMinutesInterval;   MyChart: TChart; begin   MyChart := ATool.Chart;   dt := (MyChart.LogicalExtent.b.x - Mychart.LogicalExtent.a.x) * 24;  // hours   if dt > 5 then     mi := mi60Min   else if dt > 2 then     mi := mi30Min   else if dt > 1 then     mi := mi15Min   else if dt > 0.5 then     mi := mi5min   else     mi := mi1min;   PopulateTimeSource(MyChart.LogicalExtent.a.x, MyChart.LogicalExtent.b.x, mi,     MyChart.BottomAxis.Marks.Source as TListChartSource); end;    Your specific question regarding the decimal point: No - the decimal point seems to be hardcoded (one thing I could change some time...). In the FormatDateTime code you can specifiy the decimal separator freely. But your symbol for the milliseconds is not correct: use a "z" instead of an "s" (http://www.freepascal.org/docs- html/rtl/sysutils/formatchars.html). ---------------------------------------------------------------------- CM630 · 2014-07-29 10:43 Thanks, I will try your code when I finish some tasks, that have come to be more urgent. Quote from: wp on July 23, 2014, 07:37:19 pm Usually, when I have special formatting requirements for axis labels I create the labels manually in a TListChartSource, then I have full control. The code below, for example, places labels, according to your selection, every minute, 2 minutes, 5 minutes, etc. ... The only - sometimes severe - drawback of this code is that the label interval does not change when you zoom. To get this you have to consider also the extent of the x axis and select the minute interval accordingly, for example in the OnMouseUp event of the Zoomtool:  It might be a drawback, but it might be an advantage.  Quote from: wp on July 23, 2014, 07:37:19 pm Your specific question regarding the decimal point: No - the decimal point seems to be hardcoded (one thing I could change some time...). In the FormatDateTime code you can specifiy the decimal separator freely. But your symbol for the milliseconds is not correct: use a "z" instead of an "s" (http://www.freepascal.org/docs- html/rtl/sysutils/formatchars.html). Oddly, my windows occurred to have switched itself to decimal delimer dot That is why I have dots on the left axis. As far for the bottom axis, I set MyScaleXMarks.DateTimeFormat:='hh:mm:ss,zz';