TAChart: Precisely calculate extra distance to pie series labels. Partially fixes issue #17988

git-svn-id: trunk@28368 -
This commit is contained in:
ask 2010-11-20 12:09:15 +00:00
parent 18a4dea1a7
commit b1578e5dac
2 changed files with 29 additions and 6 deletions

View File

@ -245,7 +245,8 @@ function ProjToRect(
function RectIntersectsRect(
var ARect: TDoubleRect; const AFixed: TDoubleRect): Boolean;
function RotatePoint(const APoint: TPoint; AAngle: Double): TPoint;
function RotatePoint(const APoint: TDoublePoint; AAngle: Double): TDoublePoint; overload;
function RotatePoint(const APoint: TPoint; AAngle: Double): TPoint; overload;
function RoundChecked(A: Double): Integer; inline;
function SafeInRange(AValue, ABound1, ABound2: Double): Boolean;
@ -693,6 +694,15 @@ begin
RangesIntersect(a.Y, b.Y, AFixed.a.Y, AFixed.b.Y, a.Y, b.Y);
end;
function RotatePoint(const APoint: TDoublePoint; AAngle: Double): TDoublePoint;
var
sa, ca: Extended;
begin
SinCos(AAngle, sa, ca);
Result.X := ca * APoint.X - sa * APoint.Y;
Result.Y := sa * APoint.X + ca * APoint.Y;
end;
function RotatePoint(const APoint: TPoint; AAngle: Double): TPoint;
var
sa, ca: Extended;

View File

@ -895,12 +895,28 @@ var
ARadius := Trunc(ARadius / (Max(Source.Extent.b.X, 0) + 1));
end;
function LabelExtraDist(AAngle: Double; AIndex: Integer): Double;
const
ALMOST_INF = 1e10;
var
z, e: TDoublePoint;
r: TDoubleRect;
begin
z := ZeroDoublePoint;
e := RotatePoint(DoublePoint(ALMOST_INF, 0), AAngle + Pi);
r.a.X := -labelWidths[AIndex] / 2;
r.b.X := -r.a.X;
r.a.Y := -labelHeights[AIndex] / 2;
r.b.Y := -r.a.Y;
LineIntersectsRect(z, e, r);
Result := Norm([e.X, e.Y]);
end;
var
i, radius: Integer;
prevAngle: Double = 0;
d, angleStep, sliceCenterAngle: Double;
c, center: TPoint;
sa, ca: Extended;
prevLabelPoly: TPointArray = nil;
const
RAD_TO_DEG16 = 360 * 16;
@ -929,10 +945,7 @@ begin
prevAngle += angleStep;
if not Marks.IsMarkLabelsVisible then continue;
// This is a crude approximation of label "radius", it may be improved.
SinCos(DegToRad(sliceCenterAngle / 16), sa, ca);
d := Max(Abs(labelWidths[i] * ca), Abs(labelHeights[i] * sa)) / 2;
d := LabelExtraDist(DegToRad(sliceCenterAngle / 16), i);
Marks.DrawLabel(
ACanvas,
LineEndPoint(c, sliceCenterAngle, radius),