mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-08 14:56:20 +02:00
TAChart: Add TChartAxisMarks.AtDataOnly property
git-svn-id: trunk@26930 -
This commit is contained in:
parent
c3e010c4ba
commit
0e1bfb75c2
@ -88,10 +88,13 @@ type
|
|||||||
TChartAxisMarks = class(
|
TChartAxisMarks = class(
|
||||||
specialize TGenericChartMarks<TChartAxisBrush, TChartPen, TChartAxisFramePen>)
|
specialize TGenericChartMarks<TChartAxisBrush, TChartPen, TChartAxisFramePen>)
|
||||||
private
|
private
|
||||||
|
FAtDataOnly: Boolean;
|
||||||
FDefaultSource: TIntervalChartSource;
|
FDefaultSource: TIntervalChartSource;
|
||||||
FListener: TListener;
|
FListener: TListener;
|
||||||
FSource: TCustomChartSource;
|
FSource: TCustomChartSource;
|
||||||
|
|
||||||
function IsFormatStored: Boolean;
|
function IsFormatStored: Boolean;
|
||||||
|
procedure SetAtDataOnly(AValue: Boolean);
|
||||||
procedure SetSource(AValue: TCustomChartSource);
|
procedure SetSource(AValue: TCustomChartSource);
|
||||||
public
|
public
|
||||||
constructor Create(AOwner: TCustomChart);
|
constructor Create(AOwner: TCustomChart);
|
||||||
@ -99,6 +102,8 @@ type
|
|||||||
|
|
||||||
function SourceDef: TCustomChartSource;
|
function SourceDef: TCustomChartSource;
|
||||||
published
|
published
|
||||||
|
property AtDataOnly: Boolean
|
||||||
|
read FAtDataOnly write SetAtDataOnly default false;
|
||||||
property Distance default 1;
|
property Distance default 1;
|
||||||
property Format stored IsFormatStored;
|
property Format stored IsFormatStored;
|
||||||
property Frame;
|
property Frame;
|
||||||
@ -118,6 +123,7 @@ type
|
|||||||
FSize: Integer;
|
FSize: Integer;
|
||||||
FTitleSize: Integer;
|
FTitleSize: Integer;
|
||||||
|
|
||||||
|
procedure VisitSource(ASource: TCustomChartSource; var AData);
|
||||||
procedure GetMarkValues(AMin, AMax: Double);
|
procedure GetMarkValues(AMin, AMax: Double);
|
||||||
private
|
private
|
||||||
FAlignment: TChartAxisAlignment;
|
FAlignment: TChartAxisAlignment;
|
||||||
@ -179,11 +185,17 @@ type
|
|||||||
read FOnMarkToText write SetOnMarkToText;
|
read FOnMarkToText write SetOnMarkToText;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TChartOnSourceVisitor =
|
||||||
|
procedure (ASource: TCustomChartSource; var AData) of object;
|
||||||
|
TChartOnVisitSources = procedure (
|
||||||
|
AVisitor: TChartOnSourceVisitor; AAxis: TChartAxis; var AData) of object;
|
||||||
|
|
||||||
{ TChartAxisList }
|
{ TChartAxisList }
|
||||||
|
|
||||||
TChartAxisList = class(TCollection)
|
TChartAxisList = class(TCollection)
|
||||||
private
|
private
|
||||||
FChart: TCustomChart;
|
FChart: TCustomChart;
|
||||||
|
FOnVisitSources: TChartOnVisitSources;
|
||||||
function GetAxes(AIndex: Integer): TChartAxis;
|
function GetAxes(AIndex: Integer): TChartAxis;
|
||||||
protected
|
protected
|
||||||
function GetOwner: TPersistent; override;
|
function GetOwner: TPersistent; override;
|
||||||
@ -197,6 +209,8 @@ type
|
|||||||
property Axes[AIndex: Integer]: TChartAxis read GetAxes; default;
|
property Axes[AIndex: Integer]: TChartAxis read GetAxes; default;
|
||||||
property BottomAxis: TChartAxis index 1 read GetAxis write SetAxis;
|
property BottomAxis: TChartAxis index 1 read GetAxis write SetAxis;
|
||||||
property LeftAxis: TChartAxis index 2 read GetAxis write SetAxis;
|
property LeftAxis: TChartAxis index 2 read GetAxis write SetAxis;
|
||||||
|
property OnVisitSources: TChartOnVisitSources
|
||||||
|
read FOnVisitSources write FOnVisitSources;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function SideByAlignment(
|
function SideByAlignment(
|
||||||
@ -209,6 +223,11 @@ implementation
|
|||||||
uses
|
uses
|
||||||
LResources, Math, PropEdits, TADrawUtils;
|
LResources, Math, PropEdits, TADrawUtils;
|
||||||
|
|
||||||
|
type
|
||||||
|
TAxisDataExtent = record
|
||||||
|
FMin, FMax: Double;
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
VIdentityTransform: TChartAxisTransformations;
|
VIdentityTransform: TChartAxisTransformations;
|
||||||
|
|
||||||
@ -295,6 +314,13 @@ begin
|
|||||||
Result := FStyle <> smsValue;
|
Result := FStyle <> smsValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TChartAxisMarks.SetAtDataOnly(AValue: Boolean);
|
||||||
|
begin
|
||||||
|
if FAtDataOnly = AValue then exit;
|
||||||
|
FAtDataOnly := AValue;
|
||||||
|
StyleChanged(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TChartAxisMarks.SetSource(AValue: TCustomChartSource);
|
procedure TChartAxisMarks.SetSource(AValue: TCustomChartSource);
|
||||||
begin
|
begin
|
||||||
if FSource = AValue then exit;
|
if FSource = AValue then exit;
|
||||||
@ -462,12 +488,23 @@ end;
|
|||||||
procedure TChartAxis.GetMarkValues(AMin, AMax: Double);
|
procedure TChartAxis.GetMarkValues(AMin, AMax: Double);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
d: TAxisDataExtent;
|
||||||
|
vis: TChartOnVisitSources;
|
||||||
begin
|
begin
|
||||||
AMin := GetTransform.GraphToAxis(AMin);
|
AMin := GetTransform.GraphToAxis(AMin);
|
||||||
AMax := GetTransform.GraphToAxis(AMax);
|
AMax := GetTransform.GraphToAxis(AMax);
|
||||||
EnsureOrder(AMin, AMax);
|
EnsureOrder(AMin, AMax);
|
||||||
Marks.SourceDef.ValuesInRange(
|
SetLength(FMarkValues, 0);
|
||||||
AMin, AMax, Marks.Format, IsVertical, FMarkValues, FMarkTexts);
|
SetLength(FMarkTexts, 0);
|
||||||
|
vis := TChartAxisList(Collection).OnVisitSources;
|
||||||
|
if Marks.AtDataOnly and Assigned(vis) then begin
|
||||||
|
d.FMin := AMin;
|
||||||
|
d.FMax := AMax;
|
||||||
|
vis(@VisitSource, Self, d);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Marks.SourceDef.ValuesInRange(
|
||||||
|
AMin, AMax, Marks.Format, IsVertical, FMarkValues, FMarkTexts);
|
||||||
if Inverted then
|
if Inverted then
|
||||||
for i := 0 to High(FMarkValues) div 2 do begin
|
for i := 0 to High(FMarkValues) div 2 do begin
|
||||||
Exchange(FMarkValues[i], FMarkValues[High(FMarkValues) - i]);
|
Exchange(FMarkValues[i], FMarkValues[High(FMarkValues) - i]);
|
||||||
@ -626,6 +663,26 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TChartAxis.VisitSource(ASource: TCustomChartSource; var AData);
|
||||||
|
var
|
||||||
|
lmin, lmax: Double;
|
||||||
|
ext: TDoubleRect;
|
||||||
|
begin
|
||||||
|
ext := ASource.Extent;
|
||||||
|
with TAxisDataExtent(AData) do begin
|
||||||
|
if IsVertical then begin
|
||||||
|
lmin := Max(ext.a.Y, FMin);
|
||||||
|
lmax := Min(ext.b.Y, FMax);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
lmin := Max(ext.a.X, FMin);
|
||||||
|
lmax := Min(ext.b.X, FMax);
|
||||||
|
end;
|
||||||
|
Marks.SourceDef.ValuesInRange(
|
||||||
|
lmin, lmax, Marks.Format, IsVertical, FMarkValues, FMarkTexts);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
const
|
const
|
||||||
AXIS_INDEX: array [1..2] of TChartAxisAlignment = (calBottom, calLeft);
|
AXIS_INDEX: array [1..2] of TChartAxisAlignment = (calBottom, calLeft);
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, Graphics, SysUtils,
|
Classes, Graphics, SysUtils,
|
||||||
TAChartUtils, TAGraph, TASources, TATypes;
|
TAChartAxis, TAChartUtils, TAGraph, TASources, TATypes;
|
||||||
|
|
||||||
const
|
const
|
||||||
DEF_AXIS_INDEX = -1;
|
DEF_AXIS_INDEX = -1;
|
||||||
@ -60,6 +60,8 @@ type
|
|||||||
function AxisToGraph(const APoint: TDoublePoint): TDoublePoint;
|
function AxisToGraph(const APoint: TDoublePoint): TDoublePoint;
|
||||||
function AxisToGraphX(AX: Double): Double; override;
|
function AxisToGraphX(AX: Double): Double; override;
|
||||||
function AxisToGraphY(AY: Double): Double; override;
|
function AxisToGraphY(AY: Double): Double; override;
|
||||||
|
function GetAxisX: TChartAxis;
|
||||||
|
function GetAxisY: TChartAxis;
|
||||||
function GraphToAxisX(AX: Double): Double; override;
|
function GraphToAxisX(AX: Double): Double; override;
|
||||||
function GraphToAxisY(AY: Double): Double; override;
|
function GraphToAxisY(AY: Double): Double; override;
|
||||||
|
|
||||||
@ -103,6 +105,8 @@ type
|
|||||||
function GetGraphPointY(AIndex: Integer): Double; inline;
|
function GetGraphPointY(AIndex: Integer): Double; inline;
|
||||||
function GetSeriesColor: TColor; virtual;
|
function GetSeriesColor: TColor; virtual;
|
||||||
function GetXMaxVal: Integer;
|
function GetXMaxVal: Integer;
|
||||||
|
procedure VisitSources(
|
||||||
|
AVisitor: TChartOnSourceVisitor; AAxis: TChartAxis; var AData); override;
|
||||||
public
|
public
|
||||||
constructor Create(AOwner: TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@ -124,7 +128,8 @@ type
|
|||||||
procedure SetYValue(AIndex: Integer; AValue: Double); inline;
|
procedure SetYValue(AIndex: Integer; AValue: Double); inline;
|
||||||
public
|
public
|
||||||
function Add(AValue: Double; XLabel: String; Color: TColor): Integer; inline;
|
function Add(AValue: Double; XLabel: String; Color: TColor): Integer; inline;
|
||||||
function AddXY(X, Y: Double; XLabel: String; Color: TColor): Integer; virtual; overload;
|
function AddXY(
|
||||||
|
X, Y: Double; XLabel: String; Color: TColor): Integer; virtual; overload;
|
||||||
function AddXY(X, Y: Double): Integer; overload; inline;
|
function AddXY(X, Y: Double): Integer; overload; inline;
|
||||||
procedure Clear; inline;
|
procedure Clear; inline;
|
||||||
function Count: Integer; inline;
|
function Count: Integer; inline;
|
||||||
@ -148,7 +153,7 @@ type
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Math, TAChartAxis;
|
Math;
|
||||||
|
|
||||||
{ TCustomChartSeries }
|
{ TCustomChartSeries }
|
||||||
|
|
||||||
@ -179,6 +184,22 @@ begin
|
|||||||
FAxisIndexY := DEF_AXIS_INDEX;
|
FAxisIndexY := DEF_AXIS_INDEX;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCustomChartSeries.GetAxisX: TChartAxis;
|
||||||
|
begin
|
||||||
|
if InRange(AxisIndexX, 0, FChart.AxisList.Count - 1) then
|
||||||
|
Result := FChart.AxisList[AxisIndexX]
|
||||||
|
else
|
||||||
|
Result := FChart.BottomAxis;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCustomChartSeries.GetAxisY: TChartAxis;
|
||||||
|
begin
|
||||||
|
if InRange(AxisIndexY, 0, FChart.AxisList.Count - 1) then
|
||||||
|
Result := FChart.AxisList[AxisIndexY]
|
||||||
|
else
|
||||||
|
Result := FChart.LeftAxis;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCustomChartSeries.GetGraphBounds(var ABounds: TDoubleRect);
|
procedure TCustomChartSeries.GetGraphBounds(var ABounds: TDoubleRect);
|
||||||
begin
|
begin
|
||||||
GetBounds(ABounds);
|
GetBounds(ABounds);
|
||||||
@ -544,5 +565,12 @@ begin
|
|||||||
ListSource.SetYValue(AIndex, AValue);
|
ListSource.SetYValue(AIndex, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TChartSeries.VisitSources(
|
||||||
|
AVisitor: TChartOnSourceVisitor; AAxis: TChartAxis; var AData);
|
||||||
|
begin
|
||||||
|
if (AAxis = GetAxisX) or (AAxis = GetAxisY) then
|
||||||
|
AVisitor(Source, AData);
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -65,6 +65,8 @@ type
|
|||||||
procedure SetShowInLegend(AValue: Boolean); virtual; abstract;
|
procedure SetShowInLegend(AValue: Boolean); virtual; abstract;
|
||||||
procedure SetZPosition(AValue: TChartDistance); virtual; abstract;
|
procedure SetZPosition(AValue: TChartDistance); virtual; abstract;
|
||||||
procedure UpdateMargins(ACanvas: TCanvas; var AMargins: TRect); virtual;
|
procedure UpdateMargins(ACanvas: TCanvas; var AMargins: TRect); virtual;
|
||||||
|
procedure VisitSources(
|
||||||
|
AVisitor: TChartOnSourceVisitor; AAxis: TChartAxis; var AData); virtual;
|
||||||
|
|
||||||
protected
|
protected
|
||||||
function AxisToGraphX(AX: Double): Double; virtual;
|
function AxisToGraphX(AX: Double): Double; virtual;
|
||||||
@ -196,6 +198,8 @@ type
|
|||||||
procedure SetTitle(Value: TChartTitle);
|
procedure SetTitle(Value: TChartTitle);
|
||||||
procedure SetToolset(const AValue: TBasicChartToolset);
|
procedure SetToolset(const AValue: TBasicChartToolset);
|
||||||
procedure UpdateExtent;
|
procedure UpdateExtent;
|
||||||
|
procedure VisitSources(
|
||||||
|
AVisitor: TChartOnSourceVisitor; AAxis: TChartAxis; var AData);
|
||||||
protected
|
protected
|
||||||
procedure Clean(ACanvas: TCanvas; ARect: TRect);
|
procedure Clean(ACanvas: TCanvas; ARect: TRect);
|
||||||
procedure DisplaySeries(ACanvas: TCanvas);
|
procedure DisplaySeries(ACanvas: TCanvas);
|
||||||
@ -389,6 +393,7 @@ begin
|
|||||||
FFoot := TChartTitle.Create(Self);
|
FFoot := TChartTitle.Create(Self);
|
||||||
|
|
||||||
FAxisList := TChartAxisList.Create(Self);
|
FAxisList := TChartAxisList.Create(Self);
|
||||||
|
FAxisList.OnVisitSources := @VisitSources;
|
||||||
with TChartAxis.Create(FAxisList) do begin
|
with TChartAxis.Create(FAxisList) do begin
|
||||||
Alignment := calLeft;
|
Alignment := calLeft;
|
||||||
Title.LabelFont.Orientation := FONT_VERTICAL;
|
Title.LabelFont.Orientation := FONT_VERTICAL;
|
||||||
@ -1067,6 +1072,17 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TChart.VisitSources(
|
||||||
|
AVisitor: TChartOnSourceVisitor; AAxis: TChartAxis; var AData);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
for i := 0 to SeriesCount - 1 do
|
||||||
|
with Series[i] do
|
||||||
|
if Active then
|
||||||
|
VisitSources(AVisitor, AAxis, AData);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TChart.ZoomFull;
|
procedure TChart.ZoomFull;
|
||||||
begin
|
begin
|
||||||
if not FIsZoomed then exit;
|
if not FIsZoomed then exit;
|
||||||
@ -1142,6 +1158,13 @@ begin
|
|||||||
Unused(ACanvas, AMargins);
|
Unused(ACanvas, AMargins);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TBasicChartSeries.VisitSources(
|
||||||
|
AVisitor: TChartOnSourceVisitor; AAxis: TChartAxis; var AData);
|
||||||
|
begin
|
||||||
|
Unused(AVisitor, AAxis);
|
||||||
|
Unused(AData);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TChartSeriesList }
|
{ TChartSeriesList }
|
||||||
|
|
||||||
procedure TChartSeriesList.Clear;
|
procedure TChartSeriesList.Clear;
|
||||||
|
@ -69,7 +69,7 @@ type
|
|||||||
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;
|
||||||
out AValues: TDoubleDynArray; out ATexts: TStringDynArray); virtual;
|
var AValues: TDoubleDynArray; var ATexts: TStringDynArray); virtual;
|
||||||
function ValuesTotal: Double; virtual;
|
function ValuesTotal: Double; virtual;
|
||||||
function XOfMax: Double;
|
function XOfMax: Double;
|
||||||
function XOfMin: Double;
|
function XOfMin: Double;
|
||||||
@ -181,7 +181,7 @@ type
|
|||||||
public
|
public
|
||||||
procedure ValuesInRange(
|
procedure ValuesInRange(
|
||||||
AMin, AMax: Double; const AFormat: String; AUseY: Boolean;
|
AMin, AMax: Double; const AFormat: String; AUseY: Boolean;
|
||||||
out AValues: TDoubleDynArray; out ATexts: TStringDynArray); override;
|
var AValues: TDoubleDynArray; var ATexts: TStringDynArray); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TUserDefinedChartSource = class;
|
TUserDefinedChartSource = class;
|
||||||
@ -397,14 +397,14 @@ end;
|
|||||||
|
|
||||||
procedure TCustomChartSource.ValuesInRange(
|
procedure TCustomChartSource.ValuesInRange(
|
||||||
AMin, AMax: Double; const AFormat: String; AUseY: Boolean;
|
AMin, AMax: Double; const AFormat: String; AUseY: Boolean;
|
||||||
out AValues: TDoubleDynArray; out ATexts: TStringDynArray);
|
var AValues: TDoubleDynArray; var ATexts: TStringDynArray);
|
||||||
var
|
var
|
||||||
i, cnt: Integer;
|
i, cnt: Integer;
|
||||||
v: Double;
|
v: Double;
|
||||||
begin
|
begin
|
||||||
cnt := 0;
|
cnt := Length(AValues);
|
||||||
SetLength(AValues, Count);
|
SetLength(AValues, cnt + Count);
|
||||||
SetLength(ATexts, Count);
|
SetLength(ATexts, cnt + Count);
|
||||||
for i := 0 to Count - 1 do begin
|
for i := 0 to Count - 1 do 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;
|
||||||
@ -901,11 +901,12 @@ end;
|
|||||||
|
|
||||||
procedure TIntervalChartSource.ValuesInRange(
|
procedure TIntervalChartSource.ValuesInRange(
|
||||||
AMin, AMax: Double; const AFormat: String; AUseY: Boolean;
|
AMin, AMax: Double; const AFormat: String; AUseY: Boolean;
|
||||||
out AValues: TDoubleDynArray; out ATexts: TStringDynArray);
|
var AValues: TDoubleDynArray; var ATexts: TStringDynArray);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
Unused(AUseY);
|
Unused(AUseY);
|
||||||
|
if AMin > AMax then exit;
|
||||||
AValues := GetIntervals(AMin, AMax, false);
|
AValues := GetIntervals(AMin, AMax, false);
|
||||||
SetLength(ATexts, Length(AValues));
|
SetLength(ATexts, Length(AValues));
|
||||||
for i := 0 to High(AValues) do
|
for i := 0 to High(AValues) do
|
||||||
|
Loading…
Reference in New Issue
Block a user