mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-15 03:49:26 +02:00
TAChart: Publish error bar params for TUserDefinedChartSource. Add method to query effective error bar values from chart source.
git-svn-id: trunk@58604 -
This commit is contained in:
parent
0fbcf86523
commit
9bfe23796d
@ -194,8 +194,8 @@ type
|
||||
FYCount: Cardinal;
|
||||
procedure ChangeErrorBars(Sender: TObject); virtual;
|
||||
function GetCount: Integer; virtual; abstract;
|
||||
function GetErrorBarLimits(APointIndex: Integer; Which: Integer;
|
||||
out AUpperLimit, ALowerLimit: Double): Boolean;
|
||||
function GetErrorBarValues(APointIndex: Integer; Which: Integer;
|
||||
out AUpperDelta, ALowerDelta: Double): Boolean;
|
||||
function GetHasErrorBars(Which: Integer): Boolean;
|
||||
function GetItem(AIndex: Integer): PChartDataItem; virtual; abstract;
|
||||
procedure InvalidateCaches;
|
||||
@ -227,6 +227,10 @@ type
|
||||
out AUpperLimit, ALowerLimit: Double): Boolean;
|
||||
function GetYErrorBarLimits(APointIndex: Integer;
|
||||
out AUpperLimit, ALowerLimit: Double): Boolean;
|
||||
function GetXErrorBarValues(APointIndex: Integer;
|
||||
out AUpperDelta, ALowerDelta: Double): Boolean;
|
||||
function GetYErrorBarValues(APointIndex: Integer;
|
||||
out AUpperDelta, ALowerDelta: Double): Boolean;
|
||||
function HasXErrorBars: Boolean;
|
||||
function HasYErrorBars: Boolean;
|
||||
function IsXErrorIndex(AXIndex: Integer): Boolean;
|
||||
@ -715,8 +719,8 @@ begin
|
||||
FValue := TChartErrorBarData(ASource).FValue;
|
||||
FIndex := TChartErrorBarData(ASource).FIndex;
|
||||
FKind := TChartErrorBarData(ASource).Kind;
|
||||
end;
|
||||
inherited;
|
||||
end else
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TChartErrorBarData.Changed;
|
||||
@ -998,26 +1002,24 @@ begin
|
||||
Result := FErrorBarData[AIndex];
|
||||
end;
|
||||
|
||||
{ Returns the error bar limits in positive and negative direction for the
|
||||
{ Returns the error bar values in positive and negative direction for the
|
||||
x (which = 0) or y (which = 1) coordinates of the data point at the specified
|
||||
index. The result is false if there is no error bar. }
|
||||
function TCustomChartSource.GetErrorBarLimits(APointIndex: Integer;
|
||||
Which: Integer; out AUpperLimit, ALowerLimit: Double): Boolean;
|
||||
function TCustomChartSource.GetErrorBarValues(APointIndex: Integer;
|
||||
Which: Integer; out AUpperDelta, ALowerDelta: Double): Boolean;
|
||||
var
|
||||
v: Double;
|
||||
deltaP, deltaN: Double;
|
||||
pidx, nidx: Integer;
|
||||
begin
|
||||
Result := false;
|
||||
AUpperDelta := 0;
|
||||
ALowerDelta := 0;
|
||||
|
||||
if Which = 0 then
|
||||
v := Item[APointIndex]^.X
|
||||
else
|
||||
v := Item[APointIndex]^.Y;
|
||||
|
||||
AUpperLimit := v;
|
||||
ALowerLimit := v;
|
||||
|
||||
if IsNaN(v) then
|
||||
exit;
|
||||
|
||||
@ -1027,59 +1029,91 @@ begin
|
||||
exit;
|
||||
ebkConst:
|
||||
begin
|
||||
deltaP := FErrorBarData[Which].ValuePlus;
|
||||
AUpperDelta := FErrorBarData[Which].ValuePlus;
|
||||
if FErrorBarData[Which].ValueMinus = -1 then
|
||||
deltaN := deltaP
|
||||
ALowerDelta := AUpperDelta
|
||||
else
|
||||
deltaN := FErrorBarData[Which].ValueMinus;
|
||||
ALowerDelta := FErrorBarData[Which].ValueMinus;
|
||||
end;
|
||||
ebkPercent:
|
||||
begin
|
||||
deltaP := v * FErrorBarData[Which].ValuePlus * PERCENT;
|
||||
AUpperDelta := v * FErrorBarData[Which].ValuePlus * PERCENT;
|
||||
if FErrorBarData[Which].ValueMinus = -1 then
|
||||
deltaN := deltaP
|
||||
ALowerDelta := AUpperDelta
|
||||
else
|
||||
deltaN := v * FErrorBarData[Which].ValueMinus * PERCENT;
|
||||
ALowerDelta := v * FErrorBarData[Which].ValueMinus * PERCENT;
|
||||
end;
|
||||
ebkChartSource:
|
||||
if Which = 0 then begin
|
||||
pidx := FErrorBarData[0].IndexPlus;
|
||||
nidx := FErrorBarData[0].IndexMinus;
|
||||
if not InRange(pidx, 0, XCount - 1) then exit;
|
||||
if (nidx <> -1) and not InRange(nidx, 0, XCount - 1) then exit;
|
||||
deltaP := Item[APointIndex]^.GetX(pidx);
|
||||
if not InRange(pidx, 0, XCount) then exit;
|
||||
if (nidx <> -1) and not InRange(nidx, 0, XCount-1) then exit;
|
||||
AUpperDelta := Item[APointIndex]^.GetX(pidx);
|
||||
if nidx = -1 then
|
||||
deltaN := deltaP
|
||||
ALowerDelta := AUpperDelta
|
||||
else
|
||||
deltaN := Item[APointIndex]^.GetX(nidx);
|
||||
ALowerDelta := Item[APointIndex]^.GetX(nidx);
|
||||
end else begin
|
||||
pidx := FErrorBarData[1].IndexPlus;
|
||||
nidx := FErrorBarData[1].IndexMinus;
|
||||
if not InRange(pidx, 0, YCount - 1) then exit;
|
||||
if (nidx <> -1) and not InRange(nidx, 0, YCount - 1) then exit;
|
||||
deltaP := Item[APointIndex]^.GetY(pidx);
|
||||
if not InRange(pidx, 0, YCount-1) then exit;
|
||||
if (nidx <> -1) and not InRange(nidx, 0, YCount-1) then exit;
|
||||
AUpperDelta := Item[APointIndex]^.GetY(pidx);
|
||||
if nidx = -1 then
|
||||
deltaN := deltaP
|
||||
ALowerDelta := AUpperDelta
|
||||
else
|
||||
deltaN := Item[APointIndex]^.GetY(nidx);
|
||||
ALowerDelta := Item[APointIndex]^.GetY(nidx);
|
||||
end;
|
||||
end;
|
||||
AUpperLimit := v + abs(deltaP);
|
||||
ALowerLimit := v - abs(deltaN);
|
||||
Result := (AUpperLimit <> ALowerLimit);
|
||||
AUpperDelta := abs(AUpperDelta);
|
||||
ALowerDelta := abs(ALowerDelta);
|
||||
Result := (AUpperDelta <> 0) and (ALowerDelta <> 0);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCustomChartSource.GetXErrorBarLimits(APointIndex: Integer;
|
||||
out AUpperLimit, ALowerLimit: Double): Boolean;
|
||||
var
|
||||
v, dxp, dxn: Double;
|
||||
begin
|
||||
Result := GetErrorBarLimits(APointIndex, 0, AUpperLimit, ALowerLimit);
|
||||
Result := GetErrorBarValues(APointIndex, 0, dxp, dxn);
|
||||
v := Item[APointIndex]^.X;
|
||||
if Result and not IsNaN(v) then begin
|
||||
AUpperLimit := v + dxp;
|
||||
ALowerLimit := v - dxn;
|
||||
end else begin
|
||||
AUpperLimit := v;
|
||||
ALowerLimit := v;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCustomChartSource.GetYErrorBarLimits(APointIndex: Integer;
|
||||
out AUpperLimit, ALowerLimit: Double): Boolean;
|
||||
var
|
||||
v, dyp, dyn: Double;
|
||||
begin
|
||||
Result := GetErrorBarLimits(APointIndex, 1, AUpperLimit, ALowerLimit);
|
||||
Result := GetErrorBarValues(APointIndex, 1, dyp, dyn);
|
||||
v := Item[APointIndex]^.Y;
|
||||
if Result and not IsNaN(v) then begin
|
||||
AUpperLimit := v + dyp;
|
||||
ALowerLimit := v - dyn;
|
||||
end else begin
|
||||
AUpperLimit := v;
|
||||
ALowerLimit := v;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCustomChartSource.GetXErrorBarValues(APointIndex: Integer;
|
||||
out AUpperDelta, ALowerDelta: Double): Boolean;
|
||||
begin
|
||||
Result := GetErrorBarValues(APointIndex, 0, AUpperDelta, ALowerDelta);
|
||||
end;
|
||||
|
||||
function TCustomChartSource.GetYErrorBarValues(APointIndex: Integer;
|
||||
out AUpperDelta, ALowerDelta: Double): Boolean;
|
||||
begin
|
||||
Result := GetErrorBarValues(APointIndex, 1, AUpperDelta, ALowerDelta);
|
||||
end;
|
||||
|
||||
function TCustomChartSource.GetHasErrorBars(Which: Integer): Boolean;
|
||||
|
@ -173,6 +173,8 @@ type
|
||||
property PointsNumber: Integer
|
||||
read FPointsNumber write SetPointsNumber default 0;
|
||||
property Sorted: Boolean read FSorted write FSorted default false;
|
||||
property XErrorBarData;
|
||||
property YErrorBarData;
|
||||
end;
|
||||
|
||||
TChartAccumulationMethod = (
|
||||
@ -812,6 +814,7 @@ function TRandomChartSource.GetItem(AIndex: Integer): PChartDataItem;
|
||||
|
||||
var
|
||||
i: Integer;
|
||||
fp, fn: Double;
|
||||
begin
|
||||
if FCurIndex > AIndex then begin
|
||||
FRNG.Seed := FRandSeed;
|
||||
@ -837,12 +840,12 @@ begin
|
||||
end;
|
||||
// Make sure that x values belonging to an error bar are random and
|
||||
// multiplied by the percentage given by ErrorBarData.Pos/NegDelta.
|
||||
fp := XErrorBarData.ValuePlus * PERCENT;
|
||||
if XErrorBarData.ValueMinus = -1 then fn := fp else fn := XErrorBarData.ValueMinus * PERCENT;
|
||||
for i := 0 to XCount - 2 do
|
||||
if (XErrorBarData.Kind = ebkChartSource) then begin
|
||||
if (i+1 = XErrorBarData.IndexPlus) and (XErrorBarData.ValuePlus > 0) then
|
||||
FCurItem.XList[i] := GetRandomX * XErrorBarData.ValuePlus * PERCENT;
|
||||
if (i+1 = XErrorBarData.IndexMinus) and (XErrorBarData.ValueMinus > 0) then
|
||||
FCurItem.XList[i] := GetRandomX * XErrorBarData.ValueMinus * PERCENT;
|
||||
if (i+1 = XErrorBarData.IndexPlus) then FCurItem.XList[i] := GetRandomX * fp;
|
||||
if (i+1 = XErrorBarData.IndexMinus) then FCurItem.XList[i] := GetRandomX * fn;
|
||||
end;
|
||||
end;
|
||||
if YCount > 0 then begin
|
||||
@ -853,11 +856,11 @@ begin
|
||||
// If this y value is that of an error bar assume that the error is
|
||||
// a percentage of the y value calculated. The percentage is the
|
||||
// ErrorBarData.Pos/NegDelta.
|
||||
fp := YErrorBarData.ValuePlus * PERCENT;
|
||||
if YErrorBarData.ValueMinus = -1 then fn := fp else fn := YErrorBarData.ValueMinus * PERCENT;
|
||||
if (YErrorBarData.Kind = ebkChartSource) then begin
|
||||
if (i+1 = YErrorBarData.IndexPlus) and (YErrorBarData.ValuePlus > 0) then
|
||||
FCurItem.YList[i] := FCurItem.YList[i] * YErrorBarData.ValuePlus * PERCENT;
|
||||
if (i+1 = YErrorBarData.IndexMinus) and (YErrorBarData.ValueMinus > 0) then
|
||||
FCurItem.YList[i] := FCurItem.YList[i] * YErrorBarData.ValueMinus * PERCENT;
|
||||
if (i+1 = YErrorBarData.IndexPlus) then FCurItem.YList[i] := GetRandomY * fp;
|
||||
if (i+1 = YErrorBarData.IndexMinus) then FCurItem.YList[i] := GetRandomY * fn;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user