multiple legend
multiple legend
Hi,
I would like to have 2 legends for one graph. The first one with the series name "Serie 1", "Series 2" and the second one for "Serie 3", "Series 4".
It seems that it's only possible to have all the series of a graph in a legend when we choose the lsSeries property.
Or, is it possible (and how) to have one legend but a line to separate two sets of series ?
Best regards
I would like to have 2 legends for one graph. The first one with the series name "Serie 1", "Series 2" and the second one for "Serie 3", "Series 4".
It seems that it's only possible to have all the series of a graph in a legend when we choose the lsSeries property.
Or, is it possible (and how) to have one legend but a line to separate two sets of series ?
Best regards
Hi stsl,
Yes, you could have two legends using a custom legend. Please take a look at the demo at All features/Miscellaneous/Legend/Multiple Legends.
If you prefer to draw a line, you should draw it directly to the canvas:
Yes, you could have two legends using a custom legend. Please take a look at the demo at All features/Miscellaneous/Legend/Multiple Legends.
If you prefer to draw a line, you should draw it directly to the canvas:
Code: Select all
procedure TForm1.Chart1AfterDraw(Sender: TObject);
begin
With Chart1.Legend.ShapeBounds do
begin
With Chart1.Canvas do
begin
DoHorizLine(Left,Right,Bottom-17);
end;
end;
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
multiple legend
I know that there is a multiple legend demo. But in your demo, if you use the lsSeries mode, 2 legends with all the series will be painted. In my chart, i have, for example 3 series. I would like one legend with the first serie (serie name) and the other one legend with the 2 last series.
I tried to do that :
It works but when i checked a serie (i use checkbox) the 2 legends are both painted with serie2 and serie3 intead of one legend with serie1 and the otherone with serie1 ans serie2.
[/img]
I tried to do that :
Code: Select all
procedure TForm1.FormCreate(Sender: TObject);
begin
Series1.FillSampleValues(100);
Chart.Legend.LegendStyle := lsSeries;
Series1.ShowInLegend := False;
Series2.ShowInLegend := False;
Series3.ShowInLegend := False;
end;
procedure TForm1.ChartAfterDraw(Sender: TObject);
begin
if cbAdditionalLegend.Checked then
begin
Chart.Legend.Top := 125;
Series1.ShowInLegend := False;
Series2.ShowInLegend := True;
Series3.ShowInLegend := True;
Chart.Legend.DrawLegend;
Chart.Legend.CustomPosition := False;
end;
end;
[/img]
I made a mistake in my sample code. In the form create :
Code: Select all
Series1.ShowInLegend := True;
Series2.ShowInLegend := False;
Series3.ShowInLegend := False;
I found a solution of my problem. I added a OnBeforeDrawChart :
Code: Select all
procedure TForm1.ChartBeforeDrawChart(Sender: TObject);
begin
Series1.ShowInLegend := True;
Series2.ShowInLegend := False;
Series3.ShowInLegend := False;
end;
Now, i would like to have one legend with series and a second legend with serie groups. I modified my ChartAfterDraw procedure like this :
The two legends are properly drawn but it's now impossible to check or uncheck the series in the first legend and the groups in the second legend.
Where is my mistake ?
Best regards
Code: Select all
procedure TForm1.ChartAfterDraw(Sender: TObject);
begin
if cbadditionallegend.Checked then
begin
Chart.Legend.Top := 125;
Chart.Legend.CheckBoxes:=True;
Chart.Legend.LegendStyle := lsSeriesGroups;
Chart.Legend.DrawLegend;
Chart.Legend.CustomPosition := False;
end;
end;
The two legends are properly drawn but it's now impossible to check or uncheck the series in the first legend and the groups in the second legend.
Where is my mistake ?
Best regards
Hi stsl,
Yes, I've seen the problem. It seems that, having multiple series, only the last one is clickable. I''ve added the issue to the wish list to be fixed in further releases (TV52013878).
In the meanwhile, here you have a workaround example that works for me here:
Yes, I've seen the problem. It seems that, having multiple series, only the last one is clickable. I''ve added the issue to the wish list to be fixed in further releases (TV52013878).
In the meanwhile, here you have a workaround example that works for me here:
Code: Select all
const CheckBoxesSeparation = 17;
CheckBoxesSize = 12;
FirstItemTop = 56;
CheckBoxesMargin = 4;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var i:Integer;
begin
Chart1.View3D := false;
for i:=0 to Chart1.SeriesCount-1 do
Chart1[i].FillSampleValues(25);
with Chart1.SeriesGroups do
begin
Chart1.SeriesList.AddGroup('Group A');
Items[0].Add(Chart1[0]);
Items[0].Add(Chart1[1]);
Chart1.SeriesList.AddGroup('Group B');
Items[1].Add(Chart1[2]);
Items[1].Add(Chart1[3]);
end;
Chart1.Legend.CheckBoxes:=True;
end;
procedure TForm1.Chart1AfterDraw(Sender: TObject);
begin
Chart1.Legend.Top := 125;
Chart1.Legend.LegendStyle := lsSeriesGroups;
Chart1.Legend.DrawLegend;
end;
procedure TForm1.Chart1BeforeDrawChart(Sender: TObject);
begin
Chart1.Legend.CustomPosition := False;
Chart1.Legend.LegendStyle := lsSeries;
end;
procedure TForm1.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var i: Integer;
begin
for i:= 0 to Chart1.SeriesCount-1 do
if ((X > Chart1.Legend.Left + CheckBoxesMargin) and
(X < Chart1.Legend.Left + CheckBoxesMargin + CheckBoxesSize)) then
if ((Y > FirstItemTop + (i*CheckBoxesSeparation)) and
(Y < FirstItemTop + (i*CheckBoxesSeparation) + CheckBoxesSize)) then
Chart1[i].Active := not Chart1[i].Active;
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Hi stsl,
1) It's strange, Ive tried with extralegend tool and with more than 2 legends and always the last drawn legend is clickable.
Well, you always will be able to add another "for" to check if the click was on the checkbox. This time you could do as follows:
2) I've found the constant values with a simple trick. Add the following code to your OnMouseDown or OnMouseMove event:
1) It's strange, Ive tried with extralegend tool and with more than 2 legends and always the last drawn legend is clickable.
Well, you always will be able to add another "for" to check if the click was on the checkbox. This time you could do as follows:
Code: Select all
const CheckBoxesSeparation = 17;
CheckBoxesSize = 12;
FirstItemTopLegend1 = 56;
FirstItemTopLegend2 = 131;
CheckBoxesMargin = 4;
//...
procedure TForm1.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var i, j: Integer;
begin
for i:=0 to Chart1.SeriesCount-1 do
if ((X > Chart1.Legend.Left + CheckBoxesMargin) and
(X < Chart1.Legend.Left + CheckBoxesMargin + CheckBoxesSize)) then
if ((Y > FirstItemTopLegend1 + (i*CheckBoxesSeparation)) and
(Y < FirstItemTopLegend1 + (i*CheckBoxesSeparation) + CheckBoxesSize)) then
Chart1[i].Active := not Chart1[i].Active;
for i:=0 to Chart1.SeriesGroups.Count-1 do
if ((X > Chart1.Legend.Left + CheckBoxesMargin) and
(X < Chart1.Legend.Left + CheckBoxesMargin + CheckBoxesSize)) then
if ((Y > FirstItemTopLegend2 + (i*CheckBoxesSeparation)) and
(Y < FirstItemTopLegend2 + (i*CheckBoxesSeparation) + CheckBoxesSize)) then
for j:=0 to Chart1.SeriesGroups[i].Series.Count-1 do
Chart1.SeriesGroups[i].Series[j].Active := not Chart1.SeriesGroups[i].Series[j].Active;
end;
Code: Select all
caption := 'X: ' + floattostr(X) + ' Y: ' + floattostr(Y);
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Hi stsl,
I've made some changes to the example to be mora adaptable to different chart sizes.
Yes, you can either post your files at news://www.steema.net/steema.public.attachments newsgroup or at our upload page.
I've made some changes to the example to be mora adaptable to different chart sizes.
Code: Select all
var
Form1: TForm1;
CheckBoxesSeparation, CheckBoxesSize, FirstItemTopLegend1, Leged2Top, CheckBoxesLeftMargin, CheckBoxesTopMargin: Integer;
implementation
uses Types;
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var i:Integer;
begin
Chart1.View3D := false;
for i:=0 to Chart1.SeriesCount-1 do
Chart1[i].FillSampleValues(25);
with Chart1.SeriesGroups do
begin
Chart1.SeriesList.AddGroup('Group A');
Items[0].Add(Chart1[0]);
Items[0].Add(Chart1[1]);
Chart1.SeriesList.AddGroup('Group B');
Items[1].Add(Chart1[2]);
Items[1].Add(Chart1[3]);
end;
Chart1.Legend.CheckBoxes:=True;
CheckBoxesSeparation := 17;
CheckBoxesSize := 12;
CheckBoxesLeftMargin := 4;
CheckBoxesTopMargin := 5;
Leged2Top := 125;
end;
procedure TForm1.Chart1AfterDraw(Sender: TObject);
begin
Chart1.Legend.Top := Leged2Top;
Chart1.Legend.LegendStyle := lsSeriesGroups;
Chart1.Legend.DrawLegend;
end;
procedure TForm1.Chart1BeforeDrawChart(Sender: TObject);
begin
Chart1.Legend.CustomPosition := False;
Chart1.Legend.LegendStyle := lsSeries;
end;
procedure TForm1.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var i, j: Integer;
begin
Chart1.Canvas.Pen.Color := clRed;
for i:=0 to Chart1.SeriesCount-1 do
begin
if ((X > Chart1.Legend.Left + CheckBoxesLeftMargin) and
(X < Chart1.Legend.Left + CheckBoxesLeftMargin + CheckBoxesSize)) then
if ((Y > FirstItemTopLegend1 + (i*CheckBoxesSeparation) + CheckBoxesTopMargin) and
(Y < FirstItemTopLegend1 + (i*CheckBoxesSeparation) + CheckBoxesSize + CheckBoxesTopMargin)) then
Chart1[i].Active := not Chart1[i].Active;
// Draw rectangles to test positions
// Chart1.Canvas.Rectangle(Chart1.Legend.Left + CheckBoxesLeftMargin, FirstItemTopLegend1 + (i*CheckBoxesSeparation) + CheckBoxesTopMargin, Chart1.Legend.Left + CheckBoxesLeftMargin + CheckBoxesSize, FirstItemTopLegend1 + (i*CheckBoxesSeparation) + CheckBoxesSize + CheckBoxesTopMargin);
end;
for i:=0 to Chart1.SeriesGroups.Count-1 do
begin
if ((X > Chart1.Legend.Left + CheckBoxesLeftMargin) and
(X < Chart1.Legend.Left + CheckBoxesLeftMargin + CheckBoxesSize)) then
if ((Y > Chart1.Legend.Top + (i*CheckBoxesSeparation) + CheckBoxesTopMargin) and
(Y < Chart1.Legend.Top + (i*CheckBoxesSeparation) + CheckBoxesSize + CheckBoxesTopMargin)) then
for j:=0 to Chart1.SeriesGroups[i].Series.Count-1 do
Chart1.SeriesGroups[i].Series[j].Active := not Chart1.SeriesGroups[i].Series[j].Active;
// Draw rectangles to test positions
// Chart1.Canvas.Rectangle(Chart1.Legend.Left + CheckBoxesLeftMargin, Chart1.Legend.Top + (i*CheckBoxesSeparation) + CheckBoxesTopMargin, Chart1.Legend.Left + CheckBoxesLeftMargin + CheckBoxesSize, Chart1.Legend.Top + (i*CheckBoxesSeparation) + CheckBoxesSize + CheckBoxesTopMargin);
end;
// Show X and Y of the pixel clicked
// caption := 'X: ' + floattostr(X) + ' Y: ' + floattostr(Y);
end;
procedure TForm1.Chart1GetLegendRect(Sender: TCustomChart;
var Rect: TRect);
begin
if Rect.Top <> Leged2Top then
FirstItemTopLegend1 := Rect.Top;
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Thank you for your sample.
I uploaded a file with your upload page (TChartLegend.zip). In this sample, i can check/unchek the second legend (group) but for the first legend (Series), i have to click at the right of the check box (and not on the check box) to uncheck/check the series. Click on the Gantt values button to add the grouped series and check the additionallegend check box to see the ExtraLegend tool.
In your sample, do you use an ExtraLegend tool or a multiple legend ?
It would be better if i could download your complete sample.
Best regards
I uploaded a file with your upload page (TChartLegend.zip). In this sample, i can check/unchek the second legend (group) but for the first legend (Series), i have to click at the right of the check box (and not on the check box) to uncheck/check the series. Click on the Gantt values button to add the grouped series and check the additionallegend check box to see the ExtraLegend tool.
In your sample, do you use an ExtraLegend tool or a multiple legend ?
It would be better if i could download your complete sample.
Best regards
Hi stsl,
In my sample I used multiple legends, but with extralegend tool it looks more simple because you can access to legend positions when you want because it's not re-written. So we won't need OnBeforeDraw, OnAfterDraw and OnGetLegendRect events.
In your project, the legend works fine for me all the time. I mean, simply adding an extralegendtool, the normal legend remains clickable. Then we only need to find the checkboxes of the extralegend and see if the click is in its area.
The following code works for me in your project:
PS: I also recommend you to change the value of CheckBoxesMargin to 5.
In my sample I used multiple legends, but with extralegend tool it looks more simple because you can access to legend positions when you want because it's not re-written. So we won't need OnBeforeDraw, OnAfterDraw and OnGetLegendRect events.
In your project, the legend works fine for me all the time. I mean, simply adding an extralegendtool, the normal legend remains clickable. Then we only need to find the checkboxes of the extralegend and see if the click is in its area.
The following code works for me in your project:
Code: Select all
procedure TForm1.ChartMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
i, j: Integer;
begin
for i:= 0 to Chart.SeriesGroups.Count - 1 do
begin
if (X > ExtraLegend.Legend.Left) and (X < ExtraLegend.Legend.Left + ExtraLegend.Legend.Width) then
begin
if (Y > ExtraLegend.Legend.Top + CheckBoxesMargin + (i * CheckBoxesSeparation)) and (Y < ExtraLegend.Legend.Top + CheckBoxesMargin + (i*CheckBoxesSeparation) + CheckBoxesSize) then
begin
outputdebugstring('Clic groups good');
if Chart.SeriesGroups[i].Active = gaYes then
Chart.SeriesGroups[i].Active := gaNo
else
Chart.SeriesGroups[i].Active := gaYes;
Exit;
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 |