Page 1 of 1
axis title overlap
Posted: Fri Sep 30, 2005 2:46 am
by 9338026
hello.
I have my axis title size set to zero, so the axis titles should not overlap the labels. However, this still happens sometimes. Is this because I set custom label text on the onGetAxisLabel event? If so, is there any way to activate automatic spacing in this case?
Posted: Fri Sep 30, 2005 7:59 am
by narcis
Hello David,
Could you please post an example we can run "as-is" to reproduce the problem here and help you finding a solution for it? You can post your files at [url]news://
www.steema.net/steema.public.attachments[/url] newsgroup.
Thanks in advance.
Posted: Sun Oct 02, 2005 8:31 pm
by 9338026
Narcis,
Done, the tile of the subject is bad labels. Please let me know if there is any way I can let them not overlay. I don't want to have to have my users manually adjust the offset, they should just never overlap.
Thanks,
dave
Posted: Mon Oct 03, 2005 7:56 am
by narcis
Hi Dave,
Thanks for the example application. It has an easy solution which is customizing labels size. Using the code below on your project works fine.
Code: Select all
procedure TForm1.FormCreate(Sender: TObject);
var
cntr: Integer;
begin
for cntr:=0 to 20 do
series1.addXY(cntr*1000,cntr*50);
Chart1.Axes.Left.LabelsSize:=50;
end;
Posted: Mon Oct 03, 2005 3:34 pm
by 9338026
Hello Narcis,
Thank you for your prompt reply. I found the labelSize property myself of course. The question is, how do I know WHAT to make the label size. In my application, I have no idea what the data is going to be and what the axis labels are going to be displayed (its quite a complicated algorithm in the onGetAxisLabel event).
so, somehow I need to get all of the axis labels and then figure out what the longest one will be, then make the labelSize an appropriate value. This is what I assume you do normally, when labelSize is 0, but you don't do it when I supply custom labels.
In an idea world, you would gather up all the custom labels that I am sending to you, and then if the labelSize is 0, do what you normally do, which is automatically figure out the size.
So my question is:
1. How do I plug in to TChart to figure out what the longest label is?
2. Once I know what the longest label is, how do I convert that to an appropriate .LabelSize value?
Thank you for your help.
Posted: Mon Oct 03, 2005 3:59 pm
by narcis
Hi Dave,
Using the code below works fine for me.
Code: Select all
procedure TForm1.Chart1GetAxisLabel(Sender: TChartAxis;
Series: TChartSeries; ValueIndex: Integer; var LabelText: String);
begin
if ((Sender=Chart1.Axes.Left) and
(Chart1.Axes.Left.LabelsSize < Length(LabelText)*5)) then
Chart1.Axes.Left.LabelsSize:=Length(LabelText)*5;
end;
Posted: Mon Oct 03, 2005 4:09 pm
by 9338026
Hi Narcis,
Ok, I see the theory. However, how would I account for different font sizes (my users scan switch label font size). Obviously, multiplying by 5 is not going to work in all cases.
Is the labelSize equal to pixels, i.e. if I measure that canvas.textextent of the labelText then use that, will I be okay?
Posted: Mon Oct 03, 2005 4:16 pm
by narcis
Hi Dave,
Yes, LabelsSize is in pixels. To have a more accurate formula, considering font size, you can add font size as a variable:
Posted: Mon Oct 03, 2005 4:26 pm
by 9338026
Thank you very much for your prompt and detailed answers.
Posted: Mon Oct 24, 2005 11:00 pm
by 9338026
Hello Narcis,
As I implement this more, I realize this solution does not work. During the course of the drawing, as I keep changing the labelSize based upon the "latest" custom axis label, the chart repaints and flickers. It seems to paint once with the original labelSize and then again with the updated one.
Tracing through your code, I seem to have found something strange. When calculating the automatic label size, you have the following function
Function MaxLabelsValueWidth:Integer;
var tmp : Double;
tmpA : Double;
tmpB : Double;
OldGetAxisLabel : TAxisOnGetLabel;
tmpNum : Integer;
begin
if (IsDateTime and FExactDateTime) or RoundFirstLabel then
begin
tmp:=CalcIncrement;
tmpA:=tmp*Int(IMinimum/tmp);
tmpB:=tmp*Int(IMaximum/tmp);
end
else
begin
tmpA:=IMinimum;
tmpB:=IMaximum;
end;
With ParentChart do
begin
OldGetAxisLabel:=FOnGetAxisLabel;
FOnGetAxisLabel:=nil;
With Canvas do
result:=TextWidth(' ')+
Math.Max(MultiLineTextWidth(LabelValue(tmpA),tmpNum),
MultiLineTextWidth(LabelValue(tmpB),tmpNum));
FOnGetAxisLabel:=OldGetAxisLabel;
end;
end;
For some reason, you set the FonGetAxisLabel to nil. Thus, the LabelValue method returns the incorrect value in my case, because I do have an onGetAxisLabel method. The labelValue method returns just the default axis label, which is totally incorrect, because you have set the FOnGetAxisLabel to nil.
Adjusting the axis labels as you are drawing causes a flicker, which makes sense since the labelSize is being updated as drawing continues. it seems that you have the infrastructure for the correct behavious, i.e. if the labelSize is zero you get the maximum label size and use that. However, disconnecting the onGetAxisLabel is making that not work in my case. Is there a reason why you are doing this? Is there any danger in not setting the OnGetAxisLabel to nil?