Horizontal axis with multi-level categories (like Excel)
Posted: Fri Sep 09, 2016 12:45 pm
Is it possible?
Steema Software - Customer Support Forums
http://216.92.101.67/support/
Code: Select all
uses Series, TeePNG;
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
Chart1.View3D:=false;
Chart1.Legend.Alignment:=laTop;
Chart1.Legend.LegendStyle:=lsSeries;
Chart1.MarginBottom:=12;
with Chart1.AddSeries(TLineSeries) as TLineSeries do
begin
FillSampleValues(12);
Pointer.Visible:=true;
for i:=0 to Count-1 do
Labels[i]:='label ' + InttoStr(i);
end;
with Chart1.Axes.Bottom do
begin
MinorTicks.Visible:=false;
Grid.Visible:=false;
with SubAxes.Add do
begin
Visible:=True;
Axis.Hide;
MinorTicks.Hide;
Ticks.Hide;
Texts.MarginToAxis:=300;
Items.Add(5.5, 'subaxis 3, label 1');
end;
with SubAxes.Add do
begin
Visible:=True;
Axis.Hide;
MinorTicks.Hide;
Ticks.Hide;
Texts.MarginToAxis:=200;
Items.Add(2.5, 'subaxis 2, label 1');
Items.Add(8.5, 'subaxis 2, label 2');
end;
with SubAxes.Add do
begin
Visible:=True;
Axis.Hide;
MinorTicks.Hide;
Ticks.Hide;
Texts.MarginToAxis:=100;
Items.Add(1, 'subaxis 1, label 1');
Items.Add(4, 'subaxis 1, label 2');
Items.Add(7, 'subaxis 1, label 3');
Items.Add(10, 'subaxis 1, label 3');
end;
end;
Chart1.OnBeforeDrawAxes:=Chart1BeforeDrawAxes;
Chart1.Draw;
end;
procedure TForm1.Chart1BeforeDrawAxes(Sender: TObject);
var y0, y1, x, i: Integer;
begin
y0:=Chart1.Axes.Bottom.PosAxis-3;
with Chart1.Canvas do
begin
Pen.Assign(Chart1.Axes.Bottom.TicksInner);
for i:=0 to Chart1.Axes.Bottom.Items.Count-2 do
begin
x:=Chart1.Axes.Bottom.CalcPosValue(Chart1.Axes.Bottom.Items[i].Value + (Chart1.Axes.Bottom.Items[i+1].Value - Chart1.Axes.Bottom.Items[i].Value) / 2);
if (i=2) or (i=8) then
y1:=Chart1.Axes.Bottom.SubAxes[1].PosAxis+17
else if (i=5) then
y1:=Chart1.Axes.Bottom.SubAxes[0].PosAxis+30
else
y1:=Chart1.Axes.Bottom.SubAxes[2].PosAxis+7;
VertLine3D(x, y0, y1, 0);
end;
end;
end;
I've modified the code to draw the ticks to do it a more generic:Yeray wrote:Note I had to manually draw some of the ticks.
Code: Select all
uses Series, TeePNG;
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
Chart1.View3D:=false;
Chart1.Legend.Alignment:=laTop;
Chart1.Legend.LegendStyle:=lsSeries;
Chart1.MarginBottom:=12;
with Chart1.AddSeries(TLineSeries) as TLineSeries do
begin
FillSampleValues(12);
Pointer.Visible:=true;
for i:=0 to Count-1 do
Labels[i]:='label ' + InttoStr(i);
end;
with Chart1.Axes.Bottom do
begin
MinorTicks.Visible:=false;
Grid.Visible:=false;
with SubAxes.Add do
begin
Visible:=True;
Axis.Hide;
MinorTicks.Hide;
Ticks.Hide;
Texts.MarginToAxis:=300;
Items.Add(5.5, 'subaxis 3, label 1');
end;
with SubAxes.Add do
begin
Visible:=True;
Axis.Hide;
MinorTicks.Hide;
Ticks.Hide;
Texts.MarginToAxis:=200;
Items.Add(2.5, 'subaxis 2, label 1');
Items.Add(8.5, 'subaxis 2, label 2');
end;
with SubAxes.Add do
begin
Visible:=True;
Axis.Hide;
MinorTicks.Hide;
Ticks.Hide;
Texts.MarginToAxis:=100;
Items.Add(1, 'subaxis 1, label 1');
Items.Add(4, 'subaxis 1, label 2');
Items.Add(7, 'subaxis 1, label 3');
Items.Add(10, 'subaxis 1, label 3');
end;
end;
Chart1.OnBeforeDrawAxes:=Chart1BeforeDrawAxes;
Chart1.Draw;
end;
procedure TForm1.Chart1BeforeDrawAxes(Sender: TObject);
var y0, y1, x, i, j, k: Integer;
function calcTickYPos(AAxis: TChartAxis): Integer;
var k: Integer;
begin
result:=-1;
for k:=0 to AAxis.Items.Count-1 do
if AAxis.Items[k].LabelPos = x then
begin
result:=AAxis.PosAxis + Round(Abs(AAxis.LabelsFont.Height)*AAxis.Texts.MarginToAxis*0.01);
break;
end;
end;
begin
y0:=Chart1.Axes.Bottom.PosAxis-3;
with Chart1.Canvas do
begin
Pen.Assign(Chart1.Axes.Bottom.TicksInner);
for i:=0 to Chart1.Axes.Bottom.Items.Count-2 do
begin
x:=Chart1.Axes.Bottom.CalcPosValue(Chart1.Axes.Bottom.Items[i].Value + (Chart1.Axes.Bottom.Items[i+1].Value - Chart1.Axes.Bottom.Items[i].Value) / 2);
y1:=-1;
for j:=0 to Chart1.Axes.Bottom.SubAxes.Count-1 do
begin
y1:=calcTickYPos(Chart1.Axes.Bottom.SubAxes[j]);
if y1<>-1 then
break;
end;
if (y1=-1) and (Chart1.Axes.Bottom.SubAxes.Count>0) then
y1:=Chart1.Axes.Bottom.SubAxes[Chart1.Axes.Bottom.SubAxes.Count-1].PosAxis+Round(Abs(Chart1.Axes.Bottom.SubAxes[Chart1.Axes.Bottom.SubAxes.Count-1].LabelsFont.Height)*Chart1.Axes.Bottom.SubAxes[Chart1.Axes.Bottom.SubAxes.Count-1].Texts.MarginToAxis*0.01);
VertLine3D(x, y0, y1, 0);
end;
end;
end;