mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-16 17:09:21 +02:00
TAChart: Caching of cumulative and x/y list extents of chart sources. Issue #35313, part of patch by Marcin Wiazowski.
git-svn-id: trunk@60846 -
This commit is contained in:
parent
db219396ae
commit
056f96d7b5
@ -189,6 +189,12 @@ type
|
||||
strict protected
|
||||
FBasicExtent: TDoubleRect;
|
||||
FBasicExtentIsValid: Boolean;
|
||||
FCumulativeExtent: TDoubleRect;
|
||||
FCumulativeExtentIsValid: Boolean;
|
||||
FXListExtent: TDoubleRect;
|
||||
FXListExtentIsValid: Boolean;
|
||||
FYListExtent: TDoubleRect;
|
||||
FYListExtentIsValid: Boolean;
|
||||
FValuesTotal: Double;
|
||||
FValuesTotalIsValid: Boolean;
|
||||
FXCount: Cardinal;
|
||||
@ -309,7 +315,7 @@ begin
|
||||
AItem.Color := clTAColor;
|
||||
AItem.Text := '';
|
||||
for i := 0 to High(AItem.XList) do
|
||||
Aitem.XList[i] := 0;
|
||||
AItem.XList[i] := 0;
|
||||
for i := 0 to High(AItem.YList) do
|
||||
AItem.YList[i] := 0;
|
||||
end;
|
||||
@ -832,40 +838,64 @@ var
|
||||
jyp, jyn: Integer;
|
||||
begin
|
||||
Result := Extent;
|
||||
if (YCount < 2) and (XCount < 2) then exit;
|
||||
|
||||
// Skip the x and y values used for error bars when calculating the list extent.
|
||||
if UseXList and (XErrorBarData.Kind = ebkChartSource) then begin
|
||||
jxp := XErrorBarData.IndexPlus - 1; // -1 because XList is offset by 1
|
||||
jxn := XErrorBarData.IndexMinus - 1;
|
||||
end else begin
|
||||
jxp := -1;
|
||||
jxn := -1;
|
||||
end;
|
||||
if YErrorBarData.Kind = ebkChartSource then begin
|
||||
jyp := YErrorBarData.IndexPlus - 1; // -1 because YList is offset by 1
|
||||
jyn := YErrorBarData.IndexMinus - 1;
|
||||
end else begin
|
||||
jyp := -1;
|
||||
jyn := -1;
|
||||
end;
|
||||
if UseXList and (XCount > 1) then begin
|
||||
if not FXListExtentIsValid then begin
|
||||
FXListExtent := EmptyExtent;
|
||||
|
||||
if UseXList and (XCount > 1) then
|
||||
for i := 0 to Count - 1 do
|
||||
with Item[i]^ do begin
|
||||
for j := 0 to High(XList) do
|
||||
if (j <> jxp) and (j <> jxn) then
|
||||
UpdateMinMax(XList[j], Result.a.X, Result.b.X);
|
||||
// Skip the x values used for error bars when calculating the list extent.
|
||||
if XErrorBarData.Kind = ebkChartSource then begin
|
||||
jxp := XErrorBarData.IndexPlus - 1; // -1 because XList index is offset by 1
|
||||
jxn := XErrorBarData.IndexMinus - 1;
|
||||
end else begin
|
||||
jxp := -1;
|
||||
jxn := -1;
|
||||
end;
|
||||
for i := 0 to Count - 1 do
|
||||
with Item[i]^ do begin
|
||||
for j := 0 to High(YList) do
|
||||
if (j <> jyp) and (j <> jyn) then
|
||||
UpdateMinMax(YList[j], Result.a.Y, Result.b.Y);
|
||||
end
|
||||
|
||||
for i := 0 to Count - 1 do
|
||||
with Item[i]^ do begin
|
||||
for j := 0 to High(XList) do
|
||||
if (j <> jxp) and (j <> jxn) then
|
||||
UpdateMinMax(XList[j], FXListExtent.a.X, FXListExtent.b.X);
|
||||
end;
|
||||
|
||||
FXListExtentIsValid := true;
|
||||
end;
|
||||
|
||||
Result.a.X := Min(Result.a.X, FXListExtent.a.X);
|
||||
Result.b.X := Max(Result.b.X, FXListExtent.b.X);
|
||||
end;
|
||||
|
||||
if (YCount > 1) then begin
|
||||
if not FYListExtentIsValid then begin
|
||||
FYListExtent := EmptyExtent;
|
||||
|
||||
// Skip the y values used for error bars when calculating the list extent.
|
||||
if YErrorBarData.Kind = ebkChartSource then begin
|
||||
jyp := YErrorBarData.IndexPlus - 1; // -1 because YList index is offset by 1
|
||||
jyn := YErrorBarData.IndexMinus - 1;
|
||||
end else begin
|
||||
jyp := -1;
|
||||
jyn := -1;
|
||||
end;
|
||||
|
||||
for i := 0 to Count - 1 do
|
||||
with Item[i]^ do begin
|
||||
for j := 0 to High(YList) do
|
||||
if (j <> jyp) and (j <> jyn) then
|
||||
UpdateMinMax(YList[j], FYListExtent.a.Y, FYListExtent.b.Y);
|
||||
end;
|
||||
|
||||
FYListExtentIsValid := true;
|
||||
end;
|
||||
|
||||
Result.a.Y := Min(Result.a.Y, FYListExtent.a.Y);
|
||||
Result.b.Y := Max(Result.b.Y, FYListExtent.b.Y);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
class procedure TCustomChartSource.CheckFormat(const AFormat: String);
|
||||
begin
|
||||
Format(AFormat, [0.0, 0.0, '', 0.0, 0.0]);
|
||||
@ -919,28 +949,40 @@ function TCustomChartSource.ExtentCumulative: TDoubleRect;
|
||||
var
|
||||
h: Double;
|
||||
i, j: Integer;
|
||||
jyp: Integer = -1;
|
||||
jyn: Integer = -1;
|
||||
jyp, jyn: Integer;
|
||||
begin
|
||||
Result := Extent;
|
||||
if YCount < 2 then exit;
|
||||
|
||||
// Skip the y values used for error bars in calculating the cumulative sum.
|
||||
if YErrorBarData.Kind = ebkChartSource then begin
|
||||
jyp := YErrorBarData.IndexPlus - 1; // -1 because YList index is offset by 1
|
||||
jyn := YErrorBarData.IndexMinus - 1;
|
||||
end;
|
||||
if (YCount > 1) then begin
|
||||
if not FCumulativeExtentIsValid then begin
|
||||
FCumulativeExtent := EmptyExtent;
|
||||
|
||||
for i := 0 to Count - 1 do
|
||||
with Item[i]^ do begin
|
||||
h := NumberOr(Y);
|
||||
for j := 0 to High(YList) do
|
||||
if (j <> jyp) and (j <> jyn) then begin
|
||||
h += NumberOr(YList[j]);
|
||||
// If some of the Y values are negative, h may be non-monotonic.
|
||||
UpdateMinMax(h, Result.a.Y, Result.b.Y);
|
||||
// Skip the y values used for error bars when calculating the cumulative sum.
|
||||
if YErrorBarData.Kind = ebkChartSource then begin
|
||||
jyp := YErrorBarData.IndexPlus - 1; // -1 because YList index is offset by 1
|
||||
jyn := YErrorBarData.IndexMinus - 1;
|
||||
end else begin
|
||||
jyp := -1;
|
||||
jyn := -1;
|
||||
end;
|
||||
|
||||
for i := 0 to Count - 1 do
|
||||
with Item[i]^ do begin
|
||||
h := NumberOr(Y);
|
||||
for j := 0 to High(YList) do
|
||||
if (j <> jyp) and (j <> jyn) then begin
|
||||
h += NumberOr(YList[j]);
|
||||
// If some of the Y values are negative, h may be non-monotonic.
|
||||
UpdateMinMax(h, FCumulativeExtent.a.Y, FCumulativeExtent.b.Y);
|
||||
end;
|
||||
end;
|
||||
|
||||
FCumulativeExtentIsValid := true;
|
||||
end;
|
||||
|
||||
Result.a.Y := Min(Result.a.Y, FCumulativeExtent.a.Y);
|
||||
Result.b.Y := Max(Result.b.Y, FCumulativeExtent.b.Y);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Calculates the extent including multiple y values (non-stacked) }
|
||||
|
@ -555,6 +555,12 @@ procedure TListChartSource.ClearCaches;
|
||||
begin
|
||||
FBasicExtent := EmptyExtent;
|
||||
FBasicExtentIsValid := true;
|
||||
FCumulativeExtent := EmptyExtent;
|
||||
FCumulativeExtentIsValid := true;
|
||||
FXListExtent := EmptyExtent;
|
||||
FXListExtentIsValid := true;
|
||||
FYListExtent := EmptyExtent;
|
||||
FYListExtentIsValid := true;
|
||||
FValuesTotal := 0;
|
||||
FValuesTotalIsValid := true;
|
||||
end;
|
||||
@ -613,6 +619,9 @@ begin
|
||||
if FValuesTotalIsValid then
|
||||
FValuesTotal -= NumberOr(Y);
|
||||
end;
|
||||
FCumulativeExtentIsValid := false;
|
||||
FXListExtentIsValid := false;
|
||||
FYListExtentIsValid := false;
|
||||
Dispose(Item[AIndex]);
|
||||
FData.Delete(AIndex);
|
||||
Notify;
|
||||
@ -711,7 +720,7 @@ begin
|
||||
with Item[AIndex]^ do
|
||||
for i := 0 to Min(High(AXList), High(XList)) do
|
||||
XList[i] := AXList[i];
|
||||
// wp: Update x extent here ?
|
||||
FXListExtentIsValid := false;
|
||||
end;
|
||||
|
||||
function TListChartSource.SetXValue(AIndex: Integer; AValue: Double): Integer;
|
||||
@ -777,6 +786,8 @@ begin
|
||||
with Item[AIndex]^ do
|
||||
for i := 0 to Min(High(AYList), High(YList)) do
|
||||
YList[i] := AYList[i];
|
||||
FCumulativeExtentIsValid := false;
|
||||
FYListExtentIsValid := false;
|
||||
end;
|
||||
|
||||
procedure TListChartSource.SetYValue(AIndex: Integer; AValue: Double);
|
||||
@ -867,6 +878,9 @@ begin
|
||||
end;
|
||||
if FValuesTotalIsValid then
|
||||
FValuesTotal += NumberOr(AY);
|
||||
FCumulativeExtentIsValid := false;
|
||||
FXListExtentIsValid := false;
|
||||
FYListExtentIsValid := false;
|
||||
Notify;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user