TAChart: Make margins only for actually existing labels.

git-svn-id: trunk@24125 -
This commit is contained in:
ask 2010-03-21 02:55:24 +00:00
parent 1d63cd7ced
commit 3b9c3db55c
2 changed files with 42 additions and 31 deletions

View File

@ -560,16 +560,22 @@ end;
procedure TBasicPointSeries.DrawLabel(
ACanvas: TCanvas; AIndex: Integer; const ADataPoint: TPoint; ADown: Boolean);
const
OFFSETS: array [Boolean] of TPoint = ((X: 0; Y: -1), (X: 0; Y: 1));
var
labelRect: TRect;
center: TPoint;
dummy: TRect = (Left: 0; Top: 0; Right: 0; Bottom: 0);
labelText: String;
sz: TSize;
begin
labelText := FormattedMark(AIndex);
if labelText = '' then exit;
labelRect := Marks.MeasureLabel(ACanvas, labelText, ADown);
OffsetRect(labelRect, ADataPoint.X, ADataPoint.Y);
sz := Marks.MeasureLabel(ACanvas, labelText);
center := ADataPoint + OFFSETS[ADown] * (Marks.Distance + sz.cy div 2);
labelRect :=
Bounds(center.X - sz.cx div 2, center.Y - sz.cy div 2, sz.cx, sz.cy);
if
not IsRectEmpty(FPrevLabelRect) and
IntersectRect(dummy, labelRect, FPrevLabelRect)
@ -579,11 +585,7 @@ begin
// Link between the label and the bar.
ACanvas.Pen.Assign(Marks.LinkPen);
with ADataPoint do
if ADown then
ACanvas.Line(X, Y, X, labelRect.Top)
else
ACanvas.Line(X, Y - 1, X, labelRect.Bottom - 1);
ACanvas.Line(ADataPoint, center);
Marks.DrawLabel(ACanvas, labelRect, labelText);
end;
@ -638,14 +640,35 @@ begin
end;
procedure TBasicPointSeries.UpdateMargins(ACanvas: TCanvas; var AMargins: TRect);
const
SOME_DIGIT = '0';
procedure MeasureLabel(const AText: String; ADir: Boolean);
const
LABEL_TO_BORDER = 4;
var
sz: TSize;
p: PInteger;
begin
if AText = '' then exit;
sz := Marks.MeasureLabel(ACanvas, AText);
if ADir then
p := @AMargins.Bottom
else
p := @AMargins.Top;
p^ := Max(p^, sz.cy + Marks.Distance + LABEL_TO_BORDER);
end;
var
h: Integer;
g: TDoublePoint;
i: Integer;
begin
h := ACanvas.TextHeight(SOME_DIGIT) + Marks.Distance + 2 * MARKS_MARGIN_Y + 4;
AMargins.Top := Max(AMargins.Top, h);
AMargins.Bottom := Max(AMargins.Bottom, h);
if not Marks.IsMarkLabelsVisible then exit;
for i := 0 to Count - 1 do begin
g := GetGraphPoint(i);
with ParentChart do
if IsPointInViewPort(g) then begin
MeasureLabel(FormattedMark(i), GetLabelDirection(g));
end;
end;
FPrevLabelRect := Rect(0, 0, 0, 0);
end;

View File

@ -28,7 +28,7 @@ unit TATypes;
interface
uses
Classes, SysUtils, Graphics, Controls, FPCanvas,
Classes, SysUtils, Graphics, Controls, FPCanvas, Types,
TAChartUtils;
const
@ -144,8 +144,7 @@ type
procedure DrawLabel(
ACanvas: TCanvas; const ALabelRect: TRect; const AText: String);
function IsMarkLabelsVisible: Boolean;
function MeasureLabel(
ACanvas: TCanvas; const AText: String; ADown: Boolean): TRect;
function MeasureLabel(ACanvas: TCanvas; const AText: String): TSize;
published
// If false, labels may overlap axises and legend.
property Clipped: Boolean read FClipped write SetClipped default true;
@ -245,9 +244,6 @@ type
implementation
uses
Types;
{ TChartPen }
procedure TChartPen.Assign(Source: TPersistent);
@ -444,20 +440,12 @@ begin
Result := Visible and (Style <> smsNone) and (Format <> '');
end;
function TChartMarks.MeasureLabel(
ACanvas: TCanvas; const AText: String; ADown: Boolean): TRect;
var
labelSize: TSize;
function TChartMarks.MeasureLabel(ACanvas: TCanvas; const AText: String): TSize;
begin
ACanvas.Font.Assign(LabelFont);
labelSize := ACanvas.TextExtent(AText);
Result.Left := - labelSize.cx div 2;
if ADown then
Result.Top := Distance
else
Result.Top := - Distance - labelSize.cy;
Result.BottomRight := Result.TopLeft + labelSize;
InflateRect(Result, MARKS_MARGIN_X, MARKS_MARGIN_Y);
Result := ACanvas.TextExtent(AText);
Result.cx += 2 * MARKS_MARGIN_X;
Result.cy += 2 * MARKS_MARGIN_Y;
end;
procedure TChartMarks.SetClipped(const AValue: Boolean);