mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 08:56:01 +02:00
TAChart: Add camDerivative value to TCalculatedChartSource.AccumulationMethod
git-svn-id: trunk@32184 -
This commit is contained in:
parent
ac40960c17
commit
842f2e1772
@ -90,6 +90,7 @@ type
|
||||
Text: String;
|
||||
YList: TDoubleDynArray;
|
||||
function GetY(AIndex: Integer): Double;
|
||||
procedure ClearY;
|
||||
end;
|
||||
PChartDataItem = ^TChartDataItem;
|
||||
|
||||
@ -176,7 +177,8 @@ type
|
||||
procedure AddFirst(const AItem: TChartDataItem);
|
||||
procedure AddLast(const AItem: TChartDataItem);
|
||||
procedure Clear; inline;
|
||||
function GetPLast: PChartDataItem;
|
||||
function GetPLast: PChartDataItem; overload;
|
||||
function GetPLast(AOffset: Cardinal): PChartDataItem; overload;
|
||||
procedure GetSum(var AItem: TChartDataItem);
|
||||
procedure RemoveLast; overload;
|
||||
procedure RemoveValue(const AItem: TChartDataItem);
|
||||
@ -324,6 +326,15 @@ end;
|
||||
|
||||
{ TChartDataItem }
|
||||
|
||||
procedure TChartDataItem.ClearY;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Y := 0;
|
||||
for i := 0 to High(YList) do
|
||||
YList[i] := 0;
|
||||
end;
|
||||
|
||||
function TChartDataItem.GetY(AIndex: Integer): Double;
|
||||
begin
|
||||
AIndex := EnsureRange(AIndex, 0, Length(YList));
|
||||
@ -395,6 +406,14 @@ begin
|
||||
Result := Length(FBuf);
|
||||
end;
|
||||
|
||||
function TChartSourceBuffer.GetPLast(AOffset: Cardinal): PChartDataItem;
|
||||
begin
|
||||
if AOffset >= FCount then
|
||||
raise EBufferError.Create('AOffset');
|
||||
AOffset := FCount - 1 - AOffset;
|
||||
Result := @FBuf[(FStart + AOffset + Capacity) mod Capacity];
|
||||
end;
|
||||
|
||||
function TChartSourceBuffer.GetPLast: PChartDataItem;
|
||||
begin
|
||||
Result := @FBuf[EndIndex];
|
||||
|
@ -157,7 +157,7 @@ type
|
||||
property Sorted: Boolean read FSorted write FSorted default false;
|
||||
end;
|
||||
|
||||
TChartAccumulationMethod = (camNone, camSum, camAverage);
|
||||
TChartAccumulationMethod = (camNone, camSum, camAverage, camDerivative);
|
||||
|
||||
{ TCalculatedChartSource }
|
||||
|
||||
@ -176,8 +176,9 @@ type
|
||||
FYOrder: array of Integer;
|
||||
|
||||
procedure CalcAccumulation(AIndex: Integer);
|
||||
procedure CalcDerivative(AIndex: Integer);
|
||||
procedure CalcPercentage;
|
||||
procedure Changed(ASender: TObject); inline;
|
||||
procedure Changed(ASender: TObject);
|
||||
procedure ExtractItem(out AItem: TChartDataItem; AIndex: Integer);
|
||||
procedure SetAccumulationMethod(AValue: TChartAccumulationMethod);
|
||||
procedure SetAccumulationRange(AValue: Integer);
|
||||
@ -846,12 +847,53 @@ begin
|
||||
FHistory.AddLast(FItem);
|
||||
end;
|
||||
end;
|
||||
FHistory.GetSum(FItem);
|
||||
if AccumulationMethod = camAverage then begin
|
||||
FItem.Y /= Min(ar, AIndex + 1);
|
||||
for i := 0 to High(FItem.YList) do
|
||||
FItem.YList[i] /= Min(ar, AIndex + 1);
|
||||
case AccumulationMethod of
|
||||
camSum:
|
||||
FHistory.GetSum(FItem);
|
||||
camAverage: begin
|
||||
FHistory.GetSum(FItem);
|
||||
FItem.Y /= Min(ar, AIndex + 1);
|
||||
for i := 0 to High(FItem.YList) do
|
||||
FItem.YList[i] /= Min(ar, AIndex + 1);
|
||||
end;
|
||||
camDerivative:
|
||||
CalcDerivative(AIndex);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
// Derivative is approximated by backwards finite difference
|
||||
// with accuracy order of (AccumulationRange - 1).
|
||||
procedure TCalculatedChartSource.CalcDerivative(AIndex: Integer);
|
||||
const
|
||||
COEFFS: array [2..7, 0..6] of Double = (
|
||||
( 1, -1, 0, 0, 0, 0, 0),
|
||||
( 3/2, -2, 1/2, 0, 0, 0, 0),
|
||||
( 11/6, -3, 3/2, -1/3, 0, 0, 0),
|
||||
( 25/12, -4, 3, -4/3, 1/4, 0, 0),
|
||||
(137/60, -5, 5, -10/3, 5/4, -1/5, 0),
|
||||
( 49/20, -6, 15/2, -20/3, 15/4, -6/5, 1/6));
|
||||
var
|
||||
prevItem: PChartDataItem;
|
||||
i, j, ar: Integer;
|
||||
dx: Double;
|
||||
begin
|
||||
FItem.ClearY;
|
||||
if AIndex = 0 then exit;
|
||||
dx := FItem.X - FHistory.GetPLast(1)^.X;
|
||||
if dx = 0 then exit;
|
||||
ar := Min(AccumulationRange, AIndex);
|
||||
if (ar = 0) or (ar > High(COEFFS)) then
|
||||
ar := High(COEFFS);
|
||||
for j := 0 to ar - 1 do begin
|
||||
prevItem := FHistory.GetPLast(j);
|
||||
FItem.Y += prevItem^.Y * COEFFS[ar, j];
|
||||
for i := 0 to High(FItem.YList) do
|
||||
FItem.YList[i] += prevItem^.YList[i] * COEFFS[ar, j];
|
||||
end;
|
||||
FItem.Y /= dx;
|
||||
for i := 0 to High(FItem.YList) do
|
||||
FItem.YList[i] /= dx;
|
||||
end;
|
||||
|
||||
procedure TCalculatedChartSource.CalcPercentage;
|
||||
|
Loading…
Reference in New Issue
Block a user