Page 1 of 1

CustomAxes behavior when LeftAxis is not visible

Posted: Thu May 07, 2009 11:38 am
by 9335230
Hi,

I have lived several years with the weird behaviour of vertical custom axes positioning when LeftAxis is hidden. The last version I tried is 7.12. I would like to know if this issue is fixed in later versions. If not, ¿there's any workaround you recommend me?

Thanks in advance!

Posted: Thu May 07, 2009 11:57 am
by yeray
Hi beetle,

Could you please explain us what is the exact problem? Or even better, could you please post here the topic where it was discussed (if it was)?

Thanks in advance.

Posted: Thu May 07, 2009 12:33 pm
by 9335230
Hi,

I thought you would know what I'm talking about :)
When using custom axes (at least with vertical axes), if you hide LeftAxis, the positioning of all vertical custom axes is not good; probably you won't see their labels completely. It seems that the positioning of all customAxes depends of the position of the main axes (Left, Bottom,...).
Here the simple steps for reproducing this issue at design time or running time:

- Create a chart.
- Create one custom axis (vertical)
- Create 2 TLineSeries. Set vertAxis to the custom axis for one of the two series . (FillSampleValues for both series if needed)
- Hide the LeftAxis
- As a result, the custom axis will move to the left and the labels will be trimmed.

if you don't see what I'm talking about, I'll try to explain it in a better way.

Thanks!

Posted: Thu May 07, 2009 12:39 pm
by 9335230
I forgot earlier... there's no need to hide the LeftAxis, the same issue appears if labels custom axis width is quite wider than the LeftAxis's.

Thanks!!

Posted: Thu May 07, 2009 3:17 pm
by yeray
Hi beetle,

The problem here is that for the default axes there is a offset applied to the chart margin but not for the custom axes. Here you have an example of how you could calculate the correct margin depending on the shown labels:

Code: Select all

uses series, Math;

procedure TForm1.FormCreate(Sender: TObject);
var i, maxLabelsLeftWidth, maxLabelsRightWidth: Integer;
begin
  Chart1.View3D := false;
  Chart1.Legend.Visible := false;
  for i := 0 to 5 do
  begin
    Chart1.AddSeries(TLineSeries.Create(self));
    Chart1[i].FillSampleValues(50);
    Chart1.CustomAxes.Add;
    Chart1[i].CustomVertAxis := Chart1.CustomAxes[i];
    if i mod 2 = 0 then
      Chart1.CustomAxes[i].OtherSide := true;
  end;

  Chart1.Draw;

  maxLabelsLeftWidth := 0;
  maxLabelsRightWidth := 0;
  for i:=0 to Chart1.SeriesCount-1 do
  begin
    if Chart1[i].GetVertAxis.OtherSide then
      maxLabelsRightWidth := Max(Chart1[i].GetVertAxis.MaxLabelsWidth,maxLabelsRightWidth)
    else
      maxLabelsLeftWidth := Max(Chart1[i].GetVertAxis.MaxLabelsWidth,maxLabelsLeftWidth);
  end;

  Chart1.MarginUnits := muPixels;
  Chart1.MarginLeft := maxLabelsLeftWidth + 5;
  Chart1.MarginRight := maxLabelsRightWidth + 5;

  Caption := 'maxLabelsWidth Left: ' + IntToStr(maxLabelsLeftWidth) + '  Right: ' + IntToStr(maxLabelsRightWidth)
end;

Posted: Fri May 08, 2009 1:00 pm
by 9335230
Thanks Yeray. My workaround is similar to yours, but both are not good at all . :lol:
Your code has several problems:
1) Margin offset is calculated based on labels, but axes can have its title.
2) Changing MarginUnits affects to all default axes (no problem if using muPixels from the beginning)
3) and the most important issue is the need of 2 chart repaint to achive the adjustment, (a very important issue if chart has a lot of points and series)

I just wrote some improved code to fix this, but I still got to do 2 repaint.
It would be great if you could tell me the piece of source code where the default axes calculate their margin offset you said (I have Tee chart source code and I could modify it).

Thanks!

Posted: Fri May 08, 2009 1:34 pm
by yeray
Hi beetle,

1. Here there is a function from another user that could help you to avoid it.

2. Yes, you should decide to work in pixels or in percentages. But note that with percentages you'll need to do some conversions.

3. Yes, to calculate positions relative to the axis labels, you need a first repaint of the chart. The only thing I can think for now is to try to improve the speed of these repaints following the tips from the Real-time Charting article.