TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
-
Errol
- Newbie
- Posts: 29
- Joined: Mon Jul 08, 2019 12:00 am
Post
by Errol » Tue Nov 01, 2022 10:14 pm
I use TeeChart with a Self Stacked bar chart to visualise the stratigraphy down a well. I have code to generate the legend as shown in the attached image, Stratigraphy.jpg.
However, I wish to create a split-chart with the stratigraphy on the left and a line chart on the right, I am unable to show both legends, as in StratigraphyPT.jpg. How can I place both legends on the chart. I would prefer to be able to create an ExtraLegend and then assign this to the series at the appropriate point.
I have created an ExtraLegend tool as shown below, but I don't understand how to now apply the legend code to the ExtraLegend.
Code: Select all
if self.owner.fToggleSecondWorksheet then
begin
ExtraLegend := TExtraLegendTool.Create(self.owner);
self.Owner.Chart.Tools.Add(ExtraLegend);
ExtraLegend.Series := TUnitBarSeries(SeriesListB.Objects[iIndex]);
end;
-
Attachments
-
- StragraphyPT.jpg (128.36 KiB) Viewed 7653 times
-
- Stragraphy.jpg (97.54 KiB) Viewed 7653 times
-
Yeray
- Site Admin
- Posts: 9613
- Joined: Tue Dec 05, 2006 12:00 am
- Location: Girona, Catalonia
-
Contact:
Post
by Yeray » Wed Nov 02, 2022 1:02 pm
Hello Errol,
You could override the
TeeExtraLegendTool
's
ChartEvent
to set
ShowInLegend
for those series you want it to consider, and reset
ShowInLegend
at the Chart's
OnBeforeDrawChart
for the main legend. Ie:
- extralegend.png (7.59 KiB) Viewed 7637 times
Code: Select all
uses Series, TeeExtraLegendTool;
type TMyExtraLegendTool=class(TExtraLegendTool)
protected
procedure ChartEvent(AEvent: TChartToolEvent); override;
end;
TLegendAccess=class(TChartLegend);
procedure TMyExtraLegendTool.ChartEvent(AEvent: TChartToolEvent);
begin
inherited;
if AEvent=cteAfterDraw then
begin
ParentChart[0].ShowInLegend:=False;
ParentChart[1].ShowInLegend:=True;
ParentChart[2].ShowInLegend:=True;
if Assigned(ParentChart) and Assigned(Series) then
begin
Legend.Series:=Series; // call getter
if Legend.Visible then
begin
TLegendAccess(Legend).CalcRect;
Legend.DrawLegend;
end;
end;
end;
end;
procedure TForm1.Chart1BeforeDrawChart(Sender: TObject);
begin
Chart1[0].ShowInLegend:=True;
Chart1[1].ShowInLegend:=False;
Chart1[2].ShowInLegend:=False;
end;
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
Chart1.View3D:=False;
Chart1.Gradient.Visible:=False;
Chart1.Color:=clWhite;
Chart1.Walls.Back.Gradient.Visible:=False;
Chart1.Walls.Back.Color:=clWhite;
Chart1.Axes.Bottom.EndPosition:=50;
Chart1.Axes.Top.StartPosition:=50;
with TBarSeries(Chart1.AddSeries(TBarSeries)) do
begin
MultiBar:=mbSelfStack;
Marks.Hide;
FillSampleValues(3);
end;
with TLineSeries(Chart1.AddSeries(TLineSeries)) do
begin
HorizAxis:=aTopAxis;
Pointer.Show;
Pointer.Size:=2;
FillSampleValues(5);
end;
with TLineSeries(Chart1.AddSeries(TLineSeries)) do
begin
HorizAxis:=aTopAxis;
Pointer.Show;
Pointer.Size:=2;
FillSampleValues(5);
end;
Chart1.Draw;
with TMyExtraLegendTool(Chart1.Tools.Add(TMyExtraLegendTool)) do
begin
Series:=Chart1[1];
Legend.LegendStyle:=lsSeries;
Legend.Left:=Chart1.Legend.Left;
Legend.Top:=Chart1.Legend.Top+Chart1.Legend.Height+10;
end;
end;
-
Errol
- Newbie
- Posts: 29
- Joined: Mon Jul 08, 2019 12:00 am
Post
by Errol » Sun Nov 06, 2022 5:17 am
Hello Yeray
Thank you for your reply. I have reviewed your sample code, but I am still puzzled on how to proceed. In my code, I use a single chart and a single legend for any number of line series (see multiline.jpg with 4 series and a single combined legend). Similarly, for bar charts (multigeology.jpg).
When I make a chart with both line and bar charts, I would like to simply assign the bar chart legend (a composite legend of all rock types in the selected series) to an ExtraLegend, rather than change all my code to refer to chart[0], chart[1] etc, as would seem to be necessary if I added each series to the chart. Is this possible?
-
Attachments
-
- Multigeology.jpg (219.91 KiB) Viewed 7610 times
-
- Multiline.jpg (145.39 KiB) Viewed 7610 times
-
Yeray
- Site Admin
- Posts: 9613
- Joined: Tue Dec 05, 2006 12:00 am
- Location: Girona, Catalonia
-
Contact:
Post
by Yeray » Mon Nov 07, 2022 2:41 pm
Hello Errol,
If you want
TBarSeries
in the main series and
TLineSeries
in the extra legend, you can loop all the series and activate/deactivate
ShowInLegend
according to the series class:
Code: Select all
uses Series, TeeExtraLegendTool;
type TMyExtraLegendTool=class(TExtraLegendTool)
protected
procedure ChartEvent(AEvent: TChartToolEvent); override;
end;
TLegendAccess=class(TChartLegend);
procedure TMyExtraLegendTool.ChartEvent(AEvent: TChartToolEvent);
var i: Integer;
begin
if AEvent=cteAfterDraw then
begin
for i:=0 to ParentChart.SeriesCount-1 do
ParentChart[i].ShowInLegend:=ParentChart[i] is TLineSeries;
if Assigned(ParentChart) and Assigned(Series) then
begin
if Legend.Visible then
begin
TLegendAccess(Legend).CalcRect;
Legend.DrawLegend;
end;
end;
end;
end;
procedure TForm1.Chart1BeforeDrawChart(Sender: TObject);
var i: Integer;
begin
for i:=0 to Chart1.SeriesCount-1 do
Chart1[i].ShowInLegend:=Chart1[i] is TBarSeries;
end;
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
Chart1.View3D:=False;
Chart1.Gradient.Visible:=False;
Chart1.Color:=clWhite;
Chart1.Walls.Back.Gradient.Visible:=False;
Chart1.Walls.Back.Color:=clWhite;
Chart1.Axes.Bottom.EndPosition:=50;
Chart1.Axes.Top.StartPosition:=50;
Chart1.OnBeforeDrawChart:=Chart1BeforeDrawChart;
with TBarSeries(Chart1.AddSeries(TBarSeries)) do
begin
MultiBar:=mbSelfStack;
Marks.Hide;
FillSampleValues(3);
end;
with TLineSeries(Chart1.AddSeries(TLineSeries)) do
begin
HorizAxis:=aTopAxis;
Pointer.Show;
Pointer.Size:=2;
FillSampleValues(5);
end;
with TLineSeries(Chart1.AddSeries(TLineSeries)) do
begin
HorizAxis:=aTopAxis;
Pointer.Show;
Pointer.Size:=2;
FillSampleValues(5);
end;
Chart1.Draw;
with TMyExtraLegendTool(Chart1.Tools.Add(TMyExtraLegendTool)) do
begin
Series:=Chart1[1];
Legend.LegendStyle:=lsSeries;
Legend.Left:=Chart1.Legend.Left;
Legend.Top:=Chart1.Legend.Top+Chart1.Legend.Height+10;
end;
end;