mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-26 19:43:48 +02:00
TAChart: Allow XCount=0 for TChartSource meaning "replace X by point index". Still some issues.
git-svn-id: trunk@60995 -
This commit is contained in:
parent
eee4ab0ff1
commit
ac880dd4b9
@ -920,12 +920,18 @@ end;
|
||||
|
||||
function TChartSeries.GetGraphPointX(AIndex: Integer): Double;
|
||||
begin
|
||||
Result := AxisToGraphX(Source[AIndex]^.X);
|
||||
if Source.XCount = 0 then
|
||||
Result := AxisToGraphX(Index)
|
||||
else
|
||||
Result := AxisToGraphX(Source[AIndex]^.X);
|
||||
end;
|
||||
|
||||
function TChartSeries.GetGraphPointX(AIndex, AXIndex: Integer): Double;
|
||||
begin
|
||||
Result := AxisToGraphX(Source[AIndex]^.GetX(AXIndex));
|
||||
if Source.XCount = 0 then
|
||||
Result := AxisToGraphX(AIndex)
|
||||
else
|
||||
Result := AxisToGraphX(Source[AIndex]^.GetX(AXIndex));
|
||||
end;
|
||||
|
||||
function TChartSeries.GetGraphPointY(AIndex: Integer): Double;
|
||||
@ -988,7 +994,7 @@ end;
|
||||
|
||||
class procedure TChartSeries.GetXYCountNeeded(out AXCount, AYCount: Cardinal);
|
||||
begin
|
||||
AXCount := 1;
|
||||
AXCount := 0;
|
||||
AYCount := 1;
|
||||
end;
|
||||
|
||||
@ -1004,15 +1010,18 @@ end;
|
||||
|
||||
function TChartSeries.GetXValue(AIndex: Integer): Double;
|
||||
begin
|
||||
Result := Source[AIndex]^.X;
|
||||
if Source.XCount > 0 then
|
||||
Result := Source[AIndex]^.X
|
||||
else
|
||||
Result := AIndex;
|
||||
end;
|
||||
|
||||
function TChartSeries.GetXValues(AIndex, AXIndex: Integer): Double;
|
||||
begin
|
||||
if AXIndex = 0 then
|
||||
Result := Source[AIndex]^.X
|
||||
if AXIndex > 0 then
|
||||
Result := Source[AIndex]^.XList[AXIndex - 1]
|
||||
else
|
||||
Result := Source[AIndex]^.XList[AXIndex - 1];
|
||||
Result := Source[AIndex]^.X;
|
||||
end;
|
||||
|
||||
function TChartSeries.GetYImgValue(AIndex: Integer): Integer;
|
||||
@ -1777,12 +1786,17 @@ begin
|
||||
FindExtentInterval(AExtent, AFilterByExtent);
|
||||
|
||||
SetLength(FGraphPoints, Max(FUpBound - FLoBound + 1, 0));
|
||||
if (AxisIndexX < 0) and (AxisIndexY < 0) then
|
||||
if (AxisIndexX < 0) and (AxisIndexY < 0) then begin
|
||||
// Optimization: bypass transformations in the default case.
|
||||
for i := FLoBound to FUpBound do
|
||||
with Source[i]^ do
|
||||
FGraphPoints[i - FLoBound] := DoublePoint(X, Y)
|
||||
else
|
||||
if Source.XCount > 0 then
|
||||
for i := FLoBound to FUpBound do
|
||||
with Source[i]^ do
|
||||
FGraphPoints[i - FLoBound] := DoublePoint(X, Y)
|
||||
else
|
||||
for i := FLoBound to FUpBound do
|
||||
with Source[i]^ do
|
||||
FGraphPoints[i - FLoBound] := DoublePoint(i, Y);
|
||||
end else
|
||||
for i := FLoBound to FUpBound do
|
||||
FGraphPoints[i - FLoBound] := GetGraphPoint(i);
|
||||
end;
|
||||
|
@ -827,6 +827,9 @@ begin
|
||||
end else
|
||||
for i:=0 to Count - 1 do
|
||||
UpdateMinMax(Item[i]^.X, FBasicExtent.a.X, FBasicExtent.b.X);
|
||||
end else begin
|
||||
UpdateMinMax(0, FBasicExtent.a.X, FBasicExtent.b.X);
|
||||
UpdateMinMax(Count-1, FBasicExtent.a.X, FBasicExtent.b.X);
|
||||
end;
|
||||
|
||||
if YCount > 0 then begin
|
||||
|
@ -1280,21 +1280,32 @@ var
|
||||
n, ok: Integer;
|
||||
begin
|
||||
FIsUnorderedX := false;
|
||||
while (ASourceIndex < ASource.Count) and IsNan(ASource[ASourceIndex]^.Point) do
|
||||
ASourceIndex += 1;
|
||||
if ASource.XCount > 0 then
|
||||
while (ASourceIndex < ASource.Count) and IsNan(ASource[ASourceIndex]^.Point) do
|
||||
ASourceIndex += 1;
|
||||
FSourceStartIndex := ASourceIndex;
|
||||
FFirstCacheIndex := ACacheIndex;
|
||||
while (ASourceIndex < ASource.Count) and not IsNan(ASource[ASourceIndex]^.Point) do begin
|
||||
with ASource[ASourceIndex]^ do
|
||||
if (ACacheIndex > FFirstCacheIndex) and (FOwner.FX[ACacheIndex - 1] >= X) then
|
||||
FIsUnorderedX := true
|
||||
else begin
|
||||
FOwner.FX[ACacheIndex] := X;
|
||||
if ASource.XCount > 0 then
|
||||
while (ASourceIndex < ASource.Count) and not IsNan(ASource[ASourceIndex]^.Point) do begin
|
||||
with ASource[ASourceIndex]^ do
|
||||
if (ACacheIndex > FFirstCacheIndex) and (FOwner.FX[ACacheIndex - 1] >= X) then
|
||||
FIsUnorderedX := true
|
||||
else begin
|
||||
FOwner.FX[ACacheIndex] := X;
|
||||
FOwner.FY[ACacheIndex] := Y;
|
||||
ACacheIndex += 1;
|
||||
end;
|
||||
ASourceIndex += 1;
|
||||
end
|
||||
else
|
||||
while ASourceIndex < ASource.Count do begin
|
||||
with ASource[ASourceIndex]^ do begin
|
||||
FOwner.FX[ACacheIndex] := ASourceIndex;
|
||||
FOwner.FY[ACacheIndex] := Y;
|
||||
ACacheIndex += 1;
|
||||
end;
|
||||
ASourceIndex += 1;
|
||||
end;
|
||||
ASourceIndex += 1;
|
||||
end;
|
||||
FLastCacheIndex := ACacheIndex - 1;
|
||||
if FLastCacheIndex < FFirstCacheIndex then exit(false); // No points
|
||||
if IsFewPoints then exit(true);
|
||||
@ -1654,20 +1665,25 @@ procedure TFitSeries.CalcXRange(out AXMin, AXMax: Double);
|
||||
var
|
||||
ext: TDoubleRect;
|
||||
begin
|
||||
with Source.BasicExtent do begin
|
||||
ext.a := AxisToGraph(a);
|
||||
ext.b := AxisToGraph(b);
|
||||
end;
|
||||
NormalizeRect(ext);
|
||||
if IsRotated then begin
|
||||
AXMin := GraphToAxisY(ext.a.Y);
|
||||
AXMax := GraphToAxisY(ext.b.Y);
|
||||
if Source.XCount > 0 then begin
|
||||
with Source.BasicExtent do begin
|
||||
ext.a := AxisToGraph(a);
|
||||
ext.b := AxisToGraph(b);
|
||||
end;
|
||||
NormalizeRect(ext);
|
||||
if IsRotated then begin
|
||||
AXMin := GraphToAxisY(ext.a.Y);
|
||||
AXMax := GraphToAxisY(ext.b.Y);
|
||||
end else begin
|
||||
AXMin := GraphToAxisX(ext.a.X);
|
||||
AXMax := GraphToAxisX(ext.b.X);
|
||||
end;
|
||||
EnsureOrder(AXMin, AXMax);
|
||||
FFitRange.Intersect(AXMin, AXMax);
|
||||
end else begin
|
||||
AXMin := GraphToAxisX(ext.a.X);
|
||||
AXMax := GraphToAxisX(ext.b.X);
|
||||
AXMin := 0;
|
||||
AXMax := Source.Count - 1;
|
||||
end;
|
||||
EnsureOrder(AXMin, AXMax);
|
||||
FFitRange.Intersect(AXMin, AXMax);
|
||||
end;
|
||||
|
||||
procedure TFitSeries.Assign(ASource: TPersistent);
|
||||
@ -1786,7 +1802,10 @@ var
|
||||
|
||||
function IsValidPoint(AX, AY: Double): Boolean; inline;
|
||||
begin
|
||||
Result := not IsNaN(AX) and not IsNaN(AY) and InRange(AX, xmin, xmax);
|
||||
if Source.XCount > 0 then
|
||||
Result := not IsNaN(AX) and not IsNaN(AY) and InRange(AX, xmin, xmax)
|
||||
else
|
||||
Result := not IsNaN(AY);
|
||||
end;
|
||||
|
||||
procedure TryFit;
|
||||
@ -1816,7 +1835,10 @@ var
|
||||
for i := 0 to ns - 1 do
|
||||
with Source.Item[i]^ do
|
||||
if IsValidPoint(X, Y) then begin
|
||||
xv[j] := TransformX(X);
|
||||
if Source.XCount > 0 then
|
||||
xv[j] := TransformX(X)
|
||||
else
|
||||
xv[j] := TransformX(i);
|
||||
yv[j] := TransformY(Y);
|
||||
if hasErrorBars and Source.GetYErrorBarLimits(i, yp, yn) then
|
||||
dy[j] := abs(TransformY(yp) - TransformY(yn)) / 2;
|
||||
|
@ -1418,7 +1418,10 @@ begin
|
||||
if Length(FAngleCache) = Count then exit;
|
||||
SetLength(FAngleCache, Count);
|
||||
for i := 0 to Count - 1 do begin
|
||||
SinCos(Source[i]^.X, s, c);
|
||||
if Source.XCount > 0 then
|
||||
SinCos(Source[i]^.X, s, c)
|
||||
else
|
||||
SinCos(i, s, c);
|
||||
FAngleCache[i].FSin := s;
|
||||
FAngleCache[i].FCos := c;
|
||||
end;
|
||||
|
@ -1243,6 +1243,7 @@ begin
|
||||
SetLength(heights, Source.YCount + 1);
|
||||
for pointIndex := FLoBound to FUpBound do begin
|
||||
p := Source[pointIndex]^.Point;
|
||||
if Source.XCount = 0 then p.X := pointIndex + FLoBound;
|
||||
if SkipMissingValues(pointIndex) then
|
||||
continue;
|
||||
p.X := AxisToGraphX(p.X);
|
||||
@ -1518,19 +1519,25 @@ begin
|
||||
UpdateMinMax(GraphToAxisY(ZeroLevel), Result.a.Y, Result.b.Y);
|
||||
|
||||
// Show first and last bars fully.
|
||||
i := 0;
|
||||
x := NearestXNumber(i, +1); // --> x is in graph units
|
||||
if not IsNan(x) then begin
|
||||
BarOffsetWidth(x, i, ofs, w);
|
||||
x := GraphToAxisX(x + ofs - w); // x is in graph units, Extent in axis units!
|
||||
Result.a.X := Min(Result.a.X, x);
|
||||
end;
|
||||
i := Count - 1;
|
||||
x := NearestXNumber(i, -1);
|
||||
if not IsNan(x) then begin
|
||||
BarOffsetWidth(x, i, ofs, w);
|
||||
x := GraphToAxisX(x + ofs + w);
|
||||
Result.b.X := Max(Result.b.X, x);
|
||||
if Source.XCount = 0 then begin
|
||||
BarOffsetWidth(x, 0, ofs, w);
|
||||
Result.a.X -= (ofs + w);
|
||||
Result.b.X += (ofs + w);
|
||||
end else begin
|
||||
i := 0;
|
||||
x := NearestXNumber(i, +1); // --> x is in graph units
|
||||
if not IsNan(x) then begin
|
||||
BarOffsetWidth(x, i, ofs, w);
|
||||
x := GraphToAxisX(x + ofs - w); // x is in graph units, Extent in axis units!
|
||||
Result.a.X := Min(Result.a.X, x);
|
||||
end;
|
||||
i := Count - 1;
|
||||
x := NearestXNumber(i, -1);
|
||||
if not IsNan(x) then begin
|
||||
BarOffsetWidth(x, i, ofs, w);
|
||||
x := GraphToAxisX(x + ofs + w);
|
||||
Result.b.X := Max(Result.b.X, x);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1600,6 +1607,8 @@ begin
|
||||
// Iterate through all points of the series
|
||||
for pointIndex := 0 to Count - 1 do begin
|
||||
sp := Source[pointindex]^.Point;
|
||||
if Source.XCount = 0 then
|
||||
sp.X := pointIndex;
|
||||
if IsNan(sp) then
|
||||
continue;
|
||||
sp.X := AxisToGraphX(sp.X);
|
||||
|
Loading…
Reference in New Issue
Block a user