Multiple extra legend tool to display series groups

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
wvisser
Newbie
Newbie
Posts: 5
Joined: Fri Sep 09, 2016 12:00 am
Contact:

Multiple extra legend tool to display series groups

Post by wvisser » Wed Nov 16, 2016 11:19 am

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
Attachments
mutlipleextralegends.jpg
mutlipleextralegends.jpg (184.11 KiB) Viewed 7508 times

Yeray
Site Admin
Site Admin
Posts: 9614
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Multiple extra legend tool to display series groups

Post by Yeray » Fri Nov 18, 2016 9:10 am

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:

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;
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:

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,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

wvisser
Newbie
Newbie
Posts: 5
Joined: Fri Sep 09, 2016 12:00 am
Contact:

Re: Multiple extra legend tool to display series groups

Post by wvisser » Fri Nov 18, 2016 10:31 am

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

Yeray
Site Admin
Site Admin
Posts: 9614
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Multiple extra legend tool to display series groups

Post by Yeray » Mon Nov 21, 2016 1:12 pm

Hello,
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?
You can draw it manually using DrawCheckBox function and use Chart's OnClick event to activate/deactivate the according series. Ie:

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;
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.
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.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Post Reply