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