TAChart: Add TFitSeries.IEquationText interface, deprecate previous methods of getting equation text

git-svn-id: trunk@38258 -
This commit is contained in:
ask 2012-08-16 16:09:02 +00:00
parent 71c6aaaf43
commit af9adfd054

View File

@ -209,6 +209,38 @@ type
);
TFitSeries = class(TBasicPointSeries)
public
type
IEquationText = interface
function Equation(AEquation: TFitEquation): IEquationText;
function X(AText: String): IEquationText;
function Y(AText: String): IEquationText;
function NumFormat(AFormat: String): IEquationText;
function NumFormats(const AFormats: array of String): IEquationText;
function Params(const AParams: array of Double): IEquationText;
function Get: String;
end;
TEquationText = class(TInterfacedObject, IEquationText)
strict private
FEquation: TFitEquation;
FX: String;
FY: String;
FNumFormat: String;
FNumFormats: array of String;
FParams: array of Double;
function GetNumFormat(AIndex: Integer): String;
public
constructor Create;
function Equation(AEquation: TFitEquation): IEquationText;
function X(AText: String): IEquationText;
function Y(AText: String): IEquationText;
function NumFormat(AFormat: String): IEquationText;
function NumFormats(const AFormats: array of String): IEquationText;
function Params(const AParams: array of Double): IEquationText;
function Get: String;
end;
strict private
FDrawFitRangeOnly: Boolean;
FFitEquation: TFitEquation;
@ -242,8 +274,10 @@ type
function Calculate(AX: Double): Double; virtual;
procedure Draw(ADrawer: IChartDrawer); override;
procedure ExecFit; virtual;
function EquationText: IEquationText;
function GetFitEquationString(
ANumFormat: String; AXText: String = 'x'; AYText: String = 'y'): String; virtual;
ANumFormat: String; AXText: String = 'x'; AYText: String = 'y'): String;
deprecated 'Use EquationText';
function GetNearestPoint(
const AParams: TNearestPointParams;
out AResults: TNearestPointResults): Boolean; override;
@ -311,9 +345,14 @@ type
read FStepY write SetStepY default DEF_COLORMAP_STEP;
end;
// Builds an equation string based on the parameters and the type of equation.
// AXText and AYText are placeholders for the x and y variables, respectively.
// Parameters are formatted by passing ANumFormat to the "Format" function.
function ParamsToEquation(
AEquation: TFitEquation; const AParams: array of Double;
ANumFormat: String; AXText: String = 'x'; AYText: String = 'y'): String;
deprecated 'Use TFitSeries.IEquationText';
operator :=(AEq: TFitSeries.IEquationText): String; inline;
implementation
@ -365,35 +404,108 @@ begin
Result.Y := AX;
end;
// Builds an equation string based on the parameters and the type of equation.
// AXText and AYText are placeholders for the x and y variables, respectively.
// Parameters are formatted by passing ANumFormat to the "Format" function.
function ParamsToEquation(
AEquation: TFitEquation; const AParams: array of Double;
ANumFormat, AXText, AYText: String): String;
begin
Result :=
TFitSeries.TEquationText.Create.Equation(AEquation).
X(AXText).Y(AYText).NumFormat(ANumFormat).Params(AParams);
end;
operator := (AEq: TFitSeries.IEquationText): String;
begin
Result := AEq.Get;
end;
{ TFitSeries.TEquationText }
constructor TFitSeries.TEquationText.Create;
begin
FX := 'x';
FY := 'y';
FNumFormat := '%.9g';
end;
function TFitSeries.TEquationText.Equation(
AEquation: TFitEquation): IEquationText;
begin
FEquation := AEquation;
Result := Self;
end;
function TFitSeries.TEquationText.Get: String;
var
ps: String = '';
i: Integer;
begin
if Length(AParams) = 0 then exit('');
Result := Format('%s = ' + ANumFormat, [AYText, AParams[0]]);
if AEquation in [fePolynomial, feLinear] then
for i := 1 to High(AParams) do begin
if AParams[i] = 0 then continue;
if Length(FParams) = 0 then exit('');
Result := Format('%s = ' + GetNumFormat(0), [FY, FParams[0]]);
if FEquation in [fePolynomial, feLinear] then
for i := 1 to High(FParams) do begin
if FParams[i] = 0 then continue;
if i > 1 then ps := Format('^%d', [i]);
Result += Format(
' %s ' + ANumFormat + '*%s%s',
[IfThen(AParams[i] > 0, '+', '-'), Abs(AParams[i]), AXText, ps]);
' %s ' + GetNumFormat(i) + '*%s%s',
[IfThen(FParams[i] > 0, '+', '-'), Abs(FParams[i]), FX, ps]);
end
else if (Length(AParams) >= 2) and (AParams[0] <> 0) and (AParams[1] <> 0) then
case AEquation of
else if (Length(FParams) >= 2) and (FParams[0] <> 0) and (FParams[1] <> 0) then
case FEquation of
feExp:
Result += Format(' * exp(' + ANumFormat +' * %s)', [AParams[1], AXText]);
Result += Format(' * exp(' + GetNumFormat(1) +' * %s)', [FParams[1], FX]);
fePower:
Result += Format(' * %s^' + ANumFormat, [AXText, AParams[1]]);
Result += Format(' * %s^' + GetNumFormat(1), [FX, FParams[1]]);
end;
end;
function TFitSeries.TEquationText.GetNumFormat(AIndex: Integer): String;
begin
if AIndex < Length(FNumFormats) then
Result := FNumFormats[AIndex]
else
Result := FNumFormat;
end;
function TFitSeries.TEquationText.NumFormat(AFormat: String): IEquationText;
begin
FNumFormat := AFormat;
Result := Self;
end;
function TFitSeries.TEquationText.NumFormats(
const AFormats: array of String): IEquationText;
var
i: Integer;
begin
SetLength(FNumFormats, Length(AFormats));
for i := 0 to High(AFormats) do
FNumFormats[i] := AFormats[i];
Result := Self;
end;
function TFitSeries.TEquationText.Params(
const AParams: array of Double): IEquationText;
var
i: Integer;
begin
SetLength(FParams, Length(AParams));
for i := 0 to High(AParams) do
FParams[i] := AParams[i];
Result := Self;
end;
function TFitSeries.TEquationText.X(AText: String): IEquationText;
begin
FX := AText;
Result := Self;
end;
function TFitSeries.TEquationText.Y(AText: String): IEquationText;
begin
FY := AText;
Result := Self;
end;
{ TFitSeriesRange }
constructor TFitSeriesRange.Create(ASeries: TFitSeries);
@ -1159,6 +1271,11 @@ begin
end;
end;
function TFitSeries.EquationText: IEquationText;
begin
Result := TEquationText.Create.Equation(FitEquation).Params(FFitParams);
end;
procedure TFitSeries.ExecFit;
var
i, j, term, ns, np, n: Integer;
@ -1214,10 +1331,10 @@ begin
UpdateParentChart;
end;
function TFitSeries.GetFitEquationString(
ANumFormat, AXText, AYText: String): String;
function TFitSeries.GetFitEquationString(ANumFormat: String; AXText: String;
AYText: String): String;
begin
Result := ParamsToEquation(FFitEquation, FFitParams, ANumFormat, AXText, AYText);
Result := EquationText.NumFormat(ANumFormat).X(AXText).Y(AYText);
end;
procedure TFitSeries.GetLegendItems(AItems: TChartLegendItems);
@ -1227,7 +1344,7 @@ begin
if Legend.Format = '' then
t := Title
else
t := Format(Legend.Format, [Title, Index, GetFitEquationString('%f')]);
t := Format(Legend.Format, [Title, Index, EquationText.NumFormat('%f').Get]);
AItems.Add(TLegendItemLine.Create(Pen, t));
end;