TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
-
Narcís
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
-
Contact:
Post
by Narcís » Thu Mar 27, 2008 9:43 am
Hi Dominik,
Thanks for the information, I understand your problem.
In that case you could try using a temporary chart with no parent for retrieving original chart width and height, for example:
Code: Select all
procedure TForm16.Button2Click(Sender: TObject);
var tmpChart: TChart;
begin
Form16.Width := 640;
Form16.Height := 480;
tmpChart:=TChart.Create(self);
LoadChartFromFile(TCustomChart(tmpChart), 'Test.tee');
tmpWidth:=tmpChart.Width;
tmpHeight:=tmpChart.Height;
tmpChart.Free;
LoadChartFromFile(TCustomChart(Chart1), 'Test.tee');
SetAnnotationPosition(Chart1.Tools.Items[0] as TRectangleTool);
end;
I've also sent you the project modified.
-
moelski
- Advanced
- Posts: 212
- Joined: Mon Apr 23, 2007 12:00 am
- Location: Germany
-
Contact:
Post
by moelski » Thu Mar 27, 2008 2:06 pm
Hi Narcis,
ok we come closer and closer
But there is still a small problem ...
You used this code:
Code: Select all
tmpChart:=TChart.Create(self);
LoadChartFromFile(TCustomChart(tmpChart), 'Test.tee');
tmpWidth:=tmpChart.Width;
tmpHeight:=tmpChart.Height;
tmpChart.Free;
But width and height includes the axis. So what we need is something like this:
Code: Select all
tmpChart:=TChart.Create(self);
LoadChartFromFile(TCustomChart(tmpChart), 'Test.tee');
tmpWidth := tmpChart.chartRect.Right - tmpChart.chartRect.Left; //tmpChart.Width;
tmpHeight := tmpChart.chartRect.Bottom - tmpChart.chartRect.Top;
tmpChart.Free;
But if I debug this code I get 0 for tmpWidth and tmpHeight.
And if I use your code, the callout is not at the correct position after loading in a resized chart.
-
Narcís
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
-
Contact:
Post
by Narcís » Thu Mar 27, 2008 4:00 pm
Hi Dominik,
Ok, in that case you need to draw tmpChart and use tmpWidht and tmpHeight like this:
Code: Select all
procedure TForm16.Button4Click(Sender: TObject);
begin
SaveChartToFile(Chart1, 'Test.tee', True, True);
tmpWidth := Chart1.chartRect.Right - Chart1.chartRect.Left; //tmpChart.Width;
tmpHeight := Chart1.chartRect.Bottom - Chart1.chartRect.Top;
end;
procedure TForm16.Button2Click(Sender: TObject);
var tmpChart: TChart;
begin
Form16.Width := 640;
Form16.Height := 480;
tmpChart:=TChart.Create(self);
LoadChartFromFile(TCustomChart(tmpChart), 'Test.tee');
tmpChart.Parent:=self;
tmpChart.Draw;
tmpChart.Parent:=nil;
tmpWidth := tmpChart.chartRect.Right - tmpChart.chartRect.Left; //tmpChart.Width;
tmpHeight := tmpChart.chartRect.Bottom - tmpChart.chartRect.Top;
tmpChart.Free;
LoadChartFromFile(TCustomChart(Chart1), 'Test.tee');
SetAnnotationPosition(Chart1.Tools.Items[0] as TRectangleTool);
end;
And then implement SetAnnotationPosition this way:
Code: Select all
procedure TForm16.SetAnnotationPosition(Annotacion: TRectangleTool);
var w,h: Double;
RectWidth, RectHeight: Integer;
begin
Chart1.Draw;
Annotacion.Shape.Left := Chart1.ChartRect.Left + (150 - Chart1.Left);
Annotacion.Shape.Top := Chart1.ChartRect.Top + (100 - Chart1.Top);
if tmpWidth=0 then
Annotacion.Callout.XPosition := Chart1.ChartRect.Left + (250 - Chart1.Left)
else
begin
RectWidth := Chart1.ChartRect.Right - Chart1.ChartRect.Left;
w := RectWidth / tmpWidth;
Annotacion.Callout.XPosition := Round(Annotacion.Callout.XPosition * w);
end;
if tmpHeight=0 then
Annotacion.Callout.YPosition := Chart1.ChartRect.Top + (180 - Chart1.Top)
else
begin
RectHeight := Chart1.ChartRect.Bottom - Chart1.ChartRect.Top;
h:= RectHeight / tmpHeight;
Annotacion.Callout.YPosition := Round(Annotacion.Callout.YPosition * h);
end;
end;
-
moelski
- Advanced
- Posts: 212
- Joined: Mon Apr 23, 2007 12:00 am
- Location: Germany
-
Contact:
Post
by moelski » Thu Mar 27, 2008 8:03 pm
Hi Narcis,
ok the calculation of tmpWidth and tmpHeight works now. But I think there is still something wrong.
I uploaded the project t your server:
Received
CallOutPos After Load.zip Content Type application/x-zip-compressed Length 28741
Please have a look at the following two pictures. The first one is after creation and the second one is after resize and reload of the TEE file.
As you can see the annotation is not at the correct position. Do you have any idea what causes this problem and how we can get the X / Y position calculated correct?
-
Narcís
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
-
Contact:
Post
by Narcís » Fri Mar 28, 2008 8:33 am
Hi Dominik,
In your project you didn't change Button4 OnClick event implementation as I suggested in my last post. Please try using this:
Code: Select all
procedure TForm16.Button4Click(Sender: TObject);
begin
SaveChartToFile(Chart1, 'Test.tee', True, True);
//tmpWidth:=Chart1.Width;
//tmpHeight:=Chart1.Height;
tmpWidth := Chart1.chartRect.Right - Chart1.chartRect.Left;
tmpHeight := Chart1.chartRect.Bottom - Chart1.chartRect.Top;
end;
-
moelski
- Advanced
- Posts: 212
- Joined: Mon Apr 23, 2007 12:00 am
- Location: Germany
-
Contact:
Post
by moelski » Fri Mar 28, 2008 12:54 pm
Hi Narcis,
yes you are right.
But that button won´t be pressed if you restart the application and load the saved TEE file.
And if I use that code and don´t restart the appliaction the calculation is wrong, too.
Give it a try by doing the following steps:
1) Create Tool with Button 1
2) Save Tee
3) Clear
4) Load Tee
Now have a look where the callout is placed in X direction and keep it in mind. It should be between 13 and 14.
5) Resize the form Width and press Load Tee again
You will see that the X position has changed!
So the calculation isn´t correct at this time.
-
Narcís
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
-
Contact:
Post
by Narcís » Fri Mar 28, 2008 3:45 pm
Hi Dominik,
Ok, in that case you'll also need to update tmpWidth and tmpHeight in the chart OnResize event like this:
Code: Select all
procedure TForm16.Chart1Resize(Sender: TObject);
begin
if Chart1.Tools.Count>0 then
begin
tmpWidth := Chart1.chartRect.Right - Chart1.chartRect.Left;
tmpHeight := Chart1.chartRect.Bottom - Chart1.chartRect.Top;
SetAnnotationPosition(Chart1.Tools.Items[0] as TRectangleTool);
end;
end;
-
moelski
- Advanced
- Posts: 212
- Joined: Mon Apr 23, 2007 12:00 am
- Location: Germany
-
Contact:
Post
by moelski » Sat Mar 29, 2008 9:55 am
Hi Narcis,
the code you posted produces the same error as if I load the Tee file after resizing the chart.
I have created a small video (WMV Format). Please have a look and you will see the error.
http://www.logview.info/Downloads/CallOutError.zip
How can we fix this ? Maybe there is a better solution for get the CallOut stuff working ??
-
moelski
- Advanced
- Posts: 212
- Joined: Mon Apr 23, 2007 12:00 am
- Location: Germany
-
Contact:
Post
by moelski » Wed Apr 02, 2008 7:29 am
Hi Narcis,
no idea about this?
-
Narcís
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
-
Contact:
Post
by Narcís » Wed Apr 02, 2008 7:40 am
Hi Dominik,
This is because of only using ChartRect dimensions. When redimensioning the chart you'll also see that margins also change and therefore you are introducing a little error here. As I told you earlier on the thread, the only way to always have an exact position for the annotation tool is setting it to a relative value to a chart element, for example this:
Code: Select all
procedure TForm16.SetAnnotationPosition(Annotacion: TRectangleTool);
begin
Chart1.Draw;
Annotacion.Shape.Left := Chart1.ChartRect.Left + (150 - Chart1.Left);
Annotacion.Shape.Top := Chart1.ChartRect.Top + (100 - Chart1.Top);
Annotacion.Callout.XPosition := Chart1.Axes.Bottom.CalcXPosValue(35);
Annotacion.Callout.YPosition := Chart1.Axes.Left.CalcYPosValue(Chart1[0].YValues[3]);
end;
-
moelski
- Advanced
- Posts: 212
- Joined: Mon Apr 23, 2007 12:00 am
- Location: Germany
-
Contact:
Post
by moelski » Wed Apr 02, 2008 7:49 am
Hi Narcis,
Annotacion.Callout.XPosition := Chart1.Axes.Bottom.CalcXPosValue(35);
Annotacion.Callout.YPosition := Chart1.Axes.Left.CalcYPosValue(Chart1[0].YValues[3]);
Are these values the stored (within the TEE file) x / y values from the callout?
-
Narcís
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
-
Contact:
Post
by Narcís » Wed Apr 02, 2008 8:30 am
Hi Dominik,
No, what's stored in the tee file are the result of CalcXPosValue and CalcYPosValue calls.
-
moelski
- Advanced
- Posts: 212
- Joined: Mon Apr 23, 2007 12:00 am
- Location: Germany
-
Contact:
Post
by moelski » Wed Apr 02, 2008 9:42 am
Hi Narcis,
ok but that´s exactly my problem !
The Tee file stores a pixel Value.
And how should I get the values you are using here:
Annotacion.Callout.XPosition := Chart1.Axes.Bottom.CalcXPosValue(35);
Annotacion.Callout.YPosition := Chart1.Axes.Left.CalcYPosValue(Chart1[0].YValues[3]);
These values are not available after loading a Tee file.
-
Narcís
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
-
Contact:
Post
by Narcís » Wed Apr 02, 2008 9:58 am
Hi Dominik,
No, I'm afraid there's no other option than hard coding them.
Maybe an option would be settin annotation positions to the indexes you are using, for example, setting Annotation.Callout.XPosition:=35 before exporting the file and then using this value to retrieve corresponding axis position using CalcXPosValue after the tee file has been loaded, for example:
Code: Select all
Annotacion.Callout.XPosition := Chart1.Axes.Bottom.CalcXPosValue(Annotacion.Callout.XPosition);