Hello,
I have an application with a number of lineseries in a chart plotted against multiple vertical axes (vertically stacked). Per vertical axis I would like to have a legend to show the series names linked to that axis. See the attached image example.
I can use the Legend's FirstValue and MaxnumRows properties to have the extralegends show a subset of the series, but this only works as long as the series are distributed over the Y axes in the same order is in the parent Chart's SeriesList. If for example I would like to have the 1st series on the 2nd Y axis it would not work anymore.
Solutions would be
- an event handler enabling accepting or rejecting an item in the legend
- The option to show the series in a series group
- or something showing only series attached to a particular vertical axis
I feel I need to derive a custom Legend version, but I see that this involves a lot of re-coding as many TChartLegend items are protected and few things are managed with virtual (overridable) methods.
Is there an elegant way to do this without coding?
If not: what would be the best approach to derive a custom version of the ChartLegend (to go in a Custom derivative of TExtraLegendTool)
regards, Wilfried Visser
Multiple extra legend tool to display series groups
Multiple extra legend tool to display series groups
- Attachments
-
- mutlipleextralegends.jpg (184.11 KiB) Viewed 7507 times
Re: Multiple extra legend tool to display series groups
Hello,
If you only want to show the series titles (or some other text related to each series) you could use 2 TAnnotationTool(s) as in the following simple example:
If you want to also show the series symbols in the TAnnotationTool(s) then some extra code should be added to manually draw them at OnAfterDraw event. Ie:
If you only want to show the series titles (or some other text related to each series) you could use 2 TAnnotationTool(s) as in the following simple example:
Code: Select all
procedure TForm1.FormCreate(Sender: TObject);
var i, j: Integer;
begin
Chart1.View3D:=false;
Chart1.MarginLeft:=7;
Chart1.CustomAxes.Add.EndPosition:=45;
Chart1.CustomAxes.Add.StartPosition:=55;
Chart1.Tools.Add(TAnnotationTool);
Chart1.Tools.Add(TAnnotationTool);
for i:=0 to 5 do
begin
if (i mod 3 = 0) then
Chart1.AddSeries(TLineSeries)
else
with Chart1.AddSeries(TPointSeries) as TPointSeries do
begin
Pointer.HorizSize:=3;
Pointer.VertSize:=3;
Pointer.Style:=psCircle;
end;
Chart1[i].CustomVertAxis:=Chart1.CustomAxes[i mod 2];
Chart1[i].FillSampleValues;
end;
Chart1.Draw;
for i:=0 to Chart1.CustomAxes.Count-1 do
begin
with Chart1.Tools[i] as TAnnotationTool do
begin
Shape.CustomPosition:=True;
Shape.Left:=Chart1.ChartRect.Left;
Shape.Top:=Chart1.CustomAxes[i].IStartPos;
Shape.AutoSize:=true;
Shape.Transparency:=0;
for j:=0 to Chart1.SeriesCount-1 do
if (Chart1[j].CustomVertAxis = Chart1.CustomAxes[i]) then
if (Text = '') then
Text:=' '+SeriesTitleOrName(Chart1[j])
else
Text:=Text+sLineBreak+' '+SeriesTitleOrName(Chart1[j]);
end;
end;
end;
Code: Select all
procedure TForm1.Chart1AfterDraw(Sender: TObject);
var i, j, d: Integer;
begin
for i:=0 to Chart1.CustomAxes.Count-1 do
begin
d:=9;
with Chart1.Tools[i] as TAnnotationTool do
begin
for j:=0 to Chart1.SeriesCount-1 do
if (Chart1[j].CustomVertAxis = Chart1.CustomAxes[i]) then
begin
Chart1[j].DrawLegend(-1,Rect(Shape.Left+6,Shape.Top+d, Shape.Left+16, Shape.Top+d+4));
Inc(d,14);
end;
end;
end;
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: Multiple extra legend tool to display series groups
Thanks,
I more or less already have taken this route. The tip how to dray the symbol really helps !
One final question: do you alo have a suggestion how to add a checkbox in front of the symbol that can be checked/unchecked to activate/deactivate the series?
Another question: should not the TCustomLegend tool be used for this? I tried the TCustomLegend tool but it does not seem to work properly: I do not see any text I enter in the Text property appear in the TCustomLegend grid.
regards and thanks again,
Wilfried Visser, VisserTek
I more or less already have taken this route. The tip how to dray the symbol really helps !
One final question: do you alo have a suggestion how to add a checkbox in front of the symbol that can be checked/unchecked to activate/deactivate the series?
Another question: should not the TCustomLegend tool be used for this? I tried the TCustomLegend tool but it does not seem to work properly: I do not see any text I enter in the Text property appear in the TCustomLegend grid.
regards and thanks again,
Wilfried Visser, VisserTek
Re: Multiple extra legend tool to display series groups
Hello,
You can draw it manually using DrawCheckBox function and use Chart's OnClick event to activate/deactivate the according series. Ie:wvisser wrote:do you alo have a suggestion how to add a checkbox in front of the symbol that can be checked/unchecked to activate/deactivate the series?
Code: Select all
uses TeeTools, Series;
procedure TForm1.Chart1Click(Sender: TObject);
var i, j, n, line: Integer;
annot: TAnnotationTool;
begin
for i:=0 to Chart1.Tools.Count-1 do
begin
annot:=Chart1.Tools[i] as TAnnotationTool;
if annot.Clicked(Chart1.GetCursorPos.X, Chart1.GetCursorPos.Y) then
begin
line:=(abs(Chart1.GetCursorPos.Y-(annot.Shape.Top+3)) div (abs(annot.Shape.Font.Height)+3))+1;
n:=0;
for j:=0 to Chart1.SeriesCount-1 do
if (Chart1[j].CustomVertAxis = Chart1.CustomAxes[i]) then
begin
Inc(n);
if (n=line) then
begin
Chart1[j].Active:=not Chart1[j].Active;
exit;
end;
end;
exit;
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var i, j: Integer;
begin
Chart1.View3D:=false;
Chart1.MarginLeft:=7;
Chart1.CustomAxes.Add.EndPosition:=45;
Chart1.CustomAxes.Add.StartPosition:=55;
Chart1.Tools.Add(TAnnotationTool);
Chart1.Tools.Add(TAnnotationTool);
for i:=0 to 5 do
begin
if (i mod 3 = 0) then
Chart1.AddSeries(TLineSeries)
else
with Chart1.AddSeries(TPointSeries) as TPointSeries do
begin
Pointer.HorizSize:=3;
Pointer.VertSize:=3;
Pointer.Style:=psCircle;
end;
Chart1[i].CustomVertAxis:=Chart1.CustomAxes[i mod 2];
Chart1[i].FillSampleValues;
end;
Chart1.Draw;
for i:=0 to Chart1.CustomAxes.Count-1 do
begin
with Chart1.Tools[i] as TAnnotationTool do
begin
Shape.CustomPosition:=True;
Shape.Left:=Chart1.ChartRect.Left;
Shape.Top:=Chart1.CustomAxes[i].IStartPos;
Shape.AutoSize:=true;
Shape.Transparency:=0;
for j:=0 to Chart1.SeriesCount-1 do
if (Chart1[j].CustomVertAxis = Chart1.CustomAxes[i]) then
if (Text = '') then
Text:=' '+SeriesTitleOrName(Chart1[j])
else
Text:=Text+sLineBreak+' '+SeriesTitleOrName(Chart1[j]);
end;
end;
end;
procedure TForm1.Chart1AfterDraw(Sender: TObject);
var i, j, d, tmpX: Integer;
begin
for i:=0 to Chart1.CustomAxes.Count-1 do
begin
d:=9;
with Chart1.Tools[i] as TAnnotationTool do
begin
tmpX:=Shape.Left+20;
for j:=0 to Chart1.SeriesCount-1 do
if (Chart1[j].CustomVertAxis = Chart1.CustomAxes[i]) then
begin
Chart1[j].DrawLegend(-1,Rect(tmpX,Shape.Top+d, tmpX+10, Shape.Top+d+4));
Chart1.Canvas.DrawCheckBox(Shape.Left+4, Shape.Top+d-5, Chart1[j].Active, clNone);
Inc(d,14);
end;
end;
end;
end;
That could be a different approach. Take a look at the examples under "What's New ?\Welcome!\New Chart Tools\Custom Legend Tool" in the New Features demo program shipped with the installation to see it in action, with code.wvisser wrote:should not the TCustomLegend tool be used for this? I tried the TCustomLegend tool but it does not seem to work properly: I do not see any text I enter in the Text property appear in the TCustomLegend grid.
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |