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