mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 04:29:28 +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;
|
Text: String;
|
||||||
YList: TDoubleDynArray;
|
YList: TDoubleDynArray;
|
||||||
function GetY(AIndex: Integer): Double;
|
function GetY(AIndex: Integer): Double;
|
||||||
|
procedure ClearY;
|
||||||
end;
|
end;
|
||||||
PChartDataItem = ^TChartDataItem;
|
PChartDataItem = ^TChartDataItem;
|
||||||
|
|
||||||
@ -176,7 +177,8 @@ type
|
|||||||
procedure AddFirst(const AItem: TChartDataItem);
|
procedure AddFirst(const AItem: TChartDataItem);
|
||||||
procedure AddLast(const AItem: TChartDataItem);
|
procedure AddLast(const AItem: TChartDataItem);
|
||||||
procedure Clear; inline;
|
procedure Clear; inline;
|
||||||
function GetPLast: PChartDataItem;
|
function GetPLast: PChartDataItem; overload;
|
||||||
|
function GetPLast(AOffset: Cardinal): PChartDataItem; overload;
|
||||||
procedure GetSum(var AItem: TChartDataItem);
|
procedure GetSum(var AItem: TChartDataItem);
|
||||||
procedure RemoveLast; overload;
|
procedure RemoveLast; overload;
|
||||||
procedure RemoveValue(const AItem: TChartDataItem);
|
procedure RemoveValue(const AItem: TChartDataItem);
|
||||||
@ -324,6 +326,15 @@ end;
|
|||||||
|
|
||||||
{ TChartDataItem }
|
{ 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;
|
function TChartDataItem.GetY(AIndex: Integer): Double;
|
||||||
begin
|
begin
|
||||||
AIndex := EnsureRange(AIndex, 0, Length(YList));
|
AIndex := EnsureRange(AIndex, 0, Length(YList));
|
||||||
@ -395,6 +406,14 @@ begin
|
|||||||
Result := Length(FBuf);
|
Result := Length(FBuf);
|
||||||
end;
|
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;
|
function TChartSourceBuffer.GetPLast: PChartDataItem;
|
||||||
begin
|
begin
|
||||||
Result := @FBuf[EndIndex];
|
Result := @FBuf[EndIndex];
|
||||||
|
@ -157,7 +157,7 @@ type
|
|||||||
property Sorted: Boolean read FSorted write FSorted default false;
|
property Sorted: Boolean read FSorted write FSorted default false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TChartAccumulationMethod = (camNone, camSum, camAverage);
|
TChartAccumulationMethod = (camNone, camSum, camAverage, camDerivative);
|
||||||
|
|
||||||
{ TCalculatedChartSource }
|
{ TCalculatedChartSource }
|
||||||
|
|
||||||
@ -176,8 +176,9 @@ type
|
|||||||
FYOrder: array of Integer;
|
FYOrder: array of Integer;
|
||||||
|
|
||||||
procedure CalcAccumulation(AIndex: Integer);
|
procedure CalcAccumulation(AIndex: Integer);
|
||||||
|
procedure CalcDerivative(AIndex: Integer);
|
||||||
procedure CalcPercentage;
|
procedure CalcPercentage;
|
||||||
procedure Changed(ASender: TObject); inline;
|
procedure Changed(ASender: TObject);
|
||||||
procedure ExtractItem(out AItem: TChartDataItem; AIndex: Integer);
|
procedure ExtractItem(out AItem: TChartDataItem; AIndex: Integer);
|
||||||
procedure SetAccumulationMethod(AValue: TChartAccumulationMethod);
|
procedure SetAccumulationMethod(AValue: TChartAccumulationMethod);
|
||||||
procedure SetAccumulationRange(AValue: Integer);
|
procedure SetAccumulationRange(AValue: Integer);
|
||||||
@ -846,12 +847,53 @@ begin
|
|||||||
FHistory.AddLast(FItem);
|
FHistory.AddLast(FItem);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
FHistory.GetSum(FItem);
|
case AccumulationMethod of
|
||||||
if AccumulationMethod = camAverage then begin
|
camSum:
|
||||||
FItem.Y /= Min(ar, AIndex + 1);
|
FHistory.GetSum(FItem);
|
||||||
for i := 0 to High(FItem.YList) do
|
camAverage: begin
|
||||||
FItem.YList[i] /= Min(ar, AIndex + 1);
|
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;
|
||||||
|
|
||||||
|
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;
|
end;
|
||||||
|
|
||||||
procedure TCalculatedChartSource.CalcPercentage;
|
procedure TCalculatedChartSource.CalcPercentage;
|
||||||
|
Loading…
Reference in New Issue
Block a user