Page 1 of 1
"Carpet Plot" Labels
Posted: Thu Nov 03, 2022 11:28 am
by 16592554
I am trying to build a "Carpet Plot" of 2 intersecting groups of "Iso Lines" with labels on the lines showing the Iso value of the line. As the data grid is based on the 2 Iso parameters, I can't plot them as contours in TeeChart, so I have created a grid of XY Line series. I could not find any way to add a single label to a line series, so I created an invisible grid of single point Point Series and used the point label to display the line Iso value. The problem with this approach was that the point series labels hijacked the bottom axis and I had to tie them to an invisible top axis. See attached screen shots.
My questions are:
Is there a better way to create the Carpet Plot?
Is there a way to add a label to an arbitrary position (preferably in XY coordinates) on a Line Series?
Is there a way to add labels to a series point that does not mess up the XY axis?
- Layout as required
- 2022-11-03 09_36_19-Window.png (45.29 KiB) Viewed 7984 times
- Messed up X Axis
- 2022-11-03 09_54_20-Window.png (41.9 KiB) Viewed 7984 times
Re: "Carpet Plot" Labels
Posted: Mon Nov 07, 2022 3:04 pm
by yeray
Hello,
You could use
TAnnotationTool
s to draw your texts. Ie:
Code: Select all
uses Series, TeeTools;
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
Chart1.View3D:=False;
Chart1.Gradient.Visible:=False;
Chart1.Color:=clWhite;
Chart1.Walls.Back.Gradient.Visible:=False;
Chart1.Walls.Back.Color:=clWhite;
Chart1.AddSeries(TLineSeries).FillSampleValues;
Chart1.Draw;
with TAnnotationTool(Chart1.Tools.Add(TAnnotationTool)) do
begin
Text:='Text for ValueIndex 5';
Left:=Chart1[0].CalcXPos(5);
Top:=Chart1[0].CalcYPos(5);
Shape.Transparent:=True;
end;
end;
Re: "Carpet Plot" Labels
Posted: Tue Nov 08, 2022 11:54 am
by 16592554
Is there a best practice for managing Annotations created at run-time as in your example? The main problem I am having is coping with repaints/rebuilds creating multiple copies of the same thing. The annotations don't seem to have a fixed name and selective deletion from the Tools array would rely on knowing the array position. The Annotation Text is not generally known at design time, so I can't use that without keeping a shadow copy of text somewhere. Or maybe I need to keep a local pointer to the annotation? It would be much easier if I could delete/remove in design-time code with a known name.
Re: "Carpet Plot" Labels
Posted: Tue Nov 08, 2022 1:11 pm
by yeray
Hello,
Indeed, you could store the annotations in variables, or in an array. Or you could just use the
Tools
array.
Find here an example showing how to add an annotation tool every time the chart is clicked and how to remove the annotation that is right-clicked:
Code: Select all
uses Series, TeeTools;
var mouseDownPos: TPoint;
procedure TForm1.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
mouseDownPos:=Point(X,Y);
end;
procedure TForm1.Chart1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var i: Integer;
annotation: TAnnotationTool;
begin
if (mouseDownPos.X = X) and (mouseDownPos.Y = Y) then
if Button = mbRight then
begin
for i:=Chart1.Tools.Count-1 downto 0 do
if Chart1.Tools[i] is TAnnotationTool then
begin
annotation:=TAnnotationTool(Chart1.Tools[i]);
if annotation.Clicked(X, Y) then
begin
Chart1.Tools.Delete(Chart1.Tools.IndexOf(annotation));
Chart1.Draw;
Exit;
end;
end;
end
else
if Button = mbLeft then
with TAnnotationTool(Chart1.Tools.Add(TAnnotationTool)) do
begin
Text:='Annotation at X: ' + IntToStr(X) + ', Y: ' + IntToStr(Y);
Left:=X;
Top:=Y;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
Chart1.View3D:=False;
Chart1.Gradient.Visible:=False;
Chart1.Color:=clWhite;
Chart1.Walls.Back.Gradient.Visible:=False;
Chart1.Walls.Back.Color:=clWhite;
Chart1.Legend.Hide;
Chart1.AddSeries(TLineSeries).FillSampleValues;
end;
Re: "Carpet Plot" Labels
Posted: Tue Nov 08, 2022 2:14 pm
by 16592554
Thanks, but it isn't really what I need. I am now thinking of using the component Tag property to mark sets of annotations for deletion, which should work. But in some cases it would still be better to have a fixed annotation "Name" available rather than having to store a link to the annotation so that I can access it directly for edit/deletion. Is it possible to add this feature?
Re: "Carpet Plot" Labels
Posted: Wed Nov 09, 2022 12:14 pm
by yeray
Hello,
Since the
TAnnotationTool
is a
TComponent
, it already has a
Name
property you can use. Ie:
Code: Select all
uses TeeTools;
procedure TForm1.BDeleteCheckedClick(Sender: TObject);
var i, j: Integer;
begin
for i:=CheckListBox1.Items.Count-1 downto 0 do
if CheckListBox1.Checked[i] then
for j:=Chart1.Tools.Count-1 downto 0 do
if Chart1.Tools[j].Name=CheckListBox1.Items[i] then
begin
Chart1.Tools.Delete(j);
CheckListBox1.Items.Delete(i);
break;
end;
Chart1.Draw;
end;
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
for i:=0 to 9 do
begin
with TAnnotationTool(Chart1.Tools.Add(TAnnotationTool)) do
begin
Name:='Annotation'+IntToStr(i);
Text:='Annotation'+IntToStr(i);
Left:=20+(i div 5)*80;
Top:=20+(i mod 5)*24;
end;
CheckListBox1.Items.Add(Chart1.Tools[i].Name);
end;
end;