TAChart: Add TChartAxisMarks.AtDataOnly property

git-svn-id: trunk@26930 -
This commit is contained in:
ask 2010-07-31 13:35:24 +00:00
parent c3e010c4ba
commit 0e1bfb75c2
4 changed files with 121 additions and 12 deletions

View File

@ -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);

View File

@ -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.

View File

@ -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;

View File

@ -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