Page 1 of 1

Left Align Legend Text?

Posted: Thu Jul 29, 2010 5:45 pm
by 16555616
Hello,

Is there a way that I can get the legend text to appear right next to the legend symbol? It appears that the legend items are alloted a width based upon the length of the longest text of all the legend items. This makes the legend items with shorter text display with a lot of space between the symbol and the text. Is there any way I can specify that the text for each item will be left aligned within the space alloted to it?

Thank you,

erzsebet

Re: Left Align Legend Text?

Posted: Fri Jul 30, 2010 3:30 pm
by 16555616
Hello,

How could I post a screenshot of this issue?

Thank you,

erzsebet

Re: Left Align Legend Text?

Posted: Fri Jul 30, 2010 3:35 pm
by narcis
Hi erzsebet,

Upload it as an attachment at your replies here in the forums and use the "place inlane" feature to display it embedded in your text.

Thanks.

Re: Left Align Legend Text?

Posted: Fri Jul 30, 2010 3:48 pm
by 16555616
Narcís, hello -

Thanks for answering my question about the attachment! I don't know how I missed the "Upload Attachment" tab! I will blame the fact that it is Friday!

In any event, this image shows the issue I am having with the legend:
LegendSpacing_073010.png
Shows space between text and symbol.
LegendSpacing_073010.png (1.89 KiB) Viewed 5991 times
I would like the "BORCHERS-BORCHERS, S." text to appear right next to the blue square, not far away like it is. I understand that the spacing is determined by the fact that "MANCHO PRADO-MANCHO PRADO" is longer than the "BORCHERS-BORCHERS, S" text, but is there some way to get manipulate the legend into displaying the text left aligned within the space allotted to each item?

Hope you have a great weekend!

-erzsebet

Re: Left Align Legend Text?

Posted: Fri Jul 30, 2010 4:51 pm
by yeray
Hi erzsebet ,

What TeeChart version are you using?
I'm trying the following code with the latest sources and I can't reproduce the issue:

Code: Select all

uses series;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Chart1.Legend.Alignment:=laBottom;

  with Chart1.AddSeries(TPointSeries) do
  begin
    FillSampleValues();
    Title:='short string';
  end;

  with Chart1.AddSeries(TPointSeries) do
  begin
    FillSampleValues();
    Title:='very very very long string';
  end;
end;
Chart1.png
Chart1.png (11.75 KiB) Viewed 5994 times
Could you please try the code above and see if you can see the same than me or not?
If you can't reproduce the problem with it, could you please try to modify it so we can reproduce the problem here?
Thanks in advance.

Re: Left Align Legend Text?

Posted: Thu Aug 05, 2010 9:54 pm
by 16555616
Yeray and Narcís, hello!

I hope you are both having a good day! Thanks so much for the time you've already put in to help me on this issue. Here is some more information.

I am using TeeChart Pro 8.06 with Delphi 2010. My issue with legend text alignment seems to be caused by overriding events to custom draw a customized legend. I have recreated the problem in the attached code. Please let me know if you have any suggestions on how I can get the legend text to appear closer to its associated symbol.

Thanks,

-erzsebet

Re: Left Align Legend Text?

Posted: Thu Aug 05, 2010 10:00 pm
by 16555616
And now for the actual code! :wink:

-erzsebet

Code: Select all

{ Note: My chart has one series, but users have the option to set the color for a range of values.         }
{ The legend is customized to display the range of each selection and not the series name or series value.  }
unit LegendTextAlignment_48352;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Series, TeEngine, ExtCtrls, TeeProcs, Chart;

type
  { TScatterPlotObjectColor }
  TScatterPlotObjectColor = class
  private
    FColor: LongInt;
  public
    property Color: LongInt read FColor write FColor;
    constructor Create(const AColor : LongInt);
  end;

  TForm2 = class(TForm)
    Chart1: TChart;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    FLegendList : TStringList;
    FLegendStartIndex, FCurrentLegendTextIndex, FCurrentLegendImageIndex : Integer;
    FDebugStr : String;
  public
    { Public declarations }
    procedure BeforeDrawChart(Sender: TObject);
    procedure AfterDraw(Sender: TObject);
    procedure LegendDraw(Sender: TObject; Series: TChartSeries; ValueIndex: Integer; R: TRect);
    procedure SetLegendText(Sender: TCustomAxisPanel; LegendStyle: TLegendStyle; Index: Integer; var LegendText: String);
  end;

const
  OWNS_OBJECTS_FLAG : Boolean = True;
var
  Form2: TForm2;

implementation

{$R *.dfm}
{ *******************TScatterPlotObjectColor Class*********************** }
constructor TScatterPlotObjectColor.Create(const AColor : LongInt);
begin
  FColor := AColor;
end;

