labels for marks
labels for marks
What is the best way to position the labels for point marks so that the string is centered at the same height as the mark and the left end of the string is just a little to the right of the mark? I have been trying to do the computations in pixels and then convert to user units but that seems like too much work for this simple (?) task.
Re: labels for marks
Hello,
Note there are several LabelStyles you can try. Ie smsLabelValue:
If they don't fit your needs and you still want to draw the label next to the mark, you can use TAnnotationTools. Ie:
Note there are several LabelStyles you can try. Ie smsLabelValue:
Code: Select all
uses Series;
procedure TForm1.FormCreate(Sender: TObject);
var i : Integer;
const nPoints = 5;
myLabels : array [0..nPoints-1] of string = ('Cars', 'Phones', 'Tables', 'Monitors', 'Lamps');
begin
with Chart1.AddSeries(TPointSeries) as TPointSeries do
begin
for i:=0 to nPoints-1 do
Add(50+random*50, myLabels[i]);
Marks.Visible:=True;
Marks.Style:=smsLabelValue;
end;
end;
Code: Select all
uses Series, TeeTools;
var annotations: array of TAnnotationTool;
procedure TForm1.FormCreate(Sender: TObject);
var i : Integer;
const nPoints = 5;
myLabels : array [0..nPoints-1] of string = ('Cars', 'Phones', 'Tables', 'Monitors', 'Lamps');
begin
SetLength(annotations, nPoints);
with Chart1.AddSeries(TPointSeries) as TPointSeries do
begin
for i:=0 to nPoints-1 do
begin
annotations[i]:=Chart1.Tools.Add(TAnnotationTool) as TAnnotationTool;
annotations[i].Text:=myLabels[i];
Add(50+random*50);
end;
Marks.Visible:=True;
Marks.Style:=smsValue;
OnGetMarkText:=SeriesGetMarkText;
end;
end;
procedure TForm1.SeriesGetMarkText(Sender: TChartSeries; ValueIndex: Integer; var MarkText: string);
begin
if (ValueIndex>=0) and (ValueIndex<Chart1[0].Count) and (Sender.Marks.Positions[ValueIndex] <> nil) then
begin
annotations[ValueIndex].Left:=Sender.Marks.Positions[ValueIndex].LeftTop.X+Sender.Marks.Positions[ValueIndex].Width;
annotations[ValueIndex].Top:=Sender.Marks.Positions[ValueIndex].LeftTop.Y;
end;
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: labels for marks
Thanks but this does not yet give me what I want. I have attached a screenshot below.
Two problems. First, It puts the labels to the right of the values that label each mark. I need the labels to be to the right of each point not the labels for the marks.
Second, when I run the program the annotations are initially all on top of each other at the top left of the chart until I move the mouse over one of the points. They then snap to the positions shown in the screenshot. Do I need to set some options for the TChart? My form just has a TChart component dropped onto it and then set to align with the client. No other changes to the form.
My code (copied from your second example) is given below.
Thanks for your help.
Two problems. First, It puts the labels to the right of the values that label each mark. I need the labels to be to the right of each point not the labels for the marks.
Second, when I run the program the annotations are initially all on top of each other at the top left of the chart until I move the mouse over one of the points. They then snap to the positions shown in the screenshot. Do I need to set some options for the TChart? My form just has a TChart component dropped onto it and then set to align with the client. No other changes to the form.
My code (copied from your second example) is given below.
Code: Select all
unit testTeeu;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VclTee.TeeGDIPlus, VclTee.TeEngine,
Vcl.ExtCtrls, VclTee.TeeProcs, VclTee.Chart, VclTee.Series, VclTee.TeeTools;
type
TForm1 = class(TForm)
Chart1: TChart;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
var
annotations: array of TAnnotationTool;
procedure SeriesGetMarkText(Sender: TChartSeries; ValueIndex: Integer;
var MarkText: string);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
const
nPoints = 5;
myLabels: array [0 .. nPoints - 1] of string = ('Cars', 'Phones', 'Tables',
'Monitors', 'Lamps');
begin
SetLength(annotations, nPoints);
with Chart1.AddSeries(TPointSeries) as TPointSeries do
begin
for i := 0 to nPoints - 1 do
begin
annotations[i] := Chart1.Tools.Add(TAnnotationTool) as TAnnotationTool;
annotations[i].Text := myLabels[i];
Add(50 + random * 50);
end;
Marks.Visible := True;
Marks.Style := smsValue;
OnGetMarkText := SeriesGetMarkText;
end;
end;
procedure TForm1.SeriesGetMarkText(Sender: TChartSeries; ValueIndex: Integer;
var MarkText: string);
begin
if (ValueIndex >= 0) and (ValueIndex < Chart1[0].Count) and
(Sender.Marks.Positions[ValueIndex] <> nil) then
begin
annotations[ValueIndex].Left := Sender.Marks.Positions[ValueIndex].LeftTop.X
+ Sender.Marks.Positions[ValueIndex].Width;
annotations[ValueIndex].Top := Sender.Marks.Positions[ValueIndex].LeftTop.Y;
end;
end;
end.
- Attachments
-
- Screen Shot 10-26-17 at 11.26 AM.PNG (18.23 KiB) Viewed 13261 times
Re: labels for marks
Hello,
An image could help to clarify the goal.
I'm not sure to understand if you want to also show the default marks or not. If you don't want to show the default marks, you can just modify their text and position without needing to use TAnnotationTools.JimR wrote:First, It puts the labels to the right of the values that label each mark. I need the labels to be to the right of each point not the labels for the marks.
An image could help to clarify the goal.
It also fails to correctly reposition the annotations when you zoom and unzoom. this happens because the TAnnotationTools are drawn earlier than the series in the drawing center; so the annotation positions that are calculated in the SeriesGetMarkText will apply at the next repaint. To solve it, you can force a chart repaint when these events happen. Ie:JimR wrote:Second, when I run the program the annotations are initially all on top of each other at the top left of the chart until I move the mouse over one of the points. They then snap to the positions shown in the screenshot. Do I need to set some options for the TChart? My form just has a TChart component dropped onto it and then set to align with the client. No other changes to the form.
Code: Select all
procedure TForm1.Chart1UndoZoom(Sender: TObject);
begin
Chart1.Draw;
end;
procedure TForm1.Chart1Zoom(Sender: TObject);
begin
Chart1.Draw;
end;
procedure TForm1.FormCreate(Sender: TObject);
//...
Chart1.Draw;
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: labels for marks
Right, I don't want to display the marks - I just want to show their labels at the ends of some arrow series.
The default seems to be to plot them centered above where the mark would be. I need them centered vertically but plotted to the right of where the mark would be (though for some plots I would like them to the left and right justified up to where the mark would be). For example: Xaaaaaa or aaaaaX (where X is the mark and aaaaa is some text for the label).
I could not find position constants for left, right, center, etc. for the labels.
The annotation option seems more complicated as I believe I would need to calculate positions in pixels and redraw after any zoom etc. (Is that correct?)
Thanks
The default seems to be to plot them centered above where the mark would be. I need them centered vertically but plotted to the right of where the mark would be (though for some plots I would like them to the left and right justified up to where the mark would be). For example: Xaaaaaa or aaaaaX (where X is the mark and aaaaa is some text for the label).
I could not find position constants for left, right, center, etc. for the labels.
The annotation option seems more complicated as I believe I would need to calculate positions in pixels and redraw after any zoom etc. (Is that correct?)
Thanks
Re: labels for marks
Hello,
Note you have to recalculate the positions after every zoom/scroll, exactly the same issue as with the TAnnotationTools option.
If you still find problems with it, please try to show a screenshot/mockup showing the expected result.
You can modify the Marks positions by accessing the Marks.Positions array. You can find an example of how to modify these positions here.JimR wrote:Right, I don't want to display the marks - I just want to show their labels at the ends of some arrow series.
The default seems to be to plot them centered above where the mark would be. I need them centered vertically but plotted to the right of where the mark would be (though for some plots I would like them to the left and right justified up to where the mark would be). For example: Xaaaaaa or aaaaaX (where X is the mark and aaaaa is some text for the label).
I could not find position constants for left, right, center, etc. for the labels.
The annotation option seems more complicated as I believe I would need to calculate positions in pixels and redraw after any zoom etc. (Is that correct?)
Note you have to recalculate the positions after every zoom/scroll, exactly the same issue as with the TAnnotationTools option.
If you still find problems with it, please try to show a screenshot/mockup showing the expected result.
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |