TAChart: Implement stacked line series

git-svn-id: trunk@27132 -
This commit is contained in:
ask 2010-08-18 06:32:55 +00:00
parent fe4ac38bf4
commit e44c18a3d3
3 changed files with 35 additions and 14 deletions

View File

@ -427,7 +427,7 @@ end;
function TChartSeries.Extent: TDoubleRect;
begin
Result := Source.Extent;
Result := Source.ExtentCumulative;
end;
function TChartSeries.FormattedMark(AIndex: integer): String;

View File

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

View File

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