TAChart: Refactor axis ordering

git-svn-id: trunk@27794 -
This commit is contained in:
ask 2010-10-21 12:40:12 +00:00
parent 7c2ff8e9c6
commit 387d267fa5

View File

@ -114,7 +114,8 @@ type
end; end;
TChartAxisMeasureData = record TChartAxisGroup = record
FCount: Integer;
FSize: Integer; FSize: Integer;
FTitleSize: Integer; FTitleSize: Integer;
end; end;
@ -178,7 +179,7 @@ type
function IsVertical: Boolean; inline; function IsVertical: Boolean; inline;
procedure Measure( procedure Measure(
ACanvas: TCanvas; const AExtent: TDoubleRect; AFirstPass: Boolean; ACanvas: TCanvas; const AExtent: TDoubleRect; AFirstPass: Boolean;
var AMeasureData: TChartAxisMeasureData); var AMeasureData: TChartAxisGroup);
published published
property Alignment: TChartAxisAlignment property Alignment: TChartAxisAlignment
read FAlignment write SetAlignment default calLeft; read FAlignment write SetAlignment default calLeft;
@ -214,10 +215,10 @@ type
function GetAxes(AIndex: Integer): TChartAxis; function GetAxes(AIndex: Integer): TChartAxis;
private private
FCenterPoint: TPoint; FCenterPoint: TPoint;
FCounts: TIntegerDynArray; FGroupOrder: TFPList;
FMeasureData: array of TChartAxisMeasureData; FGroups: array of TChartAxisGroup;
FOrder: TIntegerDynArray; FZOrder: TFPList;
FZOrderedAxises: TFPList; procedure InitAndSort(AList: TFPList; ACompare: TListSortCompare);
protected protected
function GetOwner: TPersistent; override; function GetOwner: TPersistent; override;
public public
@ -278,6 +279,16 @@ type
var var
VIdentityTransform: TChartAxisTransformations; VIdentityTransform: TChartAxisTransformations;
function AxisGroupCompare(Item1, Item2: Pointer): Integer;
begin
Result := TChartAxis(Item1).Group - TChartAxis(Item2).Group;
end;
function AxisZCompare(Item1, Item2: Pointer): Integer;
begin
Result := TChartAxis(Item1).ZPosition - TChartAxis(Item2).ZPosition;
end;
procedure SideByAlignment( procedure SideByAlignment(
var ARect: TRect; AAlignment: TChartAxisAlignment; ADelta: Integer); var ARect: TRect; AAlignment: TChartAxisAlignment; ADelta: Integer);
var var
@ -583,7 +594,7 @@ end;
procedure TChartAxis.Measure( procedure TChartAxis.Measure(
ACanvas: TCanvas; const AExtent: TDoubleRect; ACanvas: TCanvas; const AExtent: TDoubleRect;
AFirstPass: Boolean; var AMeasureData: TChartAxisMeasureData); AFirstPass: Boolean; var AMeasureData: TChartAxisGroup);
function CalcMarksSize(AMin, AMax: Double): TSize; function CalcMarksSize(AMin, AMax: Double): TSize;
const const
@ -770,12 +781,14 @@ constructor TChartAxisList.Create(AOwner: TCustomChart);
begin begin
inherited Create(TChartAxis); inherited Create(TChartAxis);
FChart := AOwner; FChart := AOwner;
FZOrderedAxises := TFPList.Create; FGroupOrder := TFPList.Create;
FZOrder := TFPList.Create;
end; end;
destructor TChartAxisList.Destroy; destructor TChartAxisList.Destroy;
begin begin
FreeAndNil(FZOrderedAxises); FreeAndNil(FGroupOrder);
FreeAndNil(FZOrder);
inherited Destroy; inherited Destroy;
end; end;
@ -783,12 +796,12 @@ procedure TChartAxisList.Draw(
ACanvas: TCanvas; const AExtent: TDoubleRect; ACanvas: TCanvas; const AExtent: TDoubleRect;
const ATransf: ICoordTransformer; ACurrentZ: Integer; var AIndex: Integer); const ATransf: ICoordTransformer; ACurrentZ: Integer; var AIndex: Integer);
begin begin
while AIndex < FZOrderedAxises.Count do while AIndex < FZOrder.Count do
with TChartAxis(FZOrderedAxises[AIndex]) do begin with TChartAxis(FZOrder[AIndex]) do begin
if ACurrentZ < ZPosition then break; if ACurrentZ < ZPosition then break;
Draw(ACanvas, AExtent, ATransf, FAxisRect); Draw(ACanvas, AExtent, ATransf, FAxisRect);
DrawTitle( DrawTitle(
ACanvas, FCenterPoint, FMeasureData[FGroupIndex].FTitleSize, FTitleRect); ACanvas, FCenterPoint, FGroups[FGroupIndex].FTitleSize, FTitleRect);
AIndex += 1; AIndex += 1;
end; end;
end; end;
@ -813,88 +826,85 @@ begin
Result := FChart; Result := FChart;
end; end;
procedure TChartAxisList.InitAndSort(
AList: TFPList; ACompare: TListSortCompare);
var
i: Integer;
begin
AList.Clear;
for i := 0 to Count - 1 do
AList.Add(Pointer(Axes[i]));
AList.Sort(ACompare);
end;
procedure TChartAxisList.Measure( procedure TChartAxisList.Measure(
ACanvas: TCanvas; const AExtent: TDoubleRect; ACanvas: TCanvas; const AExtent: TDoubleRect;
AFirstPass: Boolean; var AMargins: TChartAxisMargins); AFirstPass: Boolean; var AMargins: TChartAxisMargins);
var var
i, j, ai: Integer; i, j, ai: Integer;
axis: TChartAxis; axis: TChartAxis;
d: ^TChartAxisMeasureData; g: ^TChartAxisGroup;
begin begin
ai := 0; ai := 0;
for i := 0 to High(FCounts) do begin for i := 0 to High(FGroups) do begin
d := @FMeasureData[i]; g := @FGroups[i];
d^.FSize := 0; g^.FSize := 0;
d^.FTitleSize := 0; g^.FTitleSize := 0;
for j := 0 to FCounts[i] - 1 do begin for j := 0 to g^.FCount - 1 do begin
axis := Axes[FOrder[ai]]; axis := TChartAxis(FGroupOrder[ai]);
axis.Measure(ACanvas, AExtent, AFirstPass, d^); axis.Measure(ACanvas, AExtent, AFirstPass, g^);
ai += 1; ai += 1;
end; end;
if AFirstPass then if AFirstPass then
AMargins[axis.Alignment] += d^.FSize + d^.FTitleSize; AMargins[axis.Alignment] += g^.FSize + g^.FTitleSize;
end; end;
end; end;
function AxisZCompare(Item1, Item2: Pointer): Integer;
begin
Result := TChartAxis(Item1).ZPosition - TChartAxis(Item2).ZPosition;
end;
procedure TChartAxisList.Prepare(ARect: TRect); procedure TChartAxisList.Prepare(ARect: TRect);
var var
i, j, ai: Integer; i, j, ai: Integer;
axis: TChartAxis; axis: TChartAxis;
g: ^TChartAxisGroup;
begin begin
FCenterPoint := CenterPoint(ARect); FCenterPoint := CenterPoint(ARect);
ai := 0; ai := 0;
for i := 0 to High(FCounts) do begin for i := 0 to High(FGroups) do begin
for j := 0 to FCounts[i] - 1 do begin g := @FGroups[i];
axis := Axes[FOrder[ai + j]]; for j := 0 to g^.FCount - 1 do begin
axis.FGroupIndex := i; axis := TChartAxis(FGroupOrder[ai + j]);
axis.FAxisRect := ARect; axis.FAxisRect := ARect;
end; end;
SideByAlignment(ARect, axis.Alignment, FMeasureData[i].FSize); SideByAlignment(ARect, axis.Alignment, g^.FSize);
for j := 0 to FCounts[i] - 1 do begin for j := 0 to g^.FCount - 1 do begin
axis := Axes[FOrder[ai]]; axis := TChartAxis(FGroupOrder[ai]);
axis.FTitleRect := ARect; axis.FTitleRect := ARect;
ai += 1; ai += 1;
end; end;
SideByAlignment(ARect, axis.Alignment, FMeasureData[i].FTitleSize); SideByAlignment(ARect, axis.Alignment, g^.FTitleSize);
end; end;
FZOrderedAxises.Clear; InitAndSort(FZOrder, @AxisZCompare);
for i := 0 to Count - 1 do
FZOrderedAxises.Add(Pointer(Axes[i]));
FZOrderedAxises.Sort(@AxisZCompare);
end; end;
procedure TChartAxisList.PrepareGroups; procedure TChartAxisList.PrepareGroups;
var var
i, j, g, m, groupCount: Integer; i, g, prevGroup, groupCount: Integer;
begin begin
SetLength(FOrder, Count); InitAndSort(FGroupOrder, @AxisGroupCompare);
for i := 0 to Count - 1 do SetLength(FGroups, Count);
FOrder[i] := i; groupCount := 0;
for i := 0 to High(FOrder) - 1 do begin prevGroup := 0;
m := i; for i := 0 to FGroupOrder.Count - 1 do
for j := i + 1 to High(FOrder) do with TChartAxis(FGroupOrder[i]) do begin
if Axes[FOrder[j]].Group < Axes[FOrder[m]].Group then if (Group = 0) or (Group <> prevGroup) then begin
m := j; FGroups[groupCount].FCount := 1;
if m <> i then groupCount += 1;
Exchange(FOrder[i], FOrder[m]); prevGroup := Group;
end; end
SetLength(FCounts, Count); else
FCounts[0] := 1; FGroups[groupCount - 1].FCount += 1;
for i := 1 to High(FCounts) do FGroupIndex := groupCount - 1;
FCounts[i] := 0; end;
groupCount := 1; SetLength(FGroups, groupCount);
for i := 1 to High(FOrder) do begin
g := Axes[FOrder[i]].Group;
groupCount += Ord((g = 0) or (g <> Axes[FOrder[i - 1]].Group));
FCounts[groupCount - 1] += 1;
end;
SetLength(FCounts, groupCount);
SetLength(FMeasureData, groupCount);
end; end;
procedure TChartAxisList.SetAxis(AIndex: Integer; AValue: TChartAxis); procedure TChartAxisList.SetAxis(AIndex: Integer; AValue: TChartAxis);