diff --git a/applications/lazstats/source/forms/analysis/comparisons/abranovaunit.lfm b/applications/lazstats/source/forms/analysis/comparisons/abranovaunit.lfm index 7cee9ce9f..32d3c6264 100644 --- a/applications/lazstats/source/forms/analysis/comparisons/abranovaunit.lfm +++ b/applications/lazstats/source/forms/analysis/comparisons/abranovaunit.lfm @@ -17,8 +17,8 @@ inherited ABRAnovaForm: TABRAnovaForm AnchorSideLeft.Control = ParamsPanel AnchorSideBottom.Control = ButtonBevel Left = 0 - Height = 51 - Top = 244 + Height = 72 + Top = 223 Width = 324 Anchors = [akLeft, akBottom] AutoSize = True @@ -29,7 +29,7 @@ inherited ABRAnovaForm: TABRAnovaForm ChildSizing.HorizontalSpacing = 24 ChildSizing.VerticalSpacing = 2 ChildSizing.ControlsPerLine = 2 - ClientHeight = 31 + ClientHeight = 52 ClientWidth = 320 TabOrder = 10 object PlotChk: TCheckBox @@ -42,6 +42,7 @@ inherited ABRAnovaForm: TABRAnovaForm Top = 6 Width = 79 Caption = 'Plot Means' + OnChange = PlotChkChange TabOrder = 1 end object TestChk: TCheckBox @@ -54,6 +55,20 @@ inherited ABRAnovaForm: TABRAnovaForm Caption = 'Test Homogeneity of Covariance' TabOrder = 0 end + object ThreeDChk: TCheckBox + AnchorSideLeft.Control = PlotChk + AnchorSideTop.Control = PlotChk + AnchorSideTop.Side = asrBottom + Left = 245 + Height = 19 + Top = 27 + Width = 34 + BorderSpacing.Left = 16 + Caption = '3D' + Enabled = False + OnChange = ThreeDChkChange + TabOrder = 2 + end end inherited CloseBtn: TButton[1] Left = 274 @@ -136,7 +151,7 @@ inherited ABRAnovaForm: TABRAnovaForm AnchorSideRight.Control = AInBtn AnchorSideBottom.Control = OptionsGroup Left = 0 - Height = 219 + Height = 198 Top = 17 Width = 145 Anchors = [akTop, akLeft, akRight, akBottom] @@ -290,7 +305,7 @@ inherited ABRAnovaForm: TABRAnovaForm AnchorSideBottom.Control = VarList AnchorSideBottom.Side = asrBottom Left = 183 - Height = 42 + Height = 21 Top = 194 Width = 146 Anchors = [akTop, akLeft, akRight, akBottom] @@ -314,9 +329,15 @@ inherited ABRAnovaForm: TABRAnovaForm ActivePage = ReportPage TabIndex = 0 inherited ReportPage: TTabSheet - Caption = 'ANOVA Results' + Caption = 'ANOVA Summary' end - inherited ChartPage: TTabSheet + object MeansPage: TTabSheet[1] + Caption = 'Means' + end + object BoxTestsPage: TTabSheet[2] + Caption = 'Box Tests' + end + inherited ChartPage: TTabSheet[3] Caption = 'Charts' end end diff --git a/applications/lazstats/source/forms/analysis/comparisons/abranovaunit.pas b/applications/lazstats/source/forms/analysis/comparisons/abranovaunit.pas index f33416f3c..53511e279 100644 --- a/applications/lazstats/source/forms/analysis/comparisons/abranovaunit.pas +++ b/applications/lazstats/source/forms/analysis/comparisons/abranovaunit.pas @@ -7,9 +7,11 @@ unit ABRANOVAUnit; interface uses - Classes, SysUtils, FileUtil, TASources, TAStyles, Forms, - Controls, Graphics, Dialogs, StdCtrls, Buttons, ExtCtrls, ComCtrls, MainUnit, - FunctionsLib, Globals, DataProcs, MatrixLib, BasicStatsReportAndChartFormUnit; + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, LCLVersion, + StdCtrls, Buttons, ExtCtrls, ComCtrls, + TASources, TAStyles, TASeries, + MainUnit, FunctionsLib, Globals, DataProcs, MatrixLib, + ReportFrameUnit, BasicStatsReportAndChartFormUnit; type @@ -21,6 +23,7 @@ type BInBtn: TBitBtn; BOutBtn: TBitBtn; ChartStyles: TChartStyles; + ThreeDChk: TCheckBox; CInBtn: TBitBtn; COutBtn: TBitBtn; ACodesEdit: TEdit; @@ -28,6 +31,8 @@ type ListChartSource_AB: TListChartSource; ListChartSource_AC: TListChartSource; ListChartSource_BC: TListChartSource; + MeansPage: TTabSheet; + BoxTestsPage: TTabSheet; TestChk: TCheckBox; PlotChk: TCheckBox; OptionsGroup: TGroupBox; @@ -46,6 +51,8 @@ type procedure CListDblClick(Sender: TObject); procedure CListSelectionChange(Sender: TObject; {%H-}User: boolean); procedure COutBtnClick(Sender: TObject); + procedure PlotChkChange(Sender: TObject); + procedure ThreeDChkChange(Sender: TObject); procedure VarListDblClick(Sender: TObject); private type TInteraction = (AB, AC, BC); @@ -65,12 +72,15 @@ type Acnt, Bcnt, Ccnt : IntDyneVec; ASums, BSums, CSums, SumPSqr : DblDyneVec; ABSums, ACSums, BCSums, AMatrix, PooledMat : DblDyneMat; - ABCSums : DblDyneCube; - ABCNcnt : IntDyneCube; + ABCSums: DblDyneCube; + ABCNcnt: IntDyneCube; RowLabels, ColLabels : StrDyneVec; selected : integer; + FMeansReportFrame: TReportFrame; + FBoxTestsReportFrame: TReportFrame; FBtnAB, FBtnAC, FBtnBC: TToolButton; + FBarSeries: TBarSeries; procedure InteractionChanged(Sender: TObject); function InitData: Boolean; @@ -79,6 +89,7 @@ type procedure Summarize(AReport: TStrings); procedure MeansReport(AReport: TStrings); procedure BoxTests(AReport: TStrings); + procedure PreparePlot; procedure PlotMeans(AInteraction: TInteraction); procedure CleanUp; @@ -103,7 +114,7 @@ implementation uses Math, - TAChartUtils, TALegend, TACustomSource, TACustomSeries, TASeries, + TAChartUtils, TALegend, TACustomSource, TACustomSeries, Utils, MathUnit, GridProcs, ChartFrameUnit; { TABRAnovaForm } @@ -114,6 +125,24 @@ var begin inherited; + FMeansReportFrame := TReportFrame.Create(self); + FMeansReportFrame.Name := ''; + FMeansReportFrame.Parent := MeansPage; + FMeansReportFrame.Align := alClient; + FMeansReportFrame.BorderSpacing.Left := 0; + FMeansReportFrame.BorderSpacing.Top := 0; + FMeansReportFrame.BorderSpacing.Bottom := 0; + FMeansReportFrame.BorderSpacing.Right := 0; + + FBoxTestsReportFrame := TReportFrame.Create(self); + FBoxTestsReportFrame.Name := ''; + FBoxTestsReportFrame.Parent := BoxTestsPage; + FBoxTestsReportFrame.Align := alClient; + FBoxTestsReportFrame.BorderSpacing.Left := 0; + FBoxTestsReportFrame.BorderSpacing.Top := 0; + FBoxTestsReportFrame.BorderSpacing.Bottom := 0; + FBoxTestsReportFrame.BorderSpacing.Right := 0; + FChartFrame.Chart.Margins.Bottom := 0; FChartFrame.Chart.BottomAxis.AxisPen.Visible := true; FChartFrame.Chart.BottomAxis.ZPosition := 1; @@ -122,7 +151,6 @@ begin FChartFrame.ChartToolbar.ShowCaptions := true; FChartFrame.ChartToolbar.ButtonHeight := 40;; - btn := TToolButton.Create(FChartFrame.ChartToolbar); btn.Style := tbsDivider; AddButtonToToolbar(btn, FChartFrame.ChartToolbar); @@ -252,11 +280,11 @@ begin Acnt := nil; SumPSqr := nil; AMatrix := nil; - { + //{ BCSums := nil; // needed for plotting ACSums := nil; ABSums := nil; - } + //} CSums := nil; BSums := nil; ASums := nil; @@ -297,19 +325,22 @@ begin Calculate; Summarize(lReport); MeansReport(lReport); + if TestChk.Checked then BoxTests(lReport); - - FReportFrame.DisplayReport(lReport); + BoxTestsPage.TabVisible := TestChk.Checked; + BoxTestsPage.PageIndex := PageControl.PageCount-2; if PlotChk.Checked then begin + PreparePlot; if FBtnAB.Down then interaction := AB else if FBtnAC.Down then interaction := AC else if FBtnBC.Down then interaction := BC; PlotMeans(interaction); end; ChartPage.TabVisible := PlotChk.Checked; + ChartPage.PageIndex := PageControl.PageCount-1; end; finally lReport.Free; @@ -337,6 +368,19 @@ begin UpdateBtnStates; end; +procedure TABRAnovaForm.PlotChkChange(Sender: TObject); +begin + ThreeDChk.Enabled := PlotChk.Checked; +end; + +procedure TABRAnovaForm.ThreeDChkChange(Sender: TObject); +const + DEPTH: array[boolean] of Integer = (0, 20); +begin + FBarSeries.Depth := DEPTH[ThreeDChk.Checked]; + FChartFrame.Chart.LeftAxis.Grid.Visible := not ThreeDChk.Checked; +end; + function TABRAnovaForm.InitData: Boolean; var @@ -662,32 +706,37 @@ end; procedure TABRAnovaForm.Summarize(AReport: TStrings); begin - AReport.Add('SOURCE DF SS MS F PROB.'); - AReport.Add(''); - AReport.Add('Between Subjects %5.0f%10.3f',[DFBetween,SSBetweenSubjects]); - AReport.Add(' A Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFA, SSA, MSA, FA, ProbA]); - AReport.Add(' B Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFB, SSB, MSB, FB, ProbB]); - AReport.Add(' AB Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFAB, SSAB, MSAB, FAB, ProbAB]); - AReport.Add(' Error Between %5.0f%10.3f%10.3f', [DFerrorBetween,SSerrorBetween,MSerrorBetween]); - AReport.Add(''); - AReport.Add('Within Subjects %5.0f%10.3f', [DFWithin,SSWithinSubjects]); - AReport.Add(' C Replications %5.0f%10.3f%10.3f%10.3f%10.3f', [DFC, SSC, MSC, FC, ProbC]); - AReport.Add(' AC Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFAC, SSAC, MSAC, FAC, ProbAC]); - AReport.Add(' BC Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFBC, SSBC, MSBC, FBC, ProbBC]); - AReport.Add(' ABC Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFABC, SSABC, MSABC, FABC, ProbABC]); - AReport.Add(' Error Within %5.0f%10.3f%10.3f', [DFerrorWithin, SSerrorWithin, MSerrorWithin]); - AReport.Add(''); - AReport.Add('Total %5.0f%10.3f', [DFBetween + DFWithin, SSBetweenSubjects + SSWithinSubjects]); - AReport.Add(''); -// OutputFrm.ShowModal; + AReport.Add('SOURCE DF SS MS F PROB.'); + AReport.Add(''); + AReport.Add('Between Subjects %5.0f%10.3f',[DFBetween, SSBetweenSubjects]); + AReport.Add(' A Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFA, SSA, MSA, FA, ProbA]); + AReport.Add(' B Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFB, SSB, MSB, FB, ProbB]); + AReport.Add(' AB Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFAB, SSAB, MSAB, FAB, ProbAB]); + AReport.Add(' Error Between %5.0f%10.3f%10.3f', [DFerrorBetween,SSerrorBetween,MSerrorBetween]); + AReport.Add(''); + AReport.Add('Within Subjects %5.0f%10.3f', [DFWithin, SSWithinSubjects]); + AReport.Add(' C Replications %5.0f%10.3f%10.3f%10.3f%10.3f', [DFC, SSC, MSC, FC, ProbC]); + AReport.Add(' AC Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFAC, SSAC, MSAC, FAC, ProbAC]); + AReport.Add(' BC Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFBC, SSBC, MSBC, FBC, ProbBC]); + AReport.Add(' ABC Effects %5.0f%10.3f%10.3f%10.3f%10.3f', [DFABC, SSABC, MSABC, FABC, ProbABC]); + AReport.Add(' Error Within %5.0f%10.3f%10.3f', [DFerrorWithin, SSerrorWithin, MSerrorWithin]); + AReport.Add(''); + AReport.Add('Total %5.0f%10.3f', [DFBetween + DFWithin, SSBetweenSubjects + SSWithinSubjects]); + AReport.Add(''); + + FReportFrame.DisplayReport(AReport); + AReport.Clear; end; + procedure TABRAnovaForm.MeansReport(AReport: TStrings); var ColHeader, LabelStr: string; Title: string; i, j, k, row: integer; begin + AReport.Clear; + row := 1; //OutputFrm.Clear; Title := 'ABR Means Table'; @@ -756,7 +805,8 @@ begin end; MatPrint(AMatrix,NoBGrps,NoSelected,Title,RowLabels,ColLabels,NinGrp*NoAGrps, AReport); -// OutputFrm.ShowModal; + FMeansReportFrame.DisplayReport(AReport); + AReport.Clear; end; procedure TABRAnovaForm.BoxTests(AReport: TStrings); @@ -766,7 +816,6 @@ var XVector: DblDyneVec = nil; XSums: DblDyneVec = nil; DetMat: DblDyneMat = nil; - MeanCovMat: DblDyneMat = nil; M1, M2, Sum1, C1, C2, f1, f2, chi, ProbChi, X, avgvar,avgcov : double; ColHeader, LabelStr : string; Title : string; @@ -774,10 +823,11 @@ var errorcode : boolean = false; // to silence the compiler Det: Double = 0.0; begin + AReport.Clear; + SetLength(XVector, NoSelected); SetLength(XSums, NoSelected); SetLength(DetMat, NoSelected+1, NoSelected+1); - SetLength(MeanCovMat, NoSelected+1, NoSelected+1); SetLength(PooledMat, NoSelected+1, NoSelected+1); for i := 0 to NoSelected-1 do @@ -936,32 +986,15 @@ begin ErrorMsg('Determinant of theoretical covariance AMatrix near zero.'); end; - // cleanup - PooledMat := nil; - MeanCovMat := nil; - DetMat := nil; - XSums := nil; - XVector := nil; + FBoxTestsReportFrame.DisplayReport(AReport); + AReport.Clear; end; -procedure TABRAnovaForm.PlotMeans(AInteraction: TInteraction); -const - X_TITLE: array[TInteraction] of string = ( - 'B Treatment Group', - 'C Treatment (within subjects) Group', - 'C Treatment (within subjects) Group' - ); - SERIES_TITLE: array[TInteraction] of string = ( - 'A%d', - 'A%d', - 'B%d' - ); +procedure TABRAnovaForm.PreparePlot; var idx: Integer; item: PChartDataItem; - ser: TChartSeries; - serSource: TListChartSource; i, j: Integer; begin FChartFrame.Clear; @@ -997,22 +1030,46 @@ begin item^.SetY(i, BCSums[i, j] / (NInGrp * NoAGrps)); end; + FBarSeries := FChartFrame.PlotXY(ptBars, nil, nil, nil, nil, '', clDefault) as TBarSeries; + with FBarSeries do + begin + Legend.Multiplicity := lmStyle; + Stacked := false; + Styles := ChartStyles; + {$IF LCL_FullVersion >= 2010000} + DepthBrightnessDelta := -30; + {$IFEND} + end; + +end; + + +procedure TABRAnovaForm.PlotMeans(AInteraction: TInteraction); +const + X_TITLE: array[TInteraction] of string = ( + 'B Treatment Group', + 'C Treatment (within subjects) Group', + 'C Treatment (within subjects) Group' + ); + SERIES_TITLE: array[TInteraction] of string = ( + 'A%d', + 'A%d', + 'B%d' + ); +var + serSource: TListChartSource; + i, j: Integer; +begin case AInteraction of AB: serSource := ListChartSource_AB; AC: serSource := ListChartSource_AC; BC: serSource := ListChartSource_BC; end; - ser := FChartFrame.PlotXY(ptBars, nil, nil, nil, nil, '', clDefault); - with TBarSeries(ser) do - begin - Source := serSource; - Legend.Multiplicity := lmStyle; - Stacked := false; - Styles := ChartStyles; - end; + FBarSeries.Source := serSource; - for i := 0 to ser.Source.YCount-1 do + ChartStyles.Styles.Clear; + for i := 0 to serSource.YCount-1 do begin with TChartStyle(ChartStyles.Styles.Add) do begin @@ -1022,7 +1079,7 @@ begin end; end; - FChartFrame.Chart.BottomAxis.Marks.Source := ser.Source; + FChartFrame.Chart.BottomAxis.Marks.Source := FBarSeries.Source; FChartFrame.Chart.BottomAxis.Marks.Style := smsXValue; FChartFrame.SetTitle('AxBxR ANOVA'); FChartFrame.SetXTitle(X_TITLE[AInteraction]); @@ -1040,6 +1097,7 @@ begin ListChartSource_AC.Clear; ListChartSource_BC.Clear; + BoxTestsPage.TabVisible := false; ChartPage.TabVisible := false; VarList.Items.Clear;