Page 1 of 1
Legend set height
Posted: Wed Apr 30, 2014 8:22 am
by 16868859
We are using the TeeChartStandard2014 package.
I use the follwing to create a large TBarSeries series Series1.FillSampleValues(100);
The result looks like this:
- test.jpg (362.05 KiB) Viewed 7046 times
Is it possible the set a fixed height for the legend and use a custom scrollbar?
If i add a scrollbar i can navigate with Chart1.Legend.FirstValue := ScrollBarLegend.Position;
I hope I could describe the problem well.
Thanx.
Re: Legend set height
Posted: Wed Apr 30, 2014 9:15 am
by yeray
Hello Kai,
TeeChart Pro includes the TLegendScrollBar between the Chart Tools.
Here you have an example of it:
Code: Select all
uses Series, TeeLegendScrollBar;
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
with Chart1.AddSeries(TBarSeries) do
for i:=0 to 99 do
Add(i);
Chart1.Legend.Alignment:=laTop;
Chart1.Tools.Add(TLegendScrollBar);
Chart1.Legend.MaxNumRows:=4;
end;
Note this tool is designed for the default vertical Legend Alignment (aka laLeft/laRight). In an horizontal Alignment (aka alTop/alBottom), when you increment the position of the scrollbar a unit, the top-left element of the legend disappears, all the other elements move a step left (the elements on the left move a row above and to the right edge), and a new element appears on the right-bottom.
This may be better explained with two images.
Here it is how it looks when you start the application running the code above:
- 2014-04-30_1111.png (64.04 KiB) Viewed 7037 times
And this is how it looks if you press the right arrow on the legend scrollbar once:
- 2014-04-30_1112.png (64.01 KiB) Viewed 7038 times
The alternative would be draw your shapes and texts manually at OnAfterDraw event.
Re: Legend set height
Posted: Wed Apr 30, 2014 1:43 pm
by 16868859
Hello Yeray,
thank you for your answer.
If i use something like that:
Code: Select all
var
intI: Integer;
begin
ChartAccounting.Legend.Alignment := laTop;
for intI := 0 to 100 do
begin
with frmChart.ChartAccounting.AddSeries(TBarSeries) as TBarSeries do
begin
FillSampleValues(1);
end;
end;
frmChart.ChartAccounting.Draw();
end;
It looks like that:
- test.jpg (231.22 KiB) Viewed 7020 times
So the problem is that there are missing series in the legend.
How can i solve this? Thanx.
Re: Legend set height
Posted: Wed Apr 30, 2014 2:19 pm
by yeray
Hi Kai,
Kai wrote:So the problem is that there are missing series in the legend.
How can i solve this?
If you don't specify the Legend's MaxNumRows, the maximum number of rows will be 10. In the case above, to fit 101 items you'll need 21 rows:
Code: Select all
ChartAccounting.Legend.MaxNumRows:=21;
Re: Legend set height
Posted: Wed Apr 30, 2014 2:24 pm
by 16868859
Works
Thank you.
Do you have a short sample, how i can calculate the needed value of MaxNumRows?
Re: Legend set height
Posted: Wed Apr 30, 2014 2:46 pm
by yeray
Hi Kai,
Kai wrote:Do you have a short sample, how i can calculate the needed value of MaxNumRows?
We take care of a few aspects of the chart to calculate this.
This is our ItemHeight function:
Code: Select all
Function TCustomChartLegend.CalcItemHeight:Integer;
begin
result:=ParentChart.Canvas.FontHeight;
if Symbol.Visible then
if Symbol.HeightUnits=lcsPercent then
begin
if Symbol.Height>100 then
result:=Round(result*Symbol.Height*0.01);
end
else
result:=Max(result,Symbol.Height);
if HasCheckBoxes then
result:=Math.Max(6+TeeCheckBoxSize,result);
Inc(result,FVertSpacing);
if Vertical and DividingLines.Visible then
result:=result+{$IFDEF FMX}Round{$ENDIF}(DividingLines.Width);
end;
And you also need to know the YLegend. We use this FirstItemTop function for that:
Code: Select all
Function TCustomChartLegend.FirstItemTop:Integer;
begin
result:={$IFDEF FMX}Round{$ENDIF}(ShapeBounds.Top);
if Frame.Visible then
Inc(result,({$IFDEF FMX}Round{$ENDIF}(Frame.Width) div 2));
if IDrawTitle then
Inc(result,{$IFDEF FMX}Round{$ENDIF}(Title.Height)+2);
end;
Then, after having calculated this, we will be able to call our MaxLegendRows function:
Code: Select all
Function MaxLegendRows(YLegend,ItemHeight:Integer):Integer;
begin
With ParentChart do
Begin
if (YLegend<ChartRect.Bottom) and (ItemHeight>0) then
Begin
result:={$IFDEF FMX}Round{$ENDIF}(ChartHeight-FrameWidth-YLegend+ChartRect.Top) div ItemHeight;
result:=Math.Min(result,TotalLegendItems);
end
else result:=0;
end;
end;
This is how we call these functions in the Legend CalcRect function:
Code: Select all
ItemHeight:=CalcItemHeight;
//...
NumRows:=MaxLegendRows(FirstItemTop,ItemHeight);
if MaxNumRows <> 0 then
NumRows:=Math.Min(NumRows,MaxNumRows);
The above is an extract of Chart.pas, part of TeeChart sources. Being just a snipped of code means this won't probably compile in an application different than TeeChart sources but can give you an idea of what calculations you should make to emulate a similar effect.
Re: Legend set height
Posted: Fri May 02, 2014 7:06 am
by 16868859
Thank you very much. I will try it.