From ba09e05aa3cd1f0cf37b7121a7bcd2a2e720dc0a Mon Sep 17 00:00:00 2001 From: wp Date: Wed, 15 Jul 2020 13:54:00 +0000 Subject: [PATCH] TAChart: Fit confidence level can be changed in FitDemo now. Issue #37354. git-svn-id: trunk@63566 - --- components/tachart/demo/fit/Main.lfm | 146 +++++++++++------- components/tachart/demo/fit/Main.pas | 73 +++++++-- components/tachart/demo/fit/fitdemo.lpi | 6 +- .../tachart/languages/tachartstrconsts.de.po | 4 + .../tachart/languages/tachartstrconsts.fi.po | 4 + .../tachart/languages/tachartstrconsts.fr.po | 4 + .../tachart/languages/tachartstrconsts.hu.po | 4 + .../tachart/languages/tachartstrconsts.lt.po | 4 + .../tachart/languages/tachartstrconsts.pl.po | 4 + .../tachart/languages/tachartstrconsts.pot | 4 + .../languages/tachartstrconsts.pt_BR.po | 4 + .../tachart/languages/tachartstrconsts.ru.po | 4 + .../tachart/languages/tachartstrconsts.se.po | 4 + .../tachart/languages/tachartstrconsts.uk.po | 4 + .../languages/tachartstrconsts.zh_CN.po | 4 + components/tachart/tachartstrconsts.pas | 1 + components/tachart/tafitutils.pas | 8 +- components/tachart/tafuncseries.pas | 38 ++++- 18 files changed, 240 insertions(+), 80 deletions(-) diff --git a/components/tachart/demo/fit/Main.lfm b/components/tachart/demo/fit/Main.lfm index a7bda71c96..bad23a07a2 100644 --- a/components/tachart/demo/fit/Main.lfm +++ b/components/tachart/demo/fit/Main.lfm @@ -1,28 +1,28 @@ object frmMain: TfrmMain Left = 319 - Height = 503 + Height = 543 Top = 133 Width = 1026 Caption = 'frmMain' - ClientHeight = 503 + ClientHeight = 543 ClientWidth = 1026 OnCreate = FormCreate ShowHint = True LCLVersion = '2.1.0.0' object pnlParams: TPanel Left = 8 - Height = 487 + Height = 527 Top = 8 Width = 400 Align = alLeft BorderSpacing.Around = 8 BevelOuter = bvNone - ClientHeight = 487 + ClientHeight = 527 ClientWidth = 400 TabOrder = 0 object PageControl1: TPageControl Left = 0 - Height = 487 + Height = 527 Top = 0 Width = 400 ActivePage = TabSheet1 @@ -31,7 +31,7 @@ object frmMain: TfrmMain TabOrder = 0 object TabSheet1: TTabSheet Caption = 'Preparation' - ClientHeight = 459 + ClientHeight = 499 ClientWidth = 392 object gbDataGeneration: TGroupBox Left = 4 @@ -101,11 +101,11 @@ object frmMain: TfrmMain AnchorSideTop.Control = gbDataGeneration AnchorSideRight.Control = gbDataGeneration AnchorSideRight.Side = asrBottom - Left = 101 + Left = 100 Height = 23 Hint = 'Select a dataset for fitting' Top = 4 - Width = 271 + Width = 272 Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 16 BorderSpacing.Top = 4 @@ -123,7 +123,7 @@ object frmMain: TfrmMain Left = 16 Height = 15 Top = 8 - Width = 69 + Width = 68 BorderSpacing.Left = 16 Caption = 'Test function' ParentColor = False @@ -134,7 +134,7 @@ object frmMain: TfrmMain AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = edNoiseY AnchorSideTop.Side = asrCenter - Left = 175 + Left = 174 Height = 15 Top = 35 Width = 64 @@ -159,23 +159,22 @@ object frmMain: TfrmMain AnchorSideLeft.Control = cbTestFunction AnchorSideTop.Control = cbTestFunction AnchorSideTop.Side = asrBottom - Left = 101 + Left = 100 Height = 23 Top = 31 Width = 66 BorderSpacing.Top = 4 DecimalPlaces = 0 - MinValue = 0 OnChange = edNoiseYChange ParentFont = False TabOrder = 1 Value = 10 end - object EdPointsCount: TSpinEdit + object edPointsCount: TSpinEdit AnchorSideLeft.Control = cbTestFunction AnchorSideTop.Control = edNoiseY AnchorSideTop.Side = asrBottom - Left = 101 + Left = 100 Height = 23 Top = 58 Width = 66 @@ -183,14 +182,14 @@ object frmMain: TfrmMain BorderSpacing.Bottom = 8 MaxValue = 65535 MinValue = 1 - OnChange = EdPointsCountChange + OnChange = edPointsCountChange ParentFont = False TabOrder = 2 Value = 100 end object lblNoiseY1: TLabel AnchorSideLeft.Control = lblTestFunction - AnchorSideTop.Control = EdPointsCount + AnchorSideTop.Control = edPointsCount AnchorSideTop.Side = asrCenter Left = 16 Height = 15 @@ -202,7 +201,7 @@ object frmMain: TfrmMain end object Bevel1: TBevel AnchorSideLeft.Control = gbDataGeneration - AnchorSideTop.Control = EdPointsCount + AnchorSideTop.Control = edPointsCount AnchorSideTop.Side = asrBottom AnchorSideRight.Control = gbDataGeneration AnchorSideRight.Side = asrBottom @@ -251,15 +250,17 @@ object frmMain: TfrmMain end end object gbFitting: TGroupBox - Left = 0 - Height = 290 + Left = 4 + Height = 330 Top = 169 - Width = 392 + Width = 384 Align = alClient + BorderSpacing.Left = 4 BorderSpacing.Top = 8 + BorderSpacing.Right = 4 Caption = ' Fitting ' - ClientHeight = 270 - ClientWidth = 388 + ClientHeight = 310 + ClientWidth = 380 Font.Style = [fsBold] ParentFont = False TabOrder = 1 @@ -272,13 +273,13 @@ object frmMain: TfrmMain Left = 14 Height = 109 Top = 151 - Width = 360 + Width = 352 Anchors = [akTop, akLeft, akRight] AutoSize = True BorderSpacing.Top = 16 Caption = 'Fit range' ClientHeight = 89 - ClientWidth = 356 + ClientWidth = 348 Font.Style = [fsBold] ParentFont = False TabOrder = 0 @@ -303,7 +304,7 @@ object frmMain: TfrmMain Left = 16 Height = 19 Top = 31 - Width = 96 + Width = 97 BorderSpacing.Top = 8 Caption = 'Use maximum' OnClick = cbFitRangeUseMaxClick @@ -405,7 +406,7 @@ object frmMain: TfrmMain Height = 23 Hint = 'Select a function type to be used for fitting to the generated data' Top = 4 - Width = 285 + Width = 277 Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 12 BorderSpacing.Top = 4 @@ -445,13 +446,13 @@ object frmMain: TfrmMain Left = 14 Height = 61 Top = 74 - Width = 360 + Width = 352 Anchors = [akTop, akLeft, akRight] AutoSize = True BorderSpacing.Top = 16 Caption = 'Fixed parameters (check to keep constant)' ClientHeight = 41 - ClientWidth = 356 + ClientWidth = 348 TabOrder = 3 object cbFitParam0Fixed: TCheckBox AnchorSideLeft.Control = GroupBox1 @@ -483,12 +484,11 @@ object frmMain: TfrmMain OnChange = FixedParamsChanged ParentFont = False TabOrder = 1 - Value = 0 end object cbFitParam1Fixed: TCheckBox AnchorSideTop.Control = cbFitParam0Fixed AnchorSideRight.Control = edFitParam1 - Left = 220 + Left = 212 Height = 19 Top = 6 Width = 44 @@ -502,7 +502,7 @@ object frmMain: TfrmMain AnchorSideTop.Control = edFitParam0 AnchorSideRight.Control = GroupBox1 AnchorSideRight.Side = asrBottom - Left = 264 + Left = 256 Height = 23 Top = 4 Width = 80 @@ -513,18 +513,52 @@ object frmMain: TfrmMain OnChange = FixedParamsChanged ParentFont = False TabOrder = 3 - Value = 0 end end + object edConfLevel: TFloatSpinEdit + AnchorSideTop.Control = gbFitRange + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = cbFitEquation + AnchorSideRight.Side = asrBottom + Left = 312 + Height = 23 + Top = 272 + Width = 54 + Anchors = [akTop, akRight] + BorderSpacing.Top = 12 + BorderSpacing.Bottom = 8 + Increment = 0.01 + MaxValue = 1 + OnChange = edConfLevelChange + ParentFont = False + TabOrder = 4 + Value = 0.95 + end + object lblConfLevel: TLabel + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = edConfLevel + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = edConfLevel + Left = 220 + Height = 15 + Top = 276 + Width = 88 + Anchors = [akTop, akRight] + BorderSpacing.Left = 8 + BorderSpacing.Right = 4 + Caption = 'Confidence level' + ParentColor = False + ParentFont = False + end end end object TabSheet2: TTabSheet Caption = 'Results' - ClientHeight = 459 + ClientHeight = 499 ClientWidth = 392 object lbResults: TListBox Left = 0 - Height = 459 + Height = 499 Top = 0 Width = 392 Align = alClient @@ -542,18 +576,18 @@ object frmMain: TfrmMain end object pnlChart: TPanel Left = 429 - Height = 487 + Height = 527 Top = 8 Width = 589 Align = alClient BorderSpacing.Around = 8 BevelOuter = bvNone - ClientHeight = 487 + ClientHeight = 527 ClientWidth = 589 TabOrder = 1 object Chart: TChart Left = 0 - Height = 445 + Height = 485 Top = 0 Width = 589 AxisList = < @@ -662,7 +696,7 @@ object frmMain: TfrmMain object pnlLog: TPanel Left = 0 Height = 42 - Top = 445 + Top = 485 Width = 589 Align = alBottom AutoSize = True @@ -676,7 +710,7 @@ object frmMain: TfrmMain Left = 0 Height = 19 Top = 0 - Width = 92 + Width = 93 Caption = 'Logarithmic x' OnClick = cbLogClick TabOrder = 0 @@ -733,7 +767,7 @@ object frmMain: TfrmMain OnChange = cbShowPredictionIntervalsChange TabOrder = 4 end - object CbHTML: TCheckBox + object cbHTML: TCheckBox AnchorSideLeft.Control = cbShowConfidenceIntervals AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = pnlLog @@ -741,46 +775,46 @@ object frmMain: TfrmMain Left = 401 Height = 19 Top = 12 - Width = 53 + Width = 52 BorderSpacing.Left = 16 Caption = 'HTML' - OnChange = CbHTMLChange + OnChange = cbHTMLChange TabOrder = 5 end - object CbCombinedExtent: TCheckBox - AnchorSideLeft.Control = CbHTML + object cbCombinedExtent: TCheckBox + AnchorSideLeft.Control = cbHTML AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = pnlLog AnchorSideTop.Side = asrCenter - Left = 470 + Left = 469 Height = 19 Top = 12 - Width = 111 + Width = 112 BorderSpacing.Left = 16 Caption = 'Combined extent' - OnChange = CbCombinedExtentChange + OnChange = cbCombinedExtentChange TabOrder = 6 end end end object Splitter1: TSplitter Left = 416 - Height = 503 + Height = 543 Top = 0 Width = 5 ResizeStyle = rsPattern end object ListChartSource: TListChartSource - left = 584 - top = 120 + Left = 584 + Top = 120 end object SaveDialog: TSaveDialog - left = 480 - top = 64 + Left = 480 + Top = 64 end object ChartAxisTransformations: TChartAxisTransformations - left = 584 - top = 184 + Left = 584 + Top = 184 object LogarithmAxisTransform: TLogarithmAxisTransform Base = 10 end @@ -788,7 +822,7 @@ object frmMain: TfrmMain object OpenDialog1: TOpenDialog DefaultExt = '.txt' Filter = 'Text files|*.txt|CSV files|*.csv' - left = 72 - top = 184 + Left = 72 + Top = 184 end end diff --git a/components/tachart/demo/fit/Main.pas b/components/tachart/demo/fit/Main.pas index ee10718a41..cfc04b0724 100644 --- a/components/tachart/demo/fit/Main.pas +++ b/components/tachart/demo/fit/Main.pas @@ -24,8 +24,10 @@ type cbShowErrorbars: TCheckBox; cbShowConfidenceIntervals: TCheckBox; cbShowPredictionIntervals: TCheckBox; - CbHTML: TCheckBox; - CbCombinedExtent: TCheckBox; + cbHTML: TCheckBox; + cbCombinedExtent: TCheckBox; + edConfLevel: TFloatSpinEdit; + lblConfLevel: TLabel; UpperConfIntervalSeries: TFuncSeries; LowerConfIntervalSeries: TFuncSeries; UpperPredIntervalSeries: TFuncSeries; @@ -64,23 +66,21 @@ type pnlChart: TPanel; SaveDialog: TSaveDialog; btnSave: TSpeedButton; - EdPointsCount: TSpinEdit; + edPointsCount: TSpinEdit; Splitter1: TSplitter; TabSheet1: TTabSheet; TabSheet2: TTabSheet; procedure BtnLoadClick(Sender: TObject); procedure btnSaveClick(Sender: TObject); - procedure CbCombinedExtentChange(Sender: TObject); + procedure cbCombinedExtentChange(Sender: TObject); procedure cbDrawFitRangeOnlyClick(Sender: TObject); procedure cbFitEquationSelect(Sender: TObject); - procedure CbHTMLChange(Sender: TObject); + procedure cbHTMLChange(Sender: TObject); procedure cbShowConfidenceIntervalsChange(Sender: TObject); procedure cbShowErrorbarsChange(Sender: TObject); procedure cbShowPredictionIntervalsChange(Sender: TObject); - procedure EdPointsCountChange(Sender: TObject); - procedure FitSeriesFitEquationText(ASeries: TFitSeries; - AEquationText: IFitEquationText); - procedure FixedParamsChanged(Sender: TObject); + procedure edConfLevelChange(Sender: TObject); + procedure edPointsCountChange(Sender: TObject); procedure cbFitRangeUseMaxClick(Sender:TObject); procedure cbFitRangeUseMinClick(Sender:TObject); procedure cbLogClick(Sender: TObject); @@ -89,8 +89,11 @@ type procedure edFitRangeMaxChange(Sender:TObject); procedure edFitRangeMinChange(Sender:TObject); procedure edNoiseYChange(Sender: TObject); - procedure FormCreate(Sender: TObject); procedure FitCompleteHandler(Sender:TObject); + procedure FitSeriesFitEquationText(ASeries: TFitSeries; + AEquationText: IFitEquationText); + procedure FixedParamsChanged(Sender: TObject); + procedure FormCreate(Sender: TObject); procedure lbResultsDrawItem(Control: TWinControl; Index: Integer; ARect: TRect; State: TOwnerDrawState); private @@ -180,9 +183,9 @@ begin end; end; -procedure TfrmMain.CbCombinedExtentChange(Sender: TObject); +procedure TfrmMain.cbCombinedExtentChange(Sender: TObject); begin - FitSeries.UseCombinedExtentY := CbCombinedExtent.Checked; + FitSeries.UseCombinedExtentY := cbCombinedExtent.Checked; end; procedure TfrmMain.BtnLoadClick(Sender: TObject); @@ -250,9 +253,9 @@ begin end; end; -procedure TfrmMain.CbHTMLChange(Sender: TObject); +procedure TfrmMain.cbHTMLChange(Sender: TObject); begin - if CbHtml.Checked then Chart.Legend.TextFormat := tfHTML else Chart.Legend.TextFormat := tfNormal; + if cbHTML.Checked then Chart.Legend.TextFormat := tfHTML else Chart.Legend.TextFormat := tfNormal; FitSeries.Title := 'fitted data'; // the fit equation is appended automatically due to FitSeries.Legend.Format end; @@ -288,7 +291,12 @@ begin LowerPredIntervalSeries.Active := cbShowPredictionIntervals.Checked; end; -procedure TfrmMain.EdPointsCountChange(Sender: TObject); +procedure TfrmMain.edConfLevelChange(Sender: TObject); +begin + FitSeries.ConfidenceLevel := edConfLevel.Value; +end; + +procedure TfrmMain.edPointsCountChange(Sender: TObject); begin CreateData; end; @@ -297,7 +305,7 @@ procedure TfrmMain.FitSeriesFitEquationText(ASeries: TFitSeries; AEquationText: IFitEquationText); begin AEquationText.NumFormat('%.5f'); - if CbHTML.Checked then + if cbHTML.Checked then AEquationText.TextFormat(tfHtml) else AEquationText.TextFormat(tfNormal); @@ -355,7 +363,7 @@ var xarr, yarr: array of Double; begin RandSeed := 875876; // Reproducible noise for testing. - n := EdPointsCount.Value; + n := edPointsCount.Value; if n = 0 then begin MessageDlg('No data', mtError, [mbOK], 0); exit; @@ -438,6 +446,9 @@ end; function MyFormatFloat(x: Double; StdFormat, ExpFormat: String): String; begin + if IsNaN(x) then + Result := 'n/a' + else if (abs(x) <= 1E-6) or (abs(x) >= 1E6) then Result := Format(ExpFormat, [x]) else @@ -461,6 +472,7 @@ var decsep: Char; paramName: String; confL, confH: Double; + predL, predH: Double; begin decsep := DefaultFormatSettings.DecimalSeparator; with lbResults.Items do begin @@ -529,6 +541,30 @@ begin UpperPredIntervalSeries.OnCalculate := @FitSeries.GetUpperPredictionInterval; LowerPredIntervalSeries.OnCalculate := @FitSeries.GetLowerPredictionInterval; {$IFEND} + + Add(''); + Add('VALUES'); + {$IF FPC_FullVersion >= 30004} + Add(Format('%8s %8s %8s %8s %8s %8s %8s', ['x', 'y', 'y hat', 'confL', 'confH', 'predL', 'predH'])); + for i := 0 to FitSeries.Count-1 do + begin + FitSeries.GetLowerConfidenceInterval(FitSeries.XValue[i], confL); + FitSeries.GetUpperConfidenceInterval(FitSeries.XValue[i], confH); + FitSeries.GetLowerPredictionInterval(FitSeries.XValue[i], predL); + FitSeries.GetUpperPredictionInterval(FitSeries.XValue[i], predH); + Add(Format('%8.2f %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f', [ + FitSeries.XValue[i], FitSeries.YValue[i], FitSeries.Calculate(FitSeries.XValue[i]), + confL, confH, predL, predH])); + end; + {$ELSE} + Add(Format('%8s %8s %8s', ['x', 'y', 'y hat'])); + for i := 0 to FitSeries.Count-1 do + begin + Add(Format('%8.2f %8.2f %8.2f', [ + FitSeries.XValue[i], FitSeries.YValue[i], FitSeries.Calculate(FitSeries.XValue[i]) + ])); + end; + {$IFEND} end; else Add(FitSeries.ErrorMsg); @@ -634,6 +670,7 @@ begin FitSeries.ListSource.YCount := 1; FitSeries.ListSource.YErrorBarData.Kind := ebkNone; end; + FitSeries.BeginUpdate; for i:=0 to L.Count-1 do begin LC.DelimitedText := L[i]; @@ -650,6 +687,8 @@ begin FitSeries.AddXY(x, y); end; FDemoData := false; + FitSeries.EndUpdate; + FitSeries.ExecFit; finally L.Free; end; diff --git a/components/tachart/demo/fit/fitdemo.lpi b/components/tachart/demo/fit/fitdemo.lpi index 3d8a3e3de5..bc764822d5 100644 --- a/components/tachart/demo/fit/fitdemo.lpi +++ b/components/tachart/demo/fit/fitdemo.lpi @@ -1,11 +1,13 @@ - + + + + - <ResourceType Value="res"/> <UseXPManifest Value="True"/> diff --git a/components/tachart/languages/tachartstrconsts.de.po b/components/tachart/languages/tachartstrconsts.de.po index fbe426b644..2e417cc14c 100644 --- a/components/tachart/languages/tachartstrconsts.de.po +++ b/components/tachart/languages/tachartstrconsts.de.po @@ -275,6 +275,10 @@ msgstr "Quadratsumme der Residuen" msgid "Total sum of squares (SST)" msgstr "Gesamte Quadratsumme (SST)" +#: tachartstrconsts.rsfittvalue +msgid "t value" +msgstr "" + #: tachartstrconsts.rsfitvarianceratio msgid "Variance ratio F" msgstr "Varianzverhältnis" diff --git a/components/tachart/languages/tachartstrconsts.fi.po b/components/tachart/languages/tachartstrconsts.fi.po index afa1d5b670..971cc2bb5a 100644 --- a/components/tachart/languages/tachartstrconsts.fi.po +++ b/components/tachart/languages/tachartstrconsts.fi.po @@ -263,6 +263,10 @@ msgstr "" msgid "Total sum of squares (SST)" msgstr "" +#: tachartstrconsts.rsfittvalue +msgid "t value" +msgstr "" + #: tachartstrconsts.rsfitvarianceratio msgid "Variance ratio F" msgstr "" diff --git a/components/tachart/languages/tachartstrconsts.fr.po b/components/tachart/languages/tachartstrconsts.fr.po index beac3a29c7..b056405a51 100644 --- a/components/tachart/languages/tachartstrconsts.fr.po +++ b/components/tachart/languages/tachartstrconsts.fr.po @@ -273,6 +273,10 @@ msgstr "Erreur standard résiduelle" msgid "Total sum of squares (SST)" msgstr "Total de la somme des carrés (SST)" +#: tachartstrconsts.rsfittvalue +msgid "t value" +msgstr "" + #: tachartstrconsts.rsfitvarianceratio msgid "Variance ratio F" msgstr "Rapport de variance F" diff --git a/components/tachart/languages/tachartstrconsts.hu.po b/components/tachart/languages/tachartstrconsts.hu.po index 088124dac9..f266ccc13a 100644 --- a/components/tachart/languages/tachartstrconsts.hu.po +++ b/components/tachart/languages/tachartstrconsts.hu.po @@ -273,6 +273,10 @@ msgstr "" msgid "Total sum of squares (SST)" msgstr "" +#: tachartstrconsts.rsfittvalue +msgid "t value" +msgstr "" + #: tachartstrconsts.rsfitvarianceratio msgid "Variance ratio F" msgstr "" diff --git a/components/tachart/languages/tachartstrconsts.lt.po b/components/tachart/languages/tachartstrconsts.lt.po index 12a22de045..3d7b11433e 100644 --- a/components/tachart/languages/tachartstrconsts.lt.po +++ b/components/tachart/languages/tachartstrconsts.lt.po @@ -274,6 +274,10 @@ msgstr "" msgid "Total sum of squares (SST)" msgstr "" +#: tachartstrconsts.rsfittvalue +msgid "t value" +msgstr "" + #: tachartstrconsts.rsfitvarianceratio msgid "Variance ratio F" msgstr "" diff --git a/components/tachart/languages/tachartstrconsts.pl.po b/components/tachart/languages/tachartstrconsts.pl.po index 7129d0560b..ec92c22868 100644 --- a/components/tachart/languages/tachartstrconsts.pl.po +++ b/components/tachart/languages/tachartstrconsts.pl.po @@ -273,6 +273,10 @@ msgstr "" msgid "Total sum of squares (SST)" msgstr "" +#: tachartstrconsts.rsfittvalue +msgid "t value" +msgstr "" + #: tachartstrconsts.rsfitvarianceratio msgid "Variance ratio F" msgstr "" diff --git a/components/tachart/languages/tachartstrconsts.pot b/components/tachart/languages/tachartstrconsts.pot index 2d2b04f49b..3f02045edf 100644 --- a/components/tachart/languages/tachartstrconsts.pot +++ b/components/tachart/languages/tachartstrconsts.pot @@ -263,6 +263,10 @@ msgstr "" msgid "Total sum of squares (SST)" msgstr "" +#: tachartstrconsts.rsfittvalue +msgid "t value" +msgstr "" + #: tachartstrconsts.rsfitvarianceratio msgid "Variance ratio F" msgstr "" diff --git a/components/tachart/languages/tachartstrconsts.pt_BR.po b/components/tachart/languages/tachartstrconsts.pt_BR.po index c2a6ef8dcf..e7d857227d 100644 --- a/components/tachart/languages/tachartstrconsts.pt_BR.po +++ b/components/tachart/languages/tachartstrconsts.pt_BR.po @@ -273,6 +273,10 @@ msgstr "Erro residual padrão" msgid "Total sum of squares (SST)" msgstr "Soma total de quadrados (SST)" +#: tachartstrconsts.rsfittvalue +msgid "t value" +msgstr "" + #: tachartstrconsts.rsfitvarianceratio msgid "Variance ratio F" msgstr "Razão de variação F" diff --git a/components/tachart/languages/tachartstrconsts.ru.po b/components/tachart/languages/tachartstrconsts.ru.po index fbb2c0598e..33192dad40 100644 --- a/components/tachart/languages/tachartstrconsts.ru.po +++ b/components/tachart/languages/tachartstrconsts.ru.po @@ -273,6 +273,10 @@ msgstr "Остаточное стандартное отклонение" msgid "Total sum of squares (SST)" msgstr "Полная сумма квадратов (SST)" +#: tachartstrconsts.rsfittvalue +msgid "t value" +msgstr "" + #: tachartstrconsts.rsfitvarianceratio msgid "Variance ratio F" msgstr "Дисперсионное отношение F" diff --git a/components/tachart/languages/tachartstrconsts.se.po b/components/tachart/languages/tachartstrconsts.se.po index 6c54624b4e..fe2478c19c 100644 --- a/components/tachart/languages/tachartstrconsts.se.po +++ b/components/tachart/languages/tachartstrconsts.se.po @@ -276,6 +276,10 @@ msgstr "" msgid "Total sum of squares (SST)" msgstr "" +#: tachartstrconsts.rsfittvalue +msgid "t value" +msgstr "" + #: tachartstrconsts.rsfitvarianceratio msgid "Variance ratio F" msgstr "" diff --git a/components/tachart/languages/tachartstrconsts.uk.po b/components/tachart/languages/tachartstrconsts.uk.po index 3af5570e28..a92ab908a5 100644 --- a/components/tachart/languages/tachartstrconsts.uk.po +++ b/components/tachart/languages/tachartstrconsts.uk.po @@ -276,6 +276,10 @@ msgstr "Остаточна стандартна похибка" msgid "Total sum of squares (SST)" msgstr "Загальна сума квадратів (SSE)" +#: tachartstrconsts.rsfittvalue +msgid "t value" +msgstr "" + #: tachartstrconsts.rsfitvarianceratio msgid "Variance ratio F" msgstr "Коефіцієнт варіації F" diff --git a/components/tachart/languages/tachartstrconsts.zh_CN.po b/components/tachart/languages/tachartstrconsts.zh_CN.po index 33af374e01..77e9e6374d 100644 --- a/components/tachart/languages/tachartstrconsts.zh_CN.po +++ b/components/tachart/languages/tachartstrconsts.zh_CN.po @@ -274,6 +274,10 @@ msgstr "" msgid "Total sum of squares (SST)" msgstr "" +#: tachartstrconsts.rsfittvalue +msgid "t value" +msgstr "" + #: tachartstrconsts.rsfitvarianceratio msgid "Variance ratio F" msgstr "" diff --git a/components/tachart/tachartstrconsts.pas b/components/tachart/tachartstrconsts.pas index b7f00a14a1..423405070f 100644 --- a/components/tachart/tachartstrconsts.pas +++ b/components/tachart/tachartstrconsts.pas @@ -160,6 +160,7 @@ resourcestring rsFitReducedChiSquared = 'Reduced Chi-squared'; rsFitResidualStandardError = 'Residual standard error'; rsFitVarianceRatio = 'Variance ratio F'; + rsFitTValue = 't value'; rsFitPValue = 'p value'; diff --git a/components/tachart/tafitutils.pas b/components/tachart/tafitutils.pas index 3d40e38574..51ce6488fa 100644 --- a/components/tachart/tafitutils.pas +++ b/components/tachart/tafitutils.pas @@ -105,8 +105,8 @@ type function Chi2: Double; function DOF: Integer; // Degrees of freedom function F: Double; - property N: Integer read fN; - property M: Integer read fM; + property N: Integer read fN; // Number of data points + property M: Integer read fM; // Number of fit parameters function ReducedChi2: Double; function R2: Double; function ResidualStdError: Double; @@ -526,7 +526,7 @@ end; procedure TFitStatistics.Report_ANOVA(AText: TStrings; ASeparator: String = ': '; ANumFormat: String = '%f'); const - FMT = '%.3f'; + FMT = '%.3e'; begin AText.Add(rsFitNumObservations + ASeparator + IntToStr(N)); AText.Add(rsFitNumFitParams + ASeparator + IntToStr(M)); @@ -548,6 +548,8 @@ begin Format(IfThen(Fcrit < 1E-3, FMT, ANumFormat), [Fcrit])); } {$IF FPC_FullVersion >= 30004} + AText.Add(rsFitTValue + ASeparator + + Format(IfThen(FtValue < 1E-3, '%.3e', ANumFormat), [FtValue])); AText.Add(rsFitPValue + ASeparator + Format(IfThen(pValue < 1E-3, '%.3e', ANumFormat), [pValue])); {$IFEND} diff --git a/components/tachart/tafuncseries.pas b/components/tachart/tafuncseries.pas index c23124dfce..62c140ced6 100644 --- a/components/tachart/tafuncseries.pas +++ b/components/tachart/tafuncseries.pas @@ -301,6 +301,7 @@ type FErrCode: TFitErrCode; FFitStatistics: TFitStatistics; FConfidenceLevel: Double; + FLockFit: Integer; function GetParam(AIndex: Integer): Double; function GetParamCount: Integer; function GetParamError(AIndex: Integer): Double; @@ -308,6 +309,7 @@ type function GetParam_RawValue(AIndex: Integer): Double; function GetParam_tValue(AIndex: Integer): Double; function IsFixedParamsStored: Boolean; + procedure SetConfidenceLevel(AValue: Double); procedure SetDrawFitRangeOnly(AValue: Boolean); procedure SetFitEquation(AValue: TFitEquation); procedure SetFitRange(AValue: TChartRange); @@ -337,8 +339,11 @@ type constructor Create(AOwner: TComponent); override; destructor Destroy; override; public + procedure BeginUpdate; function Calculate(AX: Double): Double; virtual; + procedure Clear; override; procedure Draw(ADrawer: IChartDrawer); override; + procedure EndUpdate; function ErrorMsg: String; procedure ExecFit; virtual; function Extent: TDoubleRect; override; @@ -364,7 +369,7 @@ type {$IFEND} property Param_tValue[AIndex: Integer]: Double read GetParam_tValue; property FitStatistics: TFitStatistics read FFitStatistics; - property ConfidenceLevel: Double read FConfidenceLevel write FConfidenceLevel; + property ConfidenceLevel: Double read FConfidenceLevel write SetConfidenceLevel; property ErrCode: TFitErrCode read FErrCode; property State: TFitParamsState read FState; published @@ -1634,6 +1639,12 @@ begin FFitRange.SetOwner(ParentChart); end; +procedure TFitSeries.BeginUpdate; +begin + inherited BeginUpdate; + inc(FLockFit); +end; + function TFitSeries.Calculate(AX: Double): Double; var i: Integer; @@ -1690,6 +1701,12 @@ begin end; end; +procedure TFitSeries.Clear; +begin + inherited; + InvalidateFitResults; +end; + procedure TFitSeries.Assign(ASource: TPersistent); begin if ASource is TFitSeries then @@ -1762,6 +1779,14 @@ begin end; end; +procedure TFitSeries.EndUpdate; +begin + inherited EndUpdate; + dec(FLockFit); + if (FLockFit = 0) and FAutoFit then + ExecFit; +end; + function TFitSeries.EquationText: IFitEquationText; var basis: Array of string; @@ -1879,7 +1904,7 @@ var begin if (State <> fpsUnknown) or not Active or IsEmpty or (FChart = nil) or - ([csLoading, csDestroying] * ComponentState <> []) + ([csLoading, csDestroying] * ComponentState <> []) or (FLockFit > 0) then exit; FState := fpsInvalid; @@ -2242,6 +2267,15 @@ begin end; end; +procedure TFitSeries.SetConfidenceLevel(AValue: Double); +begin + if FConfidenceLevel = AValue then exit; + FConfidenceLevel := AValue; + InvalidateFitResults; + if FAutoFit then + ExecFit; +end; + procedure TFitSeries.SetDrawFitRangeOnly(AValue: Boolean); begin if FDrawFitRangeOnly = AValue then exit;