{ **************************TForm2 Class********************************** }
procedure TForm2.FormCreate(Sender: TObject);
begin
  { Override events to customize legend. }
  Chart1.Legend.Alignment:=laBottom;
  Chart1.Legend.LegendStyle := lsValues;
  Chart1.OnBeforeDrawChart := BeforeDrawChart;
  Chart1.OnGetLegendText := SetLegendText;
  Chart1.Legend.Symbol.OnDraw := LegendDraw;
  Chart1.OnAfterDraw := AfterDraw;
  { Set up items needed for customization. }
  FLegendList := TStringList.Create(OWNS_OBJECTS_FLAG);
  FLegendList.AddObject('SHORT_RANGE', TScatterPlotObjectColor.Create(clRed));
  FLegendList.AddObject('VERYVERY_LONGRANGE', TScatterPlotObjectColor.Create(clGreen));
  FLegendStartIndex := 0;
  FCurrentLegendTextIndex := 0;
  FCurrentLegendImageIndex := 0;
  { Add the series. }
  with Chart1.AddSeries(TPointSeries) do
  begin
    FillSampleValues();
    Title:='title';    // This does not matter in our code, as the title is only displayed in the mouseover, and not in the legend.
  end;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if Assigned(FLegendList) then FreeAndNil(FLegendList);
  Chart1.OnBeforeDrawChart := nil;
  Chart1.OnGetLegendText := nil;
  Chart1.OnAfterDraw := nil;
  Chart1.Legend.Symbol.OnDraw := nil;
  Chart1.Legend.FirstValue := 0;
end;

{ BeforeDrawChart overrides the TCustomChart OnDrawChart event to set the number of points to display in the legend - we *do not* want a legend item for every point! }
procedure TForm2.BeforeDrawChart(Sender: TObject);
begin
  try
    if Assigned(FLegendList) then begin
      TChart(Sender).Legend.FirstValue := TChart(Sender).Series[0].YValues.Count - FLegendList.Count;
      TChart(Sender).Legend.Symbol.Position := spLeft;
      TChart(Sender).Legend.Symbol.Width := 5;
      FLegendStartIndex := TChart(Sender).Legend.FirstValue;
    end;
  except
    on E : Exception do begin
      FDebugStr := 'TForm2.BeforeDrawChart: Exception caught - ' + E.Message;
      //DebugValue(DebugStr);
    end;
  end;
end;

{ SetLegendText overrides the OnGetLegendText event to allow customization of legend item text. }
procedure TForm2.SetLegendText(Sender: TCustomAxisPanel; LegendStyle: TLegendStyle; Index: Integer; var LegendText: String);{ HPDO-272 }
begin
  try
    LegendText := FLegendList[FCurrentLegendTextIndex];
    Inc(FCurrentLegendTextIndex);
  except
    on E : Exception do begin
      FDebugStr :=  'TScatterPlotDef.SetLegendText: Exception caught - ' + E.Message;
      //DebugValue(DebugStr);
    end;
  end;
end;

{ LegendDraw overrides the OnDraw event to allow customization of the legend symbol. }
procedure TForm2.LegendDraw(Sender: TObject; Series: TChartSeries; ValueIndex: Integer; R: TRect);
var
  ColorToPaint: LongInt;
begin
  try
    with TLegendSymbol(Sender) do begin
      ColorToPaint := TScatterPlotObjectColor(FLegendList.Objects[FCurrentLegendImageIndex]).Color;
      Chart1.Canvas.Brush.Color := ColorToPaint;
      Chart1.Canvas.Pen.Color := clBlack;
      Chart1.Canvas.Rectangle(R);
    end;
    Inc(FCurrentLegendImageIndex);
  except
    on E : Exception do begin
      FDebugStr :=  'TScatterPlotDef.LegendDraw: Exception caught - ' + E.Message;
      //DebugValue(DebugStr);
    end;
  end;
end;

{ AfterDraw overrides the TCustomChart OnAfterDraw event to reset all of the events and legend settings to their defaults prior to drawing other charts. }
procedure TForm2.AfterDraw(Sender: TObject);
begin
  Chart1.Legend.FirstValue := 0;
  Chart1.Legend.LegendStyle := lsAuto;
  FCurrentLegendTextIndex := 0;
  FCurrentLegendImageIndex := 0;
end;

end.
LegendAlignmentInChart.PNG
LegendAlignmentInChart.PNG (61.42 KiB) Viewed 5979 times

Re: Left Align Legend Text?

Posted: Fri Aug 06, 2010 2:18 pm
by yeray
Hi erzsebet,

The Legend.TextStyle by default shows the values and the labels if present, and it alignes the "text" to the right. If you set the TextStyle to be Plain, like you would do if you would like to show the labels, the text is aligned to the left:

Code: Select all

Chart1.Legend.TextStyle:=ltsPlain;

Re: Left Align Legend Text?

Posted: Fri Aug 06, 2010 2:53 pm
by 16555616
Thank you, Yeray!! That was exactly what I needed to do to fix my legend text alignment problem! You and your entire team are awesome!

- erzsebet