mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-23 04:39:36 +02:00
TAChart: Add Marks.YIndex property, implement labels for stacked series
git-svn-id: trunk@30588 -
This commit is contained in:
parent
88a88c1b2b
commit
553a073919
@ -165,7 +165,7 @@ type
|
||||
function Count: Integer; inline;
|
||||
procedure Delete(AIndex: Integer); virtual;
|
||||
function Extent: TDoubleRect; virtual;
|
||||
function FormattedMark(AIndex: Integer): String;
|
||||
function FormattedMark(AIndex: Integer; AYIndex: Integer = 0): String;
|
||||
function IsEmpty: Boolean; override;
|
||||
function ListSource: TListChartSource;
|
||||
property Source: TCustomChartSource
|
||||
@ -192,7 +192,6 @@ type
|
||||
function GetLabelDirection(AIndex: Integer): TLabelDirection;
|
||||
procedure SetMarkPositions(AValue: TLinearMarkPositions);
|
||||
procedure SetUseReticule(AValue: Boolean);
|
||||
|
||||
protected
|
||||
FGraphPoints: array of TDoublePoint;
|
||||
FLoBound: Integer;
|
||||
@ -555,12 +554,12 @@ begin
|
||||
Result := Source.ExtentCumulative;
|
||||
end;
|
||||
|
||||
function TChartSeries.FormattedMark(AIndex: integer): String;
|
||||
function TChartSeries.FormattedMark(AIndex, AYIndex: Integer): String;
|
||||
begin
|
||||
if Assigned(FOnGetMark) then
|
||||
FOnGetMark(Result, AIndex)
|
||||
else
|
||||
Result := Source.FormatItem(Marks.Format, AIndex);
|
||||
Result := Source.FormatItem(Marks.Format, AIndex, AYIndex);
|
||||
end;
|
||||
|
||||
procedure TChartSeries.GetBounds(var ABounds: TDoubleRect);
|
||||
@ -767,14 +766,26 @@ var
|
||||
|
||||
var
|
||||
g: TDoublePoint;
|
||||
i: Integer;
|
||||
i, si: Integer;
|
||||
ld: TLabelDirection;
|
||||
begin
|
||||
if not Marks.IsMarkLabelsVisible then exit;
|
||||
for i := 0 to Count - 1 do begin
|
||||
g := GetGraphPoint(i);
|
||||
with ParentChart do
|
||||
if IsPointInViewPort(g) then
|
||||
DrawLabel(FormattedMark(i), GraphToImage(g), GetLabelDirection(i));
|
||||
ld := GetLabelDirection(i);
|
||||
for si := 0 to Source.YCount - 1 do begin
|
||||
if si > 0 then
|
||||
if IsRotated then
|
||||
g.X += AxisToGraphY(Source[i]^.YList[si - 1])
|
||||
else
|
||||
g.Y += AxisToGraphY(Source[i]^.YList[si - 1]);
|
||||
with ParentChart do
|
||||
if
|
||||
(Marks.YIndex = MARKS_YINDEX_ALL) or (Marks.YIndex = si) and
|
||||
IsPointInViewPort(g)
|
||||
then
|
||||
DrawLabel(FormattedMark(i, si), GraphToImage(g), ld);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -32,11 +32,15 @@ type
|
||||
// Like TColor, but avoiding dependency on Graphics.
|
||||
TChartColor = -$7FFFFFFF-1..$7FFFFFFF;
|
||||
|
||||
TChartDataItem = record
|
||||
{ TChartDataItem }
|
||||
|
||||
TChartDataItem = object
|
||||
public
|
||||
X, Y: Double;
|
||||
Color: TChartColor;
|
||||
Text: String;
|
||||
YList: TDoubleDynArray;
|
||||
function GetY(AIndex: Integer): Double;
|
||||
end;
|
||||
PChartDataItem = ^TChartDataItem;
|
||||
|
||||
@ -73,7 +77,8 @@ type
|
||||
function ExtentCumulative: TDoubleRect;
|
||||
function ExtentList: TDoubleRect;
|
||||
procedure FindBounds(AXMin, AXMax: Double; out ALB, AUB: Integer);
|
||||
function FormatItem(const AFormat: String; AIndex: Integer): String;
|
||||
function FormatItem(
|
||||
const AFormat: String; AIndex, AYIndex: Integer): String;
|
||||
function IsSorted: Boolean; virtual;
|
||||
procedure ValuesInRange(
|
||||
AMin, AMax: Double; const AFormat: String; AUseY: Boolean;
|
||||
@ -130,6 +135,17 @@ begin
|
||||
AItem.YList[i] := 0;
|
||||
end;
|
||||
|
||||
{ TChartDataItem }
|
||||
|
||||
function TChartDataItem.GetY(AIndex: Integer): Double;
|
||||
begin
|
||||
AIndex := EnsureRange(AIndex, 0, Length(YList));
|
||||
if AIndex = 0 then
|
||||
Result := Y
|
||||
else
|
||||
Result := YList[AIndex - 1];
|
||||
end;
|
||||
|
||||
{ TChartSourceBuffer }
|
||||
|
||||
procedure TChartSourceBuffer.AddFirst(const AItem: TChartDataItem);
|
||||
@ -357,19 +373,20 @@ begin
|
||||
end;
|
||||
|
||||
function TCustomChartSource.FormatItem(
|
||||
const AFormat: String; AIndex: Integer): String;
|
||||
const AFormat: String; AIndex, AYIndex: Integer): String;
|
||||
const
|
||||
TO_PERCENT = 100;
|
||||
var
|
||||
total, percent: Double;
|
||||
total, percent, vy: Double;
|
||||
begin
|
||||
total := ValuesTotal;
|
||||
if total = 0 then
|
||||
percent := 0
|
||||
else
|
||||
percent := TO_PERCENT / total;
|
||||
with Item[AIndex]^ do begin
|
||||
if total = 0 then
|
||||
percent := 0
|
||||
else
|
||||
percent := Y / total * TO_PERCENT;
|
||||
Result := Format(AFormat, [y, percent, Text, total, X]);
|
||||
vy := GetY(AYIndex);
|
||||
Result := Format(AFormat, [vy, vy * percent, Text, total, X]);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -409,7 +426,7 @@ begin
|
||||
v := IfThen(AUseY, Item[i]^.Y, Item[i]^.X);
|
||||
if not InRange(v, AMin, AMax) then continue;
|
||||
AValues[cnt] := v;
|
||||
ATexts[cnt] := FormatItem(AFormat, i);
|
||||
ATexts[cnt] := FormatItem(AFormat, i, 0);
|
||||
cnt += 1;
|
||||
end;
|
||||
SetLength(AValues, cnt);
|
||||
|
@ -1089,7 +1089,6 @@ begin
|
||||
for i := 1 to n2 - 2 do
|
||||
ADrawer.DrawLineDepth(pts[i], pts[i + 1], Depth);
|
||||
ADrawer.Polygon(pts, 0, numPts);
|
||||
DrawLabels(ADrawer);
|
||||
end;
|
||||
if AreaLinesPen.Style <> psClear then begin
|
||||
ADrawer.Pen := AreaLinesPen;
|
||||
@ -1099,6 +1098,7 @@ begin
|
||||
ADrawer.Line(ParentChart.GraphToImage(a), ParentChart.GraphToImage(b));
|
||||
end;
|
||||
end;
|
||||
DrawLabels(ADrawer);
|
||||
end;
|
||||
|
||||
function TAreaSeries.Extent: TDoubleRect;
|
||||
|
@ -37,6 +37,7 @@ const
|
||||
DEF_MARGIN = 4;
|
||||
DEF_MARKS_DISTANCE = 20;
|
||||
DEF_POINTER_SIZE = 4;
|
||||
MARKS_YINDEX_ALL = -1;
|
||||
|
||||
type
|
||||
TCustomChart = class(TCustomControl)
|
||||
@ -130,12 +131,14 @@ type
|
||||
TGenericChartMarks = class(TChartElement)
|
||||
{$ENDIF}
|
||||
private
|
||||
FYIndex: Integer;
|
||||
procedure AddMargins(ADrawer: IChartDrawer; var ASize: TPoint);
|
||||
function GetDistanceToCenter: Boolean;
|
||||
function LabelAngle: Double; inline;
|
||||
procedure PutLabelFontTo(ADrawer: IChartDrawer);
|
||||
procedure SetAttachment(AValue: TChartMarkAttachment);
|
||||
procedure SetDistanceToCenter(AValue: Boolean);
|
||||
procedure SetYIndex(AValue: Integer);
|
||||
protected
|
||||
FAdditionalAngle: Double;
|
||||
FAttachment: TChartMarkAttachment;
|
||||
@ -194,6 +197,7 @@ type
|
||||
property Distance: TChartDistance read FDistance write SetDistance;
|
||||
property LabelFont: TFont read FLabelFont write SetLabelFont;
|
||||
property Visible default true;
|
||||
property YIndex: Integer read FYIndex write SetYIndex default 0;
|
||||
end;
|
||||
|
||||
TChartLinkPen = class(TChartPen)
|
||||
@ -728,6 +732,13 @@ begin
|
||||
StyleChanged(Self);
|
||||
end;
|
||||
|
||||
procedure TGenericChartMarks.SetYIndex(AValue: Integer);
|
||||
begin
|
||||
if FYIndex = AValue then exit;
|
||||
FYIndex := AValue;
|
||||
StyleChanged(Self);
|
||||
end;
|
||||
|
||||
{ TChartMarks }
|
||||
|
||||
procedure TChartMarks.Assign(Source: TPersistent);
|
||||
|
Loading…
Reference in New Issue
Block a user