From e44c18a3d3b4b1bcb82d9f7d10b0634498a820cd Mon Sep 17 00:00:00 2001 From: ask Date: Wed, 18 Aug 2010 06:32:55 +0000 Subject: [PATCH] TAChart: Implement stacked line series git-svn-id: trunk@27132 - --- components/tachart/tacustomseries.pas | 2 +- components/tachart/taseries.pas | 29 +++++++++++++++------------ components/tachart/tasources.pas | 18 +++++++++++++++++ 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/components/tachart/tacustomseries.pas b/components/tachart/tacustomseries.pas index f05e4b4b8a..3deb951858 100644 --- a/components/tachart/tacustomseries.pas +++ b/components/tachart/tacustomseries.pas @@ -427,7 +427,7 @@ end; function TChartSeries.Extent: TDoubleRect; begin - Result := Source.Extent; + Result := Source.ExtentCumulative; end; function TChartSeries.FormattedMark(AIndex: integer): String; diff --git a/components/tachart/taseries.pas b/components/tachart/taseries.pas index 2ae6d3f1fa..1cc2b0a4b2 100644 --- a/components/tachart/taseries.pas +++ b/components/tachart/taseries.pas @@ -366,16 +366,28 @@ end; procedure TLineSeries.Draw(ACanvas: TCanvas); var ext: TDoubleRect; + i, j: Integer; begin - // Do not draw anything if the series extent does not intersect CurrentExtent. - ext.a := AxisToGraph(Source.Extent.a); - ext.b := AxisToGraph(Source.Extent.b); + with Extent do begin + ext.a := AxisToGraph(a); + ext.b := AxisToGraph(b); + end; if LineType = ltFromOrigin then ExpandRect(ext, AxisToGraph(ZeroDoublePoint)); + // Do not draw anything if the series extent does not intersect CurrentExtent. if not RectIntersectsRect(ext, ParentChart.CurrentExtent) then exit; PrepareGraphPoints(ext, LineType <> ltFromOrigin); DrawSingleLineInStack(ACanvas); + for i := 0 to Source.YCount - 2 do begin + if IsRotated then + for j := FLoBound to FUpBound do + FGraphPoints[j - FLoBound].X += AxisToGraphY(Source[j]^.YList[i]) + else + for j := FLoBound to FUpBound do + FGraphPoints[j - FLoBound].Y += AxisToGraphY(Source[j]^.YList[i]); + DrawSingleLineInStack(ACanvas); + end; end; procedure TLineSeries.DrawSingleLineInStack(ACanvas: TCanvas); @@ -764,20 +776,11 @@ end; function TBarSeries.Extent: TDoubleRect; var - x, h: Double; - i, j: Integer; + x: Double; begin Result := inherited Extent; if IsEmpty then exit; UpdateMinMax(ZeroLevel, Result.a.Y, Result.b.Y); - if Source.YCount >= 2 then begin - for i := 0 to Count - 1 do begin - h := Source[i]^.Y; - for j := 0 to Source.YCount - 2 do - h += Source[i]^.YList[j]; - UpdateMinMax(h, Result.a.Y, Result.b.Y); - end; - end; // Show first and last bars fully. x := GetGraphPointX(0); Result.a.X := Min(Result.a.X, x - CalcBarWidth(x, 0)); diff --git a/components/tachart/tasources.pas b/components/tachart/tasources.pas index 3a4736c480..8450fea2de 100644 --- a/components/tachart/tasources.pas +++ b/components/tachart/tasources.pas @@ -68,6 +68,7 @@ type public class procedure CheckFormat(const AFormat: String); function Extent: TDoubleRect; + function ExtentCumulative: TDoubleRect; function ExtentList: TDoubleRect; procedure FindBounds(AXMin, AXMax: Double; out ALB, AUB: Integer); function FormatItem(const AFormat: String; AIndex: Integer): String; @@ -360,6 +361,23 @@ begin Result := FExtent; end; +function TCustomChartSource.ExtentCumulative: TDoubleRect; +var + h: Double; + i, j: Integer; +begin + Result := Extent; + if YCount < 2 then exit; + for i := 0 to Count - 1 do begin + h := Item[i]^.Y; + for j := 0 to YCount - 2 do begin + h += Item[i]^.YList[j]; + // If some of Y values are negative, h may be non-monotonic. + UpdateMinMax(h, Result.a.Y, Result.b.Y); + end; + end; +end; + function TCustomChartSource.ExtentList: TDoubleRect; var i, j: Integer;