TAChart: Support ChartAxis.Position cuAxis. For this, add OrthogonalAxisIndex property and corresponding property editor.

This commit is contained in:
wp_xyz 2024-03-01 00:26:45 +01:00
parent b8b0b042be
commit 105219a3b7
3 changed files with 108 additions and 15 deletions

View File

@ -10,11 +10,13 @@ implementation
uses uses
Graphics, Classes, Math, PropEdits, SysUtils, LCLIntf, typinfo, Graphics, Classes, Math, PropEdits, SysUtils, LCLIntf, typinfo,
TATypes, TADrawerCanvas, TACustomSeries, TASeries, TALegend, TATypes, TADrawerCanvas, TAChartAxis, TACustomSeries, TASeries, TALegend,
TAGraph, TAChartCombos; TAGraph, TAChartCombos;
type type
TAxisIndexPropertyEditor = class(TOrdinalPropertyEditor) TAxisIndexPropertyEditor = class(TOrdinalPropertyEditor)
protected
function GetChart: TChart; virtual;
public public
function GetAttributes: TPropertyAttributes; override; function GetAttributes: TPropertyAttributes; override;
function OrdValueToVisualValue(AOrdValue: Longint): String; override; function OrdValueToVisualValue(AOrdValue: Longint): String; override;
@ -22,6 +24,13 @@ type
procedure SetValue(const ANewValue: String); override; procedure SetValue(const ANewValue: String); override;
end; end;
TOrthogonalAxisIndexPropertyEditor = class(TAxisIndexPropertyEditor)
protected
function GetChart: TChart; override;
public
procedure GetValues(AProc: TGetStrProc); override;
end;
TSeriesPointerStylePropertyEditor = class(TEnumPropertyEditor) TSeriesPointerStylePropertyEditor = class(TEnumPropertyEditor)
private private
procedure DrawPointer(ACanvas: TCanvas; ARect: TRect; procedure DrawPointer(ACanvas: TCanvas; ARect: TRect;
@ -41,6 +50,8 @@ procedure Register;
begin begin
RegisterPropertyEditor( RegisterPropertyEditor(
TypeInfo(TChartAxisIndex), TCustomChartSeries, '', TAxisIndexPropertyEditor); TypeInfo(TChartAxisIndex), TCustomChartSeries, '', TAxisIndexPropertyEditor);
RegisterPropertyEditor(
TypeInfo(TChartAxisIndex), TChartAxis, '', TOrthogonalAxisIndexPropertyEditor);
RegisterPropertyEditor( RegisterPropertyEditor(
TypeInfo(TSeriesPointerStyle), TSeriesPointer, '', TSeriesPointerStylePropertyEditor); TypeInfo(TSeriesPointerStyle), TSeriesPointer, '', TSeriesPointerStylePropertyEditor);
RegisterPropertyEditor( RegisterPropertyEditor(
@ -54,14 +65,20 @@ begin
Result := [paMultiSelect, paValueList, paRevertable]; Result := [paMultiSelect, paValueList, paRevertable];
end; end;
procedure TAxisIndexPropertyEditor.GetValues(AProc: TGetStrProc); function TAxisIndexPropertyEditor.GetChart: TChart;
var var
s: TCustomChartSeries; s: TCustomChartSeries;
begin
s := GetComponent(0) as TCustomChartSeries;
Result := s.ParentChart;
end;
procedure TAxisIndexPropertyEditor.GetValues(AProc: TGetStrProc);
var
ch: TChart; ch: TChart;
i: Integer; i: Integer;
begin begin
s := GetComponent(0) as TCustomChartSeries; ch := GetChart;
ch := s.ParentChart;
AProc('-1 None'); AProc('-1 None');
if ch <> nil then if ch <> nil then
for i := 0 to ch.AxisList.Count - 1 do for i := 0 to ch.AxisList.Count - 1 do
@ -71,11 +88,9 @@ end;
function TAxisIndexPropertyEditor.OrdValueToVisualValue( function TAxisIndexPropertyEditor.OrdValueToVisualValue(
AOrdValue: Longint): String; AOrdValue: Longint): String;
var var
s: TCustomChartSeries;
ch: TChart; ch: TChart;
begin begin
s := GetComponent(0) as TCustomChartSeries; ch := GetChart;
ch := s.ParentChart;
Result := IntToStr(AOrdValue) + ' '; Result := IntToStr(AOrdValue) + ' ';
if Assigned(ch) and InRange(AOrdValue, 0, ch.AxisList.Count - 1) then if Assigned(ch) and InRange(AOrdValue, 0, ch.AxisList.Count - 1) then
Result += ch.AxisList[AOrdValue].DisplayName Result += ch.AxisList[AOrdValue].DisplayName
@ -95,6 +110,42 @@ begin
end; end;
{ TOrthogonalAxisIndexPropertyEditor }
function TOrthogonalAxisIndexPropertyEditor.GetChart: TChart;
var
ax: TChartAxis;
begin
ax := GetComponent(0) as TChartAxis;
Result := ax.GetChart as TChart;
end;
procedure TOrthogonalAxisIndexPropertyEditor.GetValues(AProc: TGetStrProc);
var
ax: TChartAxis;
ch: TChart;
i: Integer;
begin
ax := GetComponent(0) as TChartAxis;
ch := GetChart;
AProc('-1 None');
if ch <> nil then
begin
if ax.IsVertical then
begin
for i := 0 to ch.AxisList.Count - 1 do
if not ch.AxisList[i].IsVertical then
AProc(IntToStr(i) + ' ' + ch.AxisList[i].DisplayName)
end else
begin
for i := 0 to ch.AxisList.Count - 1 do
if ch.AxisList[i].IsVertical then
AProc(IntTostr(i) + ' ' + ch.AxisList[i].DisplayName);
end;
end;
end;
{ TSeriesPointerStylePropertyEditor } { TSeriesPointerStylePropertyEditor }
procedure TSeriesPointerStylePropertyEditor.DrawPointer(ACanvas: TCanvas; procedure TSeriesPointerStylePropertyEditor.DrawPointer(ACanvas: TCanvas;

View File

@ -23,9 +23,12 @@ uses
const const
DEF_TICK_LENGTH = 4; DEF_TICK_LENGTH = 4;
DEF_TICK_WIDTH = 1; DEF_TICK_WIDTH = 1;
DEF_AXIS_INDEX = -1;
type type
TChartAxisIndex = -1..MaxInt;
{ TChartMinorAxis } { TChartMinorAxis }
TChartMinorAxis = class(TChartBasicAxis) TChartMinorAxis = class(TChartBasicAxis)
@ -118,6 +121,7 @@ type
FMinors: TChartMinorAxisList; FMinors: TChartMinorAxisList;
FOnGetMarkText: TChartGetAxisMarkTextEvent; FOnGetMarkText: TChartGetAxisMarkTextEvent;
FOnMarkToText: TChartAxisMarkToTextEvent; FOnMarkToText: TChartAxisMarkToTextEvent;
FOrthogonalAxisIndex: TChartAxisIndex;
FPosition: Double; FPosition: Double;
FPositionUnits: TChartUnits; FPositionUnits: TChartUnits;
FRange: TChartRange; FRange: TChartRange;
@ -143,6 +147,7 @@ type
procedure SetMinors(AValue: TChartMinorAxisList); procedure SetMinors(AValue: TChartMinorAxisList);
procedure SetOnGetMarkText(AValue: TChartGetAxisMarkTextEvent); procedure SetOnGetMarkText(AValue: TChartGetAxisMarkTextEvent);
procedure SetOnMarkToText(AValue: TChartAxisMarkToTextEvent); procedure SetOnMarkToText(AValue: TChartAxisMarkToTextEvent);
procedure SetOrthogonalAxisIndex(AValue: TChartAxisIndex);
procedure SetPosition(AValue: Double); procedure SetPosition(AValue: Double);
procedure SetPositionUnits(AValue: TChartUnits); procedure SetPositionUnits(AValue: TChartUnits);
procedure SetRange(AValue: TChartRange); procedure SetRange(AValue: TChartRange);
@ -168,6 +173,7 @@ type
procedure Draw; procedure Draw;
procedure DrawTitle(ASize: Integer); procedure DrawTitle(ASize: Integer);
function GetChart: TCustomChart; inline; function GetChart: TCustomChart; inline;
function GetOrthogonalAxis: TChartAxis;
function GetTransform: TChartAxisTransformations; function GetTransform: TChartAxisTransformations;
function IsDefaultPosition: Boolean; function IsDefaultPosition: Boolean;
function IsFlipped: Boolean; override; function IsFlipped: Boolean; override;
@ -198,6 +204,8 @@ type
read FMarginsForMarks write SetMarginsForMarks default true; read FMarginsForMarks write SetMarginsForMarks default true;
property Marks: TChartAxisMarks read GetMarks write SetMarks; property Marks: TChartAxisMarks read GetMarks write SetMarks;
property Minors: TChartMinorAxisList read FMinors write SetMinors; property Minors: TChartMinorAxisList read FMinors write SetMinors;
property OrthogonalAxisIndex: TChartAxisIndex
read FOrthogonalAxisIndex write SetOrthogonalAxisIndex default DEF_AXIS_INDEX;
property Position: Double read FPosition write SetPosition stored PositionIsStored; property Position: Double read FPosition write SetPosition stored PositionIsStored;
property PositionUnits: TChartUnits property PositionUnits: TChartUnits
read FPositionUnits write SetPositionUnits default cuPercent; read FPositionUnits write SetPositionUnits default cuPercent;
@ -468,6 +476,7 @@ begin
Self.FTransformations := Transformations; Self.FTransformations := Transformations;
Self.FZPosition := ZPosition; Self.FZPosition := ZPosition;
Self.FMarginsForMarks := MarginsForMarks; Self.FMarginsForMarks := MarginsForMarks;
Self.FOrthogonalAxisIndex := OrthogonalAxisIndex;
Self.FOnGetMarkText := OnGetMarkText; Self.FOnGetMarkText := OnGetMarkText;
Self.FOnMarkToText := OnMarkToText; Self.FOnMarkToText := OnMarkToText;
end; end;
@ -489,6 +498,7 @@ begin
FTitle := TChartAxisTitle.Create(ACollection.Owner as TCustomChart); FTitle := TChartAxisTitle.Create(ACollection.Owner as TCustomChart);
FMarginsForMarks := true; FMarginsForMarks := true;
FMarks.SetInsideDir(1, 0); FMarks.SetInsideDir(1, 0);
FOrthogonalAxisIndex := -1;
end; end;
destructor TChartAxis.Destroy; destructor TChartAxis.Destroy;
@ -746,6 +756,20 @@ begin
Result := TChartAxisMarks(inherited Marks); Result := TChartAxisMarks(inherited Marks);
end{%H-}; // to silence the compiler warning of impossible inherited inside inline proc end{%H-}; // to silence the compiler warning of impossible inherited inside inline proc
function TChartAxis.GetOrthogonalAxis: TChartAxis;
begin
Result := nil;
if (FOrthogonalAxisIndex = -1) then
begin
if Collection.Count = 2 then
Result := TChartAxisList(Collection)[(Index + 1) mod 2];
end else
Result := TChartAxisList(Collection)[FOrthogonalAxisIndex];
if (Result <> nil) and (not (Result.IsVertical xor IsVertical)) then
Result := nil;
end;
function TChartAxis.GetRealTitle: String; function TChartAxis.GetRealTitle: String;
begin begin
if Title.Visible and IsWordwrappedTitle then if Title.Visible and IsWordwrappedTitle then
@ -1011,6 +1035,9 @@ end;
function TChartAxis.PositionToCoord(const ARect: TRect): Integer; function TChartAxis.PositionToCoord(const ARect: TRect): Integer;
var var
r: TChartAxisMargins absolute ARect; r: TChartAxisMargins absolute ARect;
orthoAx: TChartAxis;
t: TChartAxisTransformations;
posValue: Double;
begin begin
if IsDefaultPosition then exit(r[Alignment]); if IsDefaultPosition then exit(r[Alignment]);
case PositionUnits of case PositionUnits of
@ -1019,12 +1046,23 @@ begin
r[Alignment], r[Alignment],
r[TChartAxisAlignment((Ord(Alignment) + 2) mod 4)], r[TChartAxisAlignment((Ord(Alignment) + 2) mod 4)],
Position * PERCENT)); Position * PERCENT));
// TODO: Add OrthogonalAxis property to support cuAxis position.
cuAxis, cuGraph: cuAxis, cuGraph:
begin
posValue := Position;
if PositionUnits = cuAxis then
begin
orthoAx := GetOrthogonalAxis;
if orthoAx <> nil then
begin
t := orthoAx.GetTransform;
posValue := t.AxisToGraph(Position);
end;
end;
if IsVertical then if IsVertical then
Result := FHelper.FTransf.XGraphToImage(Position) Result := FHelper.FTransf.XGraphToImage(posValue)
else else
Result := FHelper.FTransf.YGraphToImage(Position); Result := FHelper.FTransf.YGraphToImage(posValue);
end;
cuPixel: cuPixel:
Result := Result :=
r[Alignment] + r[Alignment] +
@ -1143,6 +1181,13 @@ begin
StyleChanged(Self); StyleChanged(Self);
end; end;
procedure TChartAxis.SetOrthogonalAxisIndex(AValue: TChartAxisIndex);
begin
if FOrthogonalAxisIndex = AValue then exit;
FOrthogonalAxisIndex := AValue;
StyleChanged(Self);
end;
procedure TChartAxis.SetPosition(AValue: Double); procedure TChartAxis.SetPosition(AValue: Double);
begin begin
if SameValue(FPosition, AValue) then exit; if SameValue(FPosition, AValue) then exit;

View File

@ -21,7 +21,6 @@ uses
TASources, TAStyles, TATextElements, TATypes; TASources, TAStyles, TATextElements, TATypes;
const const
DEF_AXIS_INDEX = -1;
DEF_ERR_ENDLENGTH = 5; DEF_ERR_ENDLENGTH = 5;
type type
@ -42,8 +41,6 @@ type
FValue: TDoublePoint; FValue: TDoublePoint;
end; end;
TChartAxisIndex = -1..MaxInt;
{ TCustomChartSeries } { TCustomChartSeries }
TCustomChartSeries = class(TBasicChartSeries) TCustomChartSeries = class(TBasicChartSeries)