Labels lazarus / 55-TAChart ---------------------------------------------------------------------- fpcoder · 2013-08-29 03:56 If I have 100 points in a lineseries and want to display a label (string text) for only every seventh of them, how to do that? ---------------------------------------------------------------------- Windsurfer · 2013-08-29 06:56 Try: N := 100; for I := 1 to N mod 7 do; begin end; ---------------------------------------------------------------------- wp · 2013-08-29 07:38 The Add* methods of the series have an optional parameter to specify the text attached as a mark to the data point. Write code to set this text only for each seventh data point. And don't forget to set the series' Marks.Style to smsLabel in order to show these strings as labels. Here is some sample code: Code: [Select]procedure TForm1.FormCreate(Sender: TObject); var   i: Integer;   s: String;   y: Double; begin   for i:=0 to 100 do begin     y := Random;  // or whatever...     if i mod 7 = 0 then       s := Format('%.2f', [y])     else       s := '';     Chart1LineSeries1.Add(y, s);   end; end; ---------------------------------------------------------------------- fpcoder · 2013-08-29 15:40 That was also interesting, thank you. But unfortunately I confused Labels with Marks on the Axis, so I try again. It is the Marks on axes I want to work with, particularly the BottomAxis. How to: Add points that *never* have marks on the BottomAxis, but are still part of the graph. And then add more points to the same series that *can* be shown in the BottomAxis. As you see, I want control over what and when soemthing is shown on the BottomAxis. So lets say again that every 7th point should have a Mark with a text label on the bottom axis. And when you resize the chart, no other marks show up than the ones that are already there. ---------------------------------------------------------------------- wp · 2013-08-29 16:21 To some degree, you can control the location of axis labels by means of the Intervals property of the axis. Play with these parameters to see whether you can achieve the desired effect. But these automatically placed labels have a life of their own... You requirement looks to me as if you need a separate ChartSource for the axis marks. This makes sure that labels are drawn only at the positions pre-defined in the ChartSource. However, you should disable zooming because at some zooming level you will not see any axis marks any longer. To avoid double-storage, don't use the Series.Add* methods, but store your data in a separate TListChartSource -- there's an Add method as well. As in the previous posting, add the label only to every 7th data point. Something like this: Code: [Select]var   i: Integer;   x,y: Double; begin   for i:=0 to 100 do begin     x := i;     y := Random;  // or whatever...     if i mod 7 = 0 then       s := Format('%.2f', [x])     else       s := '';     ListChartSource1.Add(x,y, s);   end; Then link this source to the corresponding property of the series and to that of the Axis.Marks. Set the Axis.Marks.Style to smsLabel. Code: [Select]  Chart1LineSeries1.Source := ListChartSource1;   Chart1.BottomAxis.Marks.Source := ListChartSource1;   Chart1.BottomAxis.Marks.Style := smsLabel; Untested - no guarantee... ---------------------------------------------------------------------- fpcoder · 2013-08-29 23:19 I tried your suggestions with ListChartSource. Big improvement, thanks wp! There are a few questions though. As you hinted, automatically placed labels seem to be unpredictable. Irregular distances between marks on the BottomAxis could appear. I put all BottomAxis.Intervals.Options to false. So now there is always an even space between labels on the axis. But there is room for some improvement, because when the chart is resized to much smaller size, labels can become crowded and overlap eachother. So OverlapPolicy := HideNeighbour doesnt seem to work after that.  Labels get irregular and can disappear. Maybe OverlapPolicy is taking into account also all those labels *without* content, and thats why those few with content can become hidden? Maybe every second label with content should be removed and then it would work with automatic placement? But then TAChart OverlapPolicy has to check labels for content before adjusting the overlap. Or maybe there is some other smart solution to this. Ah, yes, the chart now shows all too many gridlines, one per point in the series. Axis.Intervals.MaxLength / MinLength makes the labels disappear and become irregular so I disabled that and made gridlines invisible for now. I would like to have a BottomAxis gridline for each label. ---------------------------------------------------------------------- wp · 2013-08-30 09:11 Still don't understand exactly what you want. In my eyes your demo runs fine with the default settings (no change with Intervals, no Marks.Source, Marks.Style = smsvalue). Could you post a screenshot of some other program to demonstrate what you want. Having non-overlapping axis marks for every 7th of 100 data points appear impossible to me, at least for reasonable chart sizes; in this sense, my previous posting was non-sense. Or maybe you mean that you want 6 minor ticks between two major ticks labelled by marks? In this case, you would leave all axis settings at their default (Intervals.Options = [aipUseMaxLength,aipUseMinLength,aipUseNiceSteps], Marks.Source = nil, Marks.Style = smsValue). Click on "Minors", then "Add". Select the new entry in the list editor, set its Intervals.Count = 6, turn off all Options except for aipUseCount, Grid.Visible = false to turn of the minor grid. ---------------------------------------------------------------------- fpcoder · 2013-08-30 16:45 Quote from: wp on August 30, 2013, 11:11:51 amStill don't understand exactly what you want. In my eyes your demo runs fine with the default settings. Yes, it just needed some polishing. 1) Gridlines for the BottomAxis only if there is a label for the point. 2) Resize of the chart without overlapping axis marks, even when the chart gets smaller. But you pointed me in the right direction and its fixed now. At least I think so: Assigning a DateTimeIntervalSource to BottomAxis.Marks.Source and setting its Params.Options all to false, except UseCount produced the wanted behaviour. From the beginning I didnt understand that there was an difference for TAChart between displaying datetime data and just an index number on the BottomAxis. So finding DateTimeIntervalSource made a difference, just as using Count for Intervals. DateTimeIntervalSource.Params.Count should be set to a number that fits within the chart. Now the chart can be resized without overlapping labels. Data comes from a ListChartSource assigned to LineSeries.source. So it was news for me that ListChartSource and DateTimeIntervalSource could be used together like this. It seems there is much to understand about controlling labels on Axes. I'll tinker some more and later I can make another wiki tutorial or demo about it.