diff --git a/applications/lazstats/source/forms/analysis/descriptive/normalityunit.lfm b/applications/lazstats/source/forms/analysis/descriptive/normalityunit.lfm index e25884918..b76cee588 100644 --- a/applications/lazstats/source/forms/analysis/descriptive/normalityunit.lfm +++ b/applications/lazstats/source/forms/analysis/descriptive/normalityunit.lfm @@ -8,98 +8,42 @@ inherited NormalityFrm: TNormalityFrm Caption = 'Normality Tests' ClientHeight = 516 ClientWidth = 998 - OnActivate = FormActivate - OnCreate = FormCreate - Position = poMainFormCenter - object ParamsPanel: TPanel[0] - Left = 8 + inherited ParamsPanel: TPanel Height = 500 - Top = 8 - Width = 320 - Align = alLeft - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - BorderSpacing.Right = 4 - BorderSpacing.Bottom = 8 - BevelOuter = bvNone ClientHeight = 500 - ClientWidth = 320 - TabOrder = 0 - object Panel1: TPanel + inherited CloseBtn: TButton + Top = 475 + TabOrder = 5 + end + inherited ComputeBtn: TButton + Top = 475 + TabOrder = 6 + end + inherited ResetBtn: TButton + Top = 475 + TabOrder = 7 + end + inherited HelpBtn: TButton + Top = 475 + TabOrder = 8 + end + inherited ButtonBevel: TBevel + Top = 459 + end + object Panel1: TPanel[5] AnchorSideRight.Control = ParamsPanel AnchorSideRight.Side = asrBottom Left = 0 - Height = 26 - Top = 474 - Width = 320 + Height = 0 + Top = 500 + Width = 291 Align = alBottom AutoSize = True BorderSpacing.Top = 6 BevelOuter = bvNone - ClientHeight = 26 - ClientWidth = 320 TabOrder = 0 - object CloseBtn: TButton - AnchorSideTop.Control = Panel1 - AnchorSideTop.Side = asrCenter - AnchorSideRight.Control = Panel1 - AnchorSideRight.Side = asrBottom - Left = 265 - Height = 25 - Top = 1 - Width = 55 - Anchors = [akTop, akRight] - AutoSize = True - BorderSpacing.Left = 8 - Caption = 'Close' - ModalResult = 11 - OnClick = CloseBtnClick - TabOrder = 0 - end - object ComputeBtn: TButton - AnchorSideTop.Control = Panel1 - AnchorSideTop.Side = asrCenter - AnchorSideRight.Control = CloseBtn - Left = 181 - Height = 25 - Top = 1 - Width = 76 - Anchors = [akTop, akRight] - AutoSize = True - BorderSpacing.Left = 8 - Caption = 'Compute' - OnClick = ComputeBtnClick - TabOrder = 1 - end - object ResetBtn: TButton - AnchorSideTop.Control = Panel1 - AnchorSideTop.Side = asrCenter - AnchorSideRight.Control = ComputeBtn - Left = 119 - Height = 25 - Top = 1 - Width = 54 - Anchors = [akTop, akRight] - AutoSize = True - BorderSpacing.Right = 8 - Caption = 'Reset' - OnClick = ResetBtnClick - TabOrder = 2 - end end - object Bevel1: TBevel - AnchorSideLeft.Control = ParamsPanel - AnchorSideRight.Control = ParamsPanel - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = Panel1 - Left = 0 - Height = 8 - Top = 460 - Width = 320 - Anchors = [akLeft, akRight, akBottom] - Shape = bsBottomLine - end - object Label1: TLabel + object Label1: TLabel[6] AnchorSideLeft.Control = ParamsPanel AnchorSideTop.Control = ParamsPanel Left = 0 @@ -109,16 +53,16 @@ inherited NormalityFrm: TNormalityFrm Caption = 'Variables:' ParentColor = False end - object VarList: TListBox + object VarList: TListBox[7] AnchorSideLeft.Control = ParamsPanel AnchorSideTop.Control = Label1 AnchorSideTop.Side = asrBottom AnchorSideRight.Control = VarInBtn - AnchorSideBottom.Control = Bevel1 + AnchorSideBottom.Control = ButtonBevel Left = 0 - Height = 443 + Height = 442 Top = 17 - Width = 140 + Width = 125 Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Top = 2 BorderSpacing.Right = 6 @@ -127,13 +71,13 @@ inherited NormalityFrm: TNormalityFrm OnSelectionChange = VarListSelectionChange TabOrder = 1 end - object VarInBtn: TBitBtn + object VarInBtn: TBitBtn[8] AnchorSideLeft.Control = ParamsPanel AnchorSideLeft.Side = asrCenter AnchorSideTop.Control = VarList AnchorSideRight.Control = VarList AnchorSideRight.Side = asrBottom - Left = 146 + Left = 131 Height = 28 Top = 17 Width = 28 @@ -143,12 +87,12 @@ inherited NormalityFrm: TNormalityFrm Spacing = 0 TabOrder = 2 end - object VarOutBtn: TBitBtn + object VarOutBtn: TBitBtn[9] AnchorSideLeft.Control = ParamsPanel AnchorSideLeft.Side = asrCenter AnchorSideTop.Control = VarInBtn AnchorSideTop.Side = asrBottom - Left = 146 + Left = 131 Height = 28 Top = 49 Width = 28 @@ -160,28 +104,28 @@ inherited NormalityFrm: TNormalityFrm Spacing = 0 TabOrder = 3 end - object TestVarEdit: TEdit + object TestVarEdit: TEdit[10] AnchorSideLeft.Control = VarOutBtn AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = Label2 AnchorSideTop.Side = asrBottom AnchorSideRight.Control = ParamsPanel AnchorSideRight.Side = asrBottom - Left = 180 + Left = 165 Height = 23 Top = 45 - Width = 140 + Width = 126 Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 6 BorderSpacing.Top = 2 TabOrder = 4 Text = 'TestVarEdit' end - object Label2: TLabel + object Label2: TLabel[11] AnchorSideLeft.Control = TestVarEdit AnchorSideBottom.Control = VarInBtn AnchorSideBottom.Side = asrBottom - Left = 180 + Left = 165 Height = 15 Top = 28 Width = 93 @@ -191,31 +135,11 @@ inherited NormalityFrm: TNormalityFrm ParentColor = False end end - object ParamsSplitter: TSplitter[1] - Left = 332 + inherited ParamsSplitter: TSplitter Height = 516 - Top = 0 - Width = 5 - ResizeStyle = rsPattern end - object PageControl: TPageControl[2] - Left = 341 + inherited PageControl: TPageControl Height = 500 - Top = 8 - Width = 649 - ActivePage = ChartPage - Align = alClient - BorderSpacing.Left = 4 - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - BorderSpacing.Bottom = 8 - TabIndex = 1 - TabOrder = 2 - object ReportPage: TTabSheet - Caption = 'Report' - end - object ChartPage: TTabSheet - Caption = 'Chart' - end + Width = 678 end end diff --git a/applications/lazstats/source/forms/analysis/descriptive/normalityunit.pas b/applications/lazstats/source/forms/analysis/descriptive/normalityunit.pas index f85eb1762..a2ec54d35 100644 --- a/applications/lazstats/source/forms/analysis/descriptive/normalityunit.pas +++ b/applications/lazstats/source/forms/analysis/descriptive/normalityunit.pas @@ -9,7 +9,7 @@ interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons, ExtCtrls, ComCtrls, - MainUnit, Globals, FunctionsLib, DataProcs, BasicStatsFormUnit, + MainUnit, Globals, FunctionsLib, DataProcs, BasicStatsReportAndChartFormUnit, ReportFrameUnit, ChartFrameUnit; @@ -17,46 +17,33 @@ type { TNormalityFrm } - TNormalityFrm = class(TBasicStatsForm) - Bevel1: TBevel; - PageControl: TPageControl; - ParamsPanel: TPanel; - ResetBtn: TButton; - ComputeBtn: TButton; - CloseBtn: TButton; + TNormalityFrm = class(TBasicStatsReportAndChartForm) Panel1: TPanel; - ParamsSplitter: TSplitter; - ReportPage: TTabSheet; - ChartPage: TTabSheet; TestVarEdit: TEdit; Label2: TLabel; VarInBtn: TBitBtn; VarOutBtn: TBitBtn; Label1: TLabel; VarList: TListBox; - procedure CloseBtnClick(Sender: TObject); - procedure ComputeBtnClick(Sender: TObject); - procedure FormActivate(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure ResetBtnClick(Sender: TObject); procedure VarInBtnClick(Sender: TObject); procedure VarListDblClick(Sender: TObject); - procedure VarListSelectionChange(Sender: TObject; User: boolean); + procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean); procedure VarOutBtnClick(Sender: TObject); private { private declarations } - FReportFrame: TReportFrame; - FChartFrame: TChartFrame; - FAutoSized: boolean; - function Calc_ShapiroWilks(const AData: DblDyneVec; out W, Prob: Double): Boolean; + function Calc_ShapiroWilks(const AData: DblDyneVec; var W, Prob: Double): Boolean; procedure Calc_Lilliefors(const AData: DblDyneVec; out ASkew, AKurtosis, AStat: Double; out AConclusion: String); procedure PlotData(AData: DblDyneVec); function PrepareData(const VarName: String): DblDyneVec; - procedure UpdateBtnStates; + protected + procedure AdjustConstraints; override; + procedure Compute; override; + procedure UpdateBtnStates; override; + public - { public declarations } + constructor Create(AOwner: TComponent); override; procedure Reset; override; end; @@ -70,7 +57,7 @@ implementation uses Math, MathUnit, TAChartUtils, TATextElements, TACustomSeries, TATransformations, - TAChartAxisUtils, TAChartAxis, TACustomSource, TASources, + TAChartAxisUtils, TAChartAxis, TASources, Utils; @@ -89,9 +76,6 @@ end; function PopulateRightMarks(AOwner: TComponent): TListChartSource; -const - SIGMA = 1; - MEAN = 0; var i: Integer; z: Double; @@ -99,13 +83,13 @@ begin Result := TListChartSource.Create(AOwner); for i := -6 to -1 do begin - z := NormalDist(i); //*SIGMA, MEAN, SIGMA); + z := NormalDist(i); Result.Add(z, z, 'μ -' + IntToStr(-i) + ' σ'); end; Result.Add(0.5, 0.5, 'Mean (μ)'); for i := 1 to 6 do begin - z := NormalDist(i); //*SIGMA, MEAN, SIGMA); + z := NormalDist(i); Result.Add(z, z, 'μ + ' + IntToStr(i) + ' σ'); end; end; @@ -113,6 +97,55 @@ end; { TNormalityFrm } +constructor TNormalityFrm.Create(AOwner: TComponent); +var + T : TChartAxisTransformations; + InvNormDistTransform: TAxisTransform; +begin + inherited; + + T := TChartAxisTransformations.Create(FChartFrame); + InvNormDistTransform := TCumulNormDistrAxisTransform.Create(T); + InvNormDistTransform.Transformations := T; + + with FChartFrame.Chart.LeftAxis do + begin + Transformations := T; + + Marks.Source := PopulateLeftMarks(FChartFrame.Chart); + Marks.Style := smsValue; + Marks.OverlapPolicy := opHideNeighbour; + end; + + with TChartAxis(FChartFrame.Chart.AxisList.Add) do + begin + Alignment := calRight; + Transformations := T; + Marks.Source := PopulateRightMarks(FChartFrame.Chart); + Marks.Style := smsLabel; + Marks.TextFormat := tfHTML; + Grid.Color := clSilver; + Grid.Style := psSolid; + end; +end; + + +procedure TNormalityFrm.AdjustConstraints; +begin + inherited; + + ParamsPanel.Constraints.MinWidth := Max( + 3*CloseBtn.Width + 2*CloseBtn.BorderSpacing.Left, + Max(Label1.Width, Label2.Width) + VarInBtn.Width + 2*VarList.BorderSpacing.Right); + ParamsPanel.Constraints.MinHeight := VarOutBtn.Top + VarOutBtn.Height + + VarOutBtn.BorderSpacing.Bottom + ButtonBevel.Height + Panel1.Height + + Panel1.BorderSpacing.Top; + + Constraints.MinWidth := ParamsPanel.Constraints.MinWidth + 300; + Constraints.MinHeight := ParamsPanel.Constraints.MinHeight + 2*ParamsPanel.BorderSpacing.Top; +end; + + procedure TNormalityFrm.Calc_Lilliefors(const AData: DblDyneVec; out ASkew, AKurtosis, AStat: Double; out AConclusion: String); var @@ -228,7 +261,7 @@ end; { Call Shapiro-Wilks function } function TNormalityFrm.Calc_ShapiroWilks(const AData: DblDyneVec; - out W, Prob: Double): boolean; + var W, Prob: Double): boolean; var init: Boolean = false; n, n1, n2: Integer; @@ -256,88 +289,7 @@ begin end; -procedure TNormalityFrm.CloseBtnClick(Sender: TObject); -begin - Close; -end; - - -procedure TNormalityFrm.FormActivate(Sender: TObject); -var - w: Integer; -begin - if FAutoSized then - exit; - - w := MaxValue([ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]); - ResetBtn.Constraints.MinWidth := w; - ComputeBtn.Constraints.MinWidth := w; - CloseBtn.Constraints.MinWidth := w; - - ParamsPanel.Constraints.MinWidth := Max( - 3*w + 2*CloseBtn.BorderSpacing.Left, - Max(Label1.Width, Label2.Width) + VarInBtn.Width + 2*VarList.BorderSpacing.Right); - ParamsPanel.Constraints.MinHeight := VarOutBtn.Top + VarOutBtn.Height + - VarOutBtn.BorderSpacing.Bottom + Bevel1.Height + Panel1.Height + - Panel1.BorderSpacing.Top; - - Constraints.MinWidth := ParamsPanel.Constraints.MinWidth + 300; - Constraints.MinHeight := ParamsPanel.Constraints.MinHeight + 2*ParamsPanel.BorderSpacing.Top; - - Position := poDesigned; - FAutoSized := True; -end; - -procedure TNormalityFrm.FormCreate(Sender: TObject); -var - T : TChartAxisTransformations; - InvNormDistTransform: TAxisTransform; - L: TListChartSource; - i: Integer; -begin - Assert(OS3MainFrm <> nil); - - InitForm(self); - - FReportFrame := TReportFrame.Create(self); - FReportFrame.Parent := ReportPage; - FReportFrame.Align := alClient; - - FChartFrame := TChartFrame.Create(self); - FChartFrame.Parent := ChartPage; - FChartFrame.Align := alClient; - FChartFrame.Chart.BottomAxis.Intervals.MaxLength := 80; - FChartFrame.Chart.BottomAxis.Intervals.MinLength := 30; - - T := TChartAxisTransformations.Create(FChartFrame); - InvNormDistTransform := TCumulNormDistrAxisTransform.Create(T); - InvNormDistTransform.Transformations := T; - - with FChartFrame.Chart.LeftAxis do - begin - Transformations := T; - - Marks.Source := PopulateLeftMarks(FChartFrame.Chart); - Marks.Style := smsValue; - Marks.OverlapPolicy := opHideNeighbour; - end; - - with TChartAxis(FChartFrame.Chart.AxisList.Add) do - begin - Alignment := calRight; - Transformations := T; - Marks.Source := PopulateRightMarks(FChartFrame.Chart); - Marks.Style := smsLabel; - Marks.TextFormat := tfHTML; - Grid.Color := clSilver; - Grid.Style := psSolid; - end; - - Reset; -end; - - -procedure TNormalityFrm.ComputeBtnClick(Sender: TObject); +procedure TNormalityFrm.Compute; var w: Double = 0.0; pw: Double = 0.0; @@ -347,6 +299,8 @@ var conclusion: String; lReport: TStrings; begin + inherited; + data := PrepareData(TestVarEdit.Text); if data = nil then exit; @@ -468,24 +422,23 @@ begin VarList.Items.Clear; for i := 1 to NoVariables do VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); - FReportFrame.Clear; - FChartFrame.Clear; + + if Assigned(FReportFrame) then + FReportFrame.Clear; + if Assigned(FChartFrame) then + FChartFrame.Clear; UpdateBtnStates; end; -procedure TNormalityFrm.ResetBtnClick(Sender: TObject); -begin - Reset; -end; - - procedure TNormalityFrm.UpdateBtnStates; begin VarInBtn.Enabled := (VarList.ItemIndex > -1) and (TestVarEdit.Text = ''); VarOutBtn.Enabled := (TestVarEdit.Text <> ''); - FReportFrame.UpdateBtnStates; - FChartFrame.UpdateBtnStates; + if Assigned(FReportFrame) then + FReportFrame.UpdateBtnStates; + if Assigned(FChartFrame) then + FChartFrame.UpdateBtnStates; end;