mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-19 02:59:19 +02:00
TAChart: Add chartsource indexes for error bar values to TChartErrorBarData. Fix RandomChartSource to create error bar data only if XCount and YCount are sufficiently large.
git-svn-id: trunk@58601 -
This commit is contained in:
parent
117f0ddf30
commit
ba7960c0bd
@ -1200,17 +1200,19 @@ procedure TBasicPointSeries.DrawErrorBars(ADrawer: IChartDrawer);
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if Assigned(YErrorBars) and YErrorBars.Visible and Source.HasYErrorBars then
|
// Draw x error bars
|
||||||
begin
|
|
||||||
ADrawer.Pen := YErrorBars.Pen;
|
|
||||||
InternalDrawErrorBars(false);
|
|
||||||
end;
|
|
||||||
|
|
||||||
if Assigned(XErrorBars) and XErrorBars.Visible and Source.HasXErrorBars then
|
if Assigned(XErrorBars) and XErrorBars.Visible and Source.HasXErrorBars then
|
||||||
begin
|
begin
|
||||||
ADrawer.pen := XErrorBars.Pen;
|
ADrawer.pen := XErrorBars.Pen;
|
||||||
InternalDrawErrorBars(true);
|
InternalDrawErrorBars(true);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Draw y error bars
|
||||||
|
if Assigned(YErrorBars) and YErrorBars.Visible and Source.HasYErrorBars then
|
||||||
|
begin
|
||||||
|
ADrawer.Pen := YErrorBars.Pen;
|
||||||
|
InternalDrawErrorBars(false);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TBasicPointSeries.DrawLabels(ADrawer: IChartDrawer);
|
procedure TBasicPointSeries.DrawLabels(ADrawer: IChartDrawer);
|
||||||
|
@ -155,9 +155,13 @@ type
|
|||||||
private
|
private
|
||||||
FKind: TChartErrorBarKind;
|
FKind: TChartErrorBarKind;
|
||||||
FValue: array[0..1] of Double; // 0 = positive, 1 = negative
|
FValue: array[0..1] of Double; // 0 = positive, 1 = negative
|
||||||
|
FIndex: array[0..1] of Integer;
|
||||||
FOnChange: TNotifyEvent;
|
FOnChange: TNotifyEvent;
|
||||||
|
procedure Changed;
|
||||||
|
function GetIndex(AIndex: Integer): Integer;
|
||||||
function GetValue(AIndex: Integer): Double;
|
function GetValue(AIndex: Integer): Double;
|
||||||
procedure SetKind(AValue: TChartErrorbarKind);
|
procedure SetKind(AValue: TChartErrorbarKind);
|
||||||
|
procedure SetIndex(AIndex, AValue: Integer);
|
||||||
procedure SetValue(AIndex: Integer; AValue: Double);
|
procedure SetValue(AIndex: Integer; AValue: Double);
|
||||||
public
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
@ -166,7 +170,10 @@ type
|
|||||||
published
|
published
|
||||||
property Kind: TChartErrorBarKind read FKind write SetKind default ebkNone;
|
property Kind: TChartErrorBarKind read FKind write SetKind default ebkNone;
|
||||||
property NegDelta: Double index 1 read GetValue write SetValue;
|
property NegDelta: Double index 1 read GetValue write SetValue;
|
||||||
|
property NegIndex: Integer index 1 read GetIndex write SetIndex default -1;
|
||||||
property PosDelta: Double index 0 read GetValue write SetValue;
|
property PosDelta: Double index 0 read GetValue write SetValue;
|
||||||
|
property PosIndex: Integer index 0 read GetIndex write SetIndex default -1;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TCustomChartSource = class(TBasicChartSource)
|
TCustomChartSource = class(TBasicChartSource)
|
||||||
@ -693,8 +700,10 @@ end;
|
|||||||
constructor TChartErrorBarData.Create;
|
constructor TChartErrorBarData.Create;
|
||||||
begin
|
begin
|
||||||
inherited;
|
inherited;
|
||||||
FValue[0] := -1;
|
FIndex[0] := -1;
|
||||||
FValue[1] := -1;
|
FIndex[1] := -1;
|
||||||
|
FValue[0] := 0;
|
||||||
|
FValue[1] := 0;
|
||||||
FKind := ebkNone;
|
FKind := ebkNone;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -702,27 +711,46 @@ procedure TChartErrorBarData.Assign(ASource: TPersistent);
|
|||||||
begin
|
begin
|
||||||
if ASource is TChartErrorBarData then begin
|
if ASource is TChartErrorBarData then begin
|
||||||
FValue := TChartErrorBarData(ASource).FValue;
|
FValue := TChartErrorBarData(ASource).FValue;
|
||||||
|
FIndex := TChartErrorBarData(ASource).FIndex;
|
||||||
FKind := TChartErrorBarData(ASource).Kind;
|
FKind := TChartErrorBarData(ASource).Kind;
|
||||||
end;
|
end;
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TChartErrorBarData.Changed;
|
||||||
|
begin
|
||||||
|
if Assigned(FOnChange) then FOnChange(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TChartErrorBarData.GetIndex(AIndex: Integer): Integer;
|
||||||
|
begin
|
||||||
|
Result := FIndex[AIndex];
|
||||||
|
end;
|
||||||
|
|
||||||
function TChartErrorBarData.GetValue(AIndex: Integer): Double;
|
function TChartErrorBarData.GetValue(AIndex: Integer): Double;
|
||||||
begin
|
begin
|
||||||
Result := FValue[AIndex];
|
Result := FValue[AIndex];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TChartErrorBarData.SetIndex(AIndex, AValue: Integer);
|
||||||
|
begin
|
||||||
|
if FIndex[AIndex] = AValue then exit;
|
||||||
|
FIndex[AIndex] := AValue;
|
||||||
|
Changed;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TChartErrorBarData.SetKind(AValue: TChartErrorBarKind);
|
procedure TChartErrorBarData.SetKind(AValue: TChartErrorBarKind);
|
||||||
begin
|
begin
|
||||||
if FKind = AValue then exit;
|
if FKind = AValue then exit;
|
||||||
FKind := AValue;
|
FKind := AValue;
|
||||||
if Assigned(FOnChange) then FOnChange(self);
|
Changed;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TChartErrorBarData.SetValue(AIndex: Integer; AValue: Double);
|
procedure TChartErrorBarData.SetValue(AIndex: Integer; AValue: Double);
|
||||||
begin
|
begin
|
||||||
|
if FValue[AIndex] = AValue then exit;
|
||||||
FValue[AIndex] := AValue;
|
FValue[AIndex] := AValue;
|
||||||
if Assigned(FOnChange) then FOnChange(self);
|
Changed;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -823,8 +851,8 @@ begin
|
|||||||
|
|
||||||
// Skip the y values used for error bars in calculating the cumulative sum.
|
// Skip the y values used for error bars in calculating the cumulative sum.
|
||||||
if YErrorBarData.Kind = ebkChartSource then begin
|
if YErrorBarData.Kind = ebkChartSource then begin
|
||||||
jyp := round(YErrorBarData.PosDelta) - 1; // -1 because YList index is offset by 1
|
jyp := YErrorBarData.PosIndex - 1; // -1 because YList index is offset by 1
|
||||||
jyn := round(YErrorBarData.NegDelta) - 1;
|
jyn := YErrorBarData.NegIndex - 1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
for i := 0 to Count - 1 do begin
|
for i := 0 to Count - 1 do begin
|
||||||
@ -850,15 +878,15 @@ begin
|
|||||||
|
|
||||||
// Skip then x and y values used for error bars when calculating the list extent.
|
// Skip then x and y values used for error bars when calculating the list extent.
|
||||||
if XErrorBarData.Kind = ebkChartSource then begin
|
if XErrorBarData.Kind = ebkChartSource then begin
|
||||||
jxp := round(XErrorBarData.PosDelta) - 1; // -1 because XList is offset by 1
|
jxp := XErrorBarData.PosIndex - 1; // -1 because XList is offset by 1
|
||||||
jxn := round(XErrorBarData.NegDelta) - 1;
|
jxn := XErrorBarData.NegIndex - 1;
|
||||||
end else begin
|
end else begin
|
||||||
jxp := -1;
|
jxp := -1;
|
||||||
jyp := -1;
|
jxn := -1;
|
||||||
end;
|
end;
|
||||||
if YErrorBarData.Kind = ebkChartSource then begin
|
if YErrorBarData.Kind = ebkChartSource then begin
|
||||||
jyp := round(YErrorbarData.PosDelta) - 1; // -1 because YList is offset by 1
|
jyp := YErrorbarData.PosIndex - 1; // -1 because YList is offset by 1
|
||||||
jyn := round(YErrorBarData.NegDelta) - 1;
|
jyn := YErrorBarData.NegIndex - 1;
|
||||||
end else begin
|
end else begin
|
||||||
jyp := -1;
|
jyp := -1;
|
||||||
jyn := -1;
|
jyn := -1;
|
||||||
@ -967,6 +995,7 @@ function TCustomChartSource.GetErrorBarLimits(APointIndex: Integer;
|
|||||||
var
|
var
|
||||||
v: Double;
|
v: Double;
|
||||||
deltaP, deltaN: Double;
|
deltaP, deltaN: Double;
|
||||||
|
pidx, nidx: Integer;
|
||||||
begin
|
begin
|
||||||
Result := false;
|
Result := false;
|
||||||
|
|
||||||
@ -1002,23 +1031,31 @@ begin
|
|||||||
deltaN := v * FErrorBarData[Which].NegDelta * PERCENT;
|
deltaN := v * FErrorBarData[Which].NegDelta * PERCENT;
|
||||||
end;
|
end;
|
||||||
ebkChartSource:
|
ebkChartSource:
|
||||||
begin
|
if Which = 0 then begin
|
||||||
if Which = 0 then
|
pidx := FErrorBarData[0].PosIndex;
|
||||||
deltaP := Item[APointIndex]^.GetX(round(FErrorbarData[0].PosDelta))
|
nidx := FErrorBarData[0].NegIndex;
|
||||||
else
|
if not InRange(pidx, 0, XCount - 1) then exit;
|
||||||
deltaP := Item[APointIndex]^.GetY(round(FErrorBarData[1].PosDelta));
|
if (nidx <> -1) and not InRange(nidx, 0, XCount - 1) then exit;
|
||||||
if FErrorBarData[Which].NegDelta = -1 then
|
deltaP := Item[APointIndex]^.GetX(pidx);
|
||||||
|
if nidx = -1 then
|
||||||
deltaN := deltaP
|
deltaN := deltaP
|
||||||
else
|
else
|
||||||
if Which = 0 then
|
deltaN := Item[APointIndex]^.GetX(nidx);
|
||||||
deltaN := Item[APointIndex]^.GetX(round(FErrorBarData[Which].NegDelta))
|
end else begin
|
||||||
|
pidx := FErrorBarData[1].PosIndex;
|
||||||
|
nidx := FErrorBarData[1].NegIndex;
|
||||||
|
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 nidx = -1 then
|
||||||
|
deltaN := deltaP
|
||||||
else
|
else
|
||||||
deltaN := Item[APointIndex]^.GetY(round(FErrorBarData[Which].NegDelta));
|
deltaN := Item[APointIndex]^.GetY(nidx);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
AUpperLimit := v + abs(deltaP);
|
AUpperLimit := v + abs(deltaP);
|
||||||
ALowerLimit := v - abs(deltaN);
|
ALowerLimit := v - abs(deltaN);
|
||||||
Result := true;
|
Result := (AUpperLimit <> ALowerLimit);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1044,7 +1081,7 @@ begin
|
|||||||
ebkConst, ebkPercent:
|
ebkConst, ebkPercent:
|
||||||
Result := (FErrorBarData[Which].PosDelta > 0);
|
Result := (FErrorBarData[Which].PosDelta > 0);
|
||||||
ebkChartSource:
|
ebkChartSource:
|
||||||
Result := (FErrorBarData[Which].PosDelta > -1);
|
Result := (FErrorBarData[Which].PosIndex > -1);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1066,14 +1103,19 @@ end;
|
|||||||
|
|
||||||
function TCustomChartSource.IsXErrorIndex(AXIndex: Integer): Boolean;
|
function TCustomChartSource.IsXErrorIndex(AXIndex: Integer): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := (XErrorBarData.Kind = ebkChartSource) and
|
Result :=
|
||||||
((round(XErrorBarData.PosDelta) = AXIndex) or (round(XErrorBarData.NegDelta) = AXIndex));
|
(XErrorBarData.Kind = ebkChartSource) and
|
||||||
|
((XErrorBarData.PosIndex = AXIndex) or (XErrorBarData.NegIndex = AXIndex) and
|
||||||
|
(AXIndex > -1)
|
||||||
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomChartSource.IsYErrorIndex(AYIndex: Integer): Boolean;
|
function TCustomChartSource.IsYErrorIndex(AYIndex: Integer): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := (YErrorBarData.Kind = ebkChartSource) and
|
Result :=
|
||||||
((round(YErrorBarData.PosDelta) = AYIndex) or (round(YErrorBarData.NegDelta) = AYIndex));
|
(YErrorBarData.Kind = ebkChartSource) and
|
||||||
|
((YErrorBarData.PosIndex = AYIndex) or (YErrorBarData.NegIndex = AYIndex)) and
|
||||||
|
(AYIndex > -1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomChartSource.IsSorted: Boolean;
|
function TCustomChartSource.IsSorted: Boolean;
|
||||||
|
Loading…
Reference in New Issue
Block a user