Page 1 of 1
Custom vertical axis and LabelsSize
Posted: Mon Apr 30, 2007 7:21 pm
by 9234349
Hi,
I am finding that I can't get LabelsSize to work properly when using only custom axes.
For example, if you want to have three left axes, do you have to use the built-in left axis and then create two additional custom left axes?
I was trying to create three custom left axis and only use them, and it didn't work very well.
Regards,
Bill
Posted: Thu May 03, 2007 8:44 am
by yeray
Hi Bill,
I've made a project for a customer who requested something similar to you. Here's the code:
Code: Select all
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
const nSeries = 6;
begin
ComboBox1.Items.Clear;
ComboBox2.Items.Clear;
for i := 0 to nSeries-1 do
begin
Chart1.AddSeries(TLineSeries);
Chart1.CustomAxes.Add;
Chart1[i].CustomVertAxis := Chart1.CustomAxes.Items[i];
Chart1.CustomAxes.Items[i].Axis.Color := Chart1[i].Color;
Chart1.CustomAxes.Items[i].Grid.Visible := False;
ComboBox2.Items.Add('Series' + inttostr(i + 1));
Chart1[i].FillSampleValues(20000);
Chart1.CustomAxes.Items[i].PositionUnits := muPixels;
if ((i+1) mod 2 = 0) then
Chart1.CustomAxes.Items[i].OtherSide := True;
end;
Chart1.MarginUnits := muPixels;
ComboBox1.Items.Add('20000');
ComboBox1.Items.Add('5000');
ComboBox1.Items.Add('500');
ComboBox1.Items.Add('50');
ComboBox1.ItemIndex := 0;
ComboBox2.ItemIndex := 0;
CheckBox1.Checked := True;
CheckBox2.Checked := Chart1.CustomAxes.Items[0].OtherSide;
Chart1.Draw;
PlaceAxes();
end;
procedure TForm1.PlaceAxes(nSeries: Integer=0; NextXLeft: Integer=0; NextXRight: Integer=0; MargLeft: Integer=0; MargRight: Integer=0);
const extraPos = 12;
const extraMargin = 45;
begin
if Chart1[nSeries].Active then
begin
if Chart1.CustomAxes.Items[nSeries].OtherSide then
begin
Chart1.CustomAxes.Items[nSeries].PositionPercent := NextXRight;
NextXRight := NextXRight - Chart1.CustomAxes.Items[nSeries].MaxLabelsWidth - Chart1.CustomAxes.Items[nSeries].TickLength - extraPos;
MargRight := MargRight + extraMargin;
end
else
begin
Chart1.CustomAxes.Items[nSeries].PositionPercent := NextXLeft;
NextXLeft := NextXLeft - Chart1.CustomAxes.Items[nSeries].MaxLabelsWidth - Chart1.CustomAxes.Items[nSeries].TickLength - extraPos;
MargLeft := MargLeft + extraMargin;
end;
end;
Chart1.MarginLeft := MargLeft;
Chart1.MarginRight := MargRight;
nSeries := nSeries + 1;
if nSeries <= Chart1.SeriesCount - 1 then
begin
PlaceAxes(nSeries, NextXLeft, NextXRight, MargLeft, MargRight);
end;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
Chart1[ComboBox2.ItemIndex].Active := CheckBox1.Checked;
PlaceAxes();
end;
procedure TForm1.CheckBox2Click(Sender: TObject);
begin
Chart1.CustomAxes.Items[ComboBox2.ItemIndex].OtherSide := CheckBox2.Checked;
PlaceAxes();
end;
procedure TForm1.ComboBox2Change(Sender: TObject);
begin
CheckBox1.Checked := Chart1[ComboBox2.ItemIndex].Active;
CheckBox2.Checked := Chart1.CustomAxes.Items[ComboBox2.ItemIndex].OtherSide;
end;
procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
begin
for i := 0 to Chart1.SeriesCount-1 do
begin
Chart1[i].FillSampleValues(strtoint(ComboBox1.Text));
end;
PlaceAxes();
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Chart1.AddSeries(TLineSeries);
Chart1.CustomAxes.Add;
Chart1.CustomAxes.Items[Chart1.CustomAxes.Count-1].PositionUnits := muPixels;
Chart1[Chart1.SeriesCount-1].CustomVertAxis := Chart1.CustomAxes.Items[Chart1.CustomAxes.Count-1];
if (Chart1.CustomAxes.Count mod 2 = 0) then
Chart1.CustomAxes.Items[Chart1.CustomAxes.Count-1].OtherSide := True;
Chart1.CustomAxes.Items[Chart1.CustomAxes.Count-1].Axis.Color := Chart1[Chart1.SeriesCount-1].Color;
Chart1.CustomAxes.Items[Chart1.CustomAxes.Count-1].Grid.Visible := False;
ComboBox2.Items.Add('Series' + inttostr(Chart1.SeriesCount));
ComboBox2.ItemIndex := ComboBox2.Items.Count-1;
Chart1[Chart1.SeriesCount-1].FillSampleValues(Chart1[0].XValues.Count);
PlaceAxes();
end;
Probably this is more than what you need because in this there are axis in the other side (right), but I hope it will help you to see what you need.
I will try to explain in a few words what is this code doing:
-Create: This adds a predefined number of LineSeries (nSeries=6) to the chart, creates and assign a custom axis to each one of them and populate them. (Note that I'm not using the predefined Left Axis). Also is important to note that I change MarginUnits and all CustomAxis.PositionUnits to pixels to calculate them easier.
-PlaceAxes: Is a recursive method that calculates the position of all the Axes taking in consideration the MaxLabelsWidth and the TickLength of the already drawn axes.
-CheckBox1: Actives/ deactivates the Series shown at ComboBox2 (and its axis).
-CheckBox2: Changes the side of the CustomAxis of the Series shown at ComboBox2.
-Button1: Executes a FillSampleValues with a number of data indicated at ComboBox1.
-Button2: Adds a new LineSeries and its new CustomAxis to the chart.
I hope the explanation helps...
Posted: Thu May 03, 2007 9:00 am
by yeray
Please, add this 3 lines to the TForm1.FormCreate to see the chart better.
Code: Select all
Chart1.View3D := false;
Chart1.Title.Visible := false;
Chart1.Legend.Alignment := laBottom;
Posted: Thu May 03, 2007 1:50 pm
by 9234349
Hi Veray,
Thank you for the code. I ran it and it isn't what I'm looking for.
1. I don't think it works when there are multiple series per custom axis.
2. If you add the following code into your series create loop:
Chart1.CustomAxes.Items.Title.Caption := 'Caption ' + IntToStr(i);
Chart1.CustomAxes.Items.Title.Angle := 90;
you will see that the axis captions are overwritten.
3. I am using StartPosition and EndPosition to place the axes in a line vertically. I am allowing for four pairs of left and right axis, as indicated below (with the chart in the middle of my diagram).
| |
| |
| |
| |
Regards,
Bill
Posted: Fri May 04, 2007 9:35 am
by yeray
Hi Bill,
1) The code above was thought for having one Custom Axis per Series and avoid overlapping.
2) If you want to add a title to each Custom Axis you should increment the axis separation setting higher extraPos and extraMargin (at PlaceAxes method). Following values work for me: extraPos := 32 and extraMargin := 62
3) You should assign a left and a right custom axis to each of your series but it is not possible at this moment. But, as a workaround, you can create two series with the same values and assign a left custom axis to one and a right custom axis to the other. This would be as follows:
Code: Select all
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
for i := 0 to 3 do
begin
Chart1.AddSeries(TLineSeries);
Chart1[Chart1.SeriesCount-1].FillSampleValues(2000);
Chart1.CustomAxes.Add;
Chart1[Chart1.SeriesCount-1].CustomVertAxis := Chart1.CustomAxes.Items[Chart1.CustomAxes.Count-1];
Chart1.CustomAxes.Items[Chart1.CustomAxes.Count-1].StartPosition := i * 25;
Chart1.CustomAxes.Items[Chart1.CustomAxes.Count-1].EndPosition := (i+1) * 25;
Chart1.AddSeries(CloneChartSeries(Chart1[Chart1.SeriesCount-1]));
Chart1.CustomAxes.Add;
Chart1.CustomAxes.Items[Chart1.CustomAxes.Count-1].OtherSide := true;
Chart1[Chart1.SeriesCount-1].CustomVertAxis := Chart1.CustomAxes.Items[Chart1.CustomAxes.Count-1];
Chart1.CustomAxes.Items[Chart1.CustomAxes.Count-1].StartPosition := i * 25;
Chart1.CustomAxes.Items[Chart1.CustomAxes.Count-1].EndPosition := (i+1) * 25;
end;
Chart1.View3D := false;
Chart1.Title.Visible := false;
Chart1.Legend.Visible := false;
Chart1.MarginLeft := 7;
Chart1.MarginRight := 7;
end;