From 12255066ac4f85efade982c022e16c036ea98834 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Wed, 11 Nov 2020 11:47:07 +0000 Subject: [PATCH] LazStats: Inherit AxSAnovaUnit from BasicStatsReportAndChartFormUnit. Use TAChart. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7859 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- applications/lazstats/source/LazStats.lpi | 2 +- .../analysis/comparisons/axsanovaunit.lfm | 398 +++++++--------- .../analysis/comparisons/axsanovaunit.pas | 426 ++++++++++++------ .../lazstats/source/forms/mainunit.pas | 6 +- 4 files changed, 446 insertions(+), 386 deletions(-) diff --git a/applications/lazstats/source/LazStats.lpi b/applications/lazstats/source/LazStats.lpi index 402f8bf24..8f639a222 100644 --- a/applications/lazstats/source/LazStats.lpi +++ b/applications/lazstats/source/LazStats.lpi @@ -357,7 +357,7 @@ - + diff --git a/applications/lazstats/source/forms/analysis/comparisons/axsanovaunit.lfm b/applications/lazstats/source/forms/analysis/comparisons/axsanovaunit.lfm index 191e77a21..0053d6144 100644 --- a/applications/lazstats/source/forms/analysis/comparisons/axsanovaunit.lfm +++ b/applications/lazstats/source/forms/analysis/comparisons/axsanovaunit.lfm @@ -1,166 +1,36 @@ -object AxSAnovaFrm: TAxSAnovaFrm - Left = 629 - Height = 360 - Top = 278 - Width = 471 +inherited AxSAnovaForm: TAxSAnovaForm + Left = 636 + Height = 413 + Top = 186 + Width = 777 HelpType = htKeyword HelpKeyword = 'html/AbySAnalysisofVariance.htm' - AutoSize = True Caption = 'Treatments by Subjects ANOVA (AxS)' - ClientHeight = 360 - ClientWidth = 471 - OnActivate = FormActivate - OnCreate = FormCreate - OnShow = FormShow - Position = poMainFormCenter - LCLVersion = '2.0.10.0' - object GroupBox1: TGroupBox - AnchorSideLeft.Control = Owner - AnchorSideBottom.Control = Bevel1 - Left = 8 - Height = 51 - Top = 260 - Width = 282 - Anchors = [akLeft, akBottom] - AutoSize = True - BorderSpacing.Left = 8 - BorderSpacing.Top = 12 - Caption = 'Option' - ChildSizing.LeftRightSpacing = 12 - ChildSizing.TopBottomSpacing = 6 - ChildSizing.HorizontalSpacing = 16 - ChildSizing.VerticalSpacing = 2 - ChildSizing.Layout = cclLeftToRightThenTopToBottom - ChildSizing.ControlsPerLine = 2 - ClientHeight = 31 - ClientWidth = 278 + ClientHeight = 413 + ClientWidth = 777 + inherited ParamsPanel: TPanel + Height = 397 + ClientHeight = 397 TabOrder = 1 - object PlotChk: TCheckBox - Left = 12 - Height = 19 - Top = 6 - Width = 102 - Caption = 'Plot Cell Means' - TabOrder = 0 + inherited CloseBtn: TButton + Top = 372 end - object PosthocChk: TCheckBox - Left = 130 - Height = 19 - Top = 6 - Width = 136 - BorderSpacing.Left = 8 - Caption = 'Posthoc Comparisons' - TabOrder = 1 + inherited ComputeBtn: TButton + Top = 372 end - end - object ResetBtn: TButton - AnchorSideRight.Control = ComputeBtn - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 258 - Height = 25 - Top = 327 - Width = 54 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - BorderSpacing.Bottom = 8 - Caption = 'Reset' - OnClick = ResetBtnClick - TabOrder = 3 - end - object ComputeBtn: TButton - AnchorSideRight.Control = CloseBtn - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 320 - Height = 25 - Top = 327 - Width = 76 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - BorderSpacing.Bottom = 8 - Caption = 'Compute' - OnClick = ComputeBtnClick - TabOrder = 4 - end - object CloseBtn: TButton - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 404 - Height = 25 - Top = 327 - Width = 55 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - BorderSpacing.Right = 12 - BorderSpacing.Bottom = 8 - Caption = 'Close' - ModalResult = 11 - TabOrder = 5 - end - object HelpBtn: TButton - Tag = 106 - AnchorSideRight.Control = ResetBtn - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 199 - Height = 25 - Top = 327 - Width = 51 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 12 - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - BorderSpacing.Bottom = 8 - Caption = 'Help' - OnClick = HelpBtnClick - TabOrder = 2 - end - object Bevel1: TBevel - AnchorSideLeft.Control = Owner - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = CloseBtn - Left = 0 - Height = 8 - Top = 311 - Width = 471 - Anchors = [akLeft, akRight, akBottom] - Shape = bsBottomLine - end - object Panel1: TPanel - AnchorSideLeft.Control = Owner - AnchorSideTop.Control = Owner - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = GroupBox1 - Left = 8 - Height = 240 - Top = 8 - Width = 455 - Anchors = [akTop, akLeft, akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - BevelOuter = bvNone - ClientHeight = 240 - ClientWidth = 455 - TabOrder = 0 - object Label1: TLabel - AnchorSideLeft.Control = Panel1 - AnchorSideTop.Control = Panel1 + inherited ResetBtn: TButton + Top = 372 + end + inherited HelpBtn: TButton + Tag = 106 + Top = 372 + end + inherited ButtonBevel: TBevel + Top = 356 + end + object Label1: TLabel[5] + AnchorSideLeft.Control = ParamsPanel + AnchorSideTop.Control = ParamsPanel Left = 0 Height = 15 Top = 0 @@ -168,148 +38,208 @@ object AxSAnovaFrm: TAxSAnovaFrm Caption = 'Available Variables:' ParentColor = False end - object Label2: TLabel - AnchorSideLeft.Control = DepInBtn - AnchorSideLeft.Side = asrBottom - Left = 249 - Height = 15 - Top = 25 - Width = 77 - BorderSpacing.Left = 8 - Caption = 'Group Variable' - ParentColor = False - end - object Label3: TLabel - AnchorSideLeft.Control = DepInBtn - AnchorSideLeft.Side = asrBottom - AnchorSideTop.Control = RepInBtn - Left = 249 - Height = 15 - Top = 106 - Width = 102 - BorderSpacing.Left = 8 - BorderSpacing.Top = 5 - Caption = 'Repeated Measures' - ParentColor = False - end - object VarList: TListBox - AnchorSideLeft.Control = Panel1 + object VarList: TListBox[6] + AnchorSideLeft.Control = ParamsPanel AnchorSideTop.Control = Label1 AnchorSideTop.Side = asrBottom AnchorSideRight.Control = DepInBtn - AnchorSideBottom.Control = Panel1 - AnchorSideBottom.Side = asrBottom + AnchorSideBottom.Control = GroupBox1 Left = 0 - Height = 223 + Height = 280 Top = 17 - Width = 205 + Width = 126 Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Top = 2 - BorderSpacing.Right = 8 - Constraints.MinHeight = 220 + BorderSpacing.Right = 6 ItemHeight = 0 MultiSelect = True + OnDblClick = VarListDblClick OnSelectionChange = VarListSelectionChange - TabOrder = 0 + TabOrder = 4 end - object DepInBtn: TBitBtn - AnchorSideLeft.Control = Panel1 + object DepInBtn: TBitBtn[7] + AnchorSideLeft.Control = ParamsPanel AnchorSideLeft.Side = asrCenter AnchorSideTop.Control = VarList - Left = 213 - Height = 28 + Left = 132 + Height = 26 Top = 17 - Width = 28 + Width = 26 Images = MainDataModule.ImageList ImageIndex = 1 OnClick = DepInBtnClick Spacing = 0 - TabOrder = 1 + TabOrder = 5 end - object DepOutBtn: TBitBtn - AnchorSideLeft.Control = Panel1 + object DepOutBtn: TBitBtn[8] + AnchorSideLeft.Control = ParamsPanel AnchorSideLeft.Side = asrCenter AnchorSideTop.Control = DepInBtn AnchorSideTop.Side = asrBottom - Left = 213 - Height = 28 - Top = 49 - Width = 28 + Left = 132 + Height = 26 + Top = 47 + Width = 26 BorderSpacing.Top = 4 Images = MainDataModule.ImageList ImageIndex = 0 OnClick = DepOutBtnClick Spacing = 0 - TabOrder = 2 + TabOrder = 6 end - object RepInBtn: TBitBtn - AnchorSideLeft.Control = Panel1 + object RepInBtn: TBitBtn[9] + AnchorSideLeft.Control = ParamsPanel AnchorSideLeft.Side = asrCenter AnchorSideTop.Control = DepOutBtn AnchorSideTop.Side = asrBottom - Left = 213 - Height = 28 - Top = 101 - Width = 28 + Left = 132 + Height = 26 + Top = 97 + Width = 26 BorderSpacing.Top = 24 Images = MainDataModule.ImageList ImageIndex = 1 OnClick = RepInBtnClick Spacing = 0 - TabOrder = 4 + TabOrder = 7 end - object RepOutBtn: TBitBtn - AnchorSideLeft.Control = Panel1 + object RepOutBtn: TBitBtn[10] + AnchorSideLeft.Control = ParamsPanel AnchorSideLeft.Side = asrCenter AnchorSideTop.Control = RepInBtn AnchorSideTop.Side = asrBottom - Left = 213 - Height = 28 - Top = 133 - Width = 28 + Left = 132 + Height = 26 + Top = 127 + Width = 26 BorderSpacing.Top = 4 Images = MainDataModule.ImageList ImageIndex = 0 OnClick = RepOutBtnClick Spacing = 0 - TabOrder = 5 + TabOrder = 8 end - object GrpVar: TEdit + object GroupBox1: TGroupBox[11] + AnchorSideLeft.Control = ParamsPanel + AnchorSideBottom.Control = ButtonBevel + Left = 0 + Height = 51 + Top = 305 + Width = 282 + Anchors = [akLeft, akBottom] + AutoSize = True + BorderSpacing.Top = 8 + Caption = 'Option' + ChildSizing.LeftRightSpacing = 12 + ChildSizing.TopBottomSpacing = 6 + ChildSizing.HorizontalSpacing = 16 + ChildSizing.VerticalSpacing = 2 + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 2 + ClientHeight = 31 + ClientWidth = 278 + TabOrder = 9 + object PlotChk: TCheckBox + Left = 12 + Height = 19 + Top = 6 + Width = 102 + Caption = 'Plot Cell Means' + TabOrder = 0 + end + object PosthocChk: TCheckBox + Left = 130 + Height = 19 + Top = 6 + Width = 136 + BorderSpacing.Left = 8 + Caption = 'Posthoc Comparisons' + TabOrder = 1 + end + end + object Label2: TLabel[12] + AnchorSideLeft.Control = GrpVar + AnchorSideTop.Control = DepInBtn + Left = 164 + Height = 15 + Top = 17 + Width = 77 + Caption = 'Group Variable' + ParentColor = False + end + object Label3: TLabel[13] + AnchorSideLeft.Control = RepList + AnchorSideTop.Control = RepInBtn + Left = 164 + Height = 15 + Top = 97 + Width = 102 + Caption = 'Repeated Measures' + ParentColor = False + end + object GrpVar: TEdit[14] AnchorSideLeft.Control = DepInBtn AnchorSideLeft.Side = asrBottom - AnchorSideRight.Control = Panel1 + AnchorSideTop.Control = Label2 + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = ParamsPanel AnchorSideRight.Side = asrBottom - Left = 249 + Left = 164 Height = 23 - Top = 40 - Width = 206 + Top = 32 + Width = 127 Anchors = [akTop, akLeft, akRight] - BorderSpacing.Left = 8 + BorderSpacing.Left = 6 OnChange = GrpVarChange ReadOnly = True - TabOrder = 3 + TabOrder = 10 Text = 'GrpVar' end - object RepList: TListBox - AnchorSideLeft.Control = DepInBtn + object RepList: TListBox[15] + AnchorSideLeft.Control = RepInBtn AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = Label3 AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = Panel1 + AnchorSideRight.Control = ParamsPanel AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = Panel1 AnchorSideBottom.Side = asrBottom - Left = 249 - Height = 117 - Top = 123 - Width = 206 + Left = 164 + Height = 179 + Top = 114 + Width = 127 Anchors = [akTop, akLeft, akRight, akBottom] - BorderSpacing.Left = 8 + BorderSpacing.Left = 6 BorderSpacing.Top = 2 ItemHeight = 0 MultiSelect = True + OnDblClick = RepListDblClick OnSelectionChange = VarListSelectionChange - TabOrder = 6 + TabOrder = 11 end end + inherited ParamsSplitter: TSplitter + Height = 413 + end + inherited PageControl: TPageControl + Height = 397 + Width = 457 + ActivePage = PosthocPage + TabOrder = 0 + inherited ReportPage: TTabSheet + Caption = 'ANOVA Results' + end + object PosthocPage: TTabSheet[1] + Caption = 'Post-Hoc' + TabVisible = False + end + inherited ChartPage: TTabSheet[2] + Caption = 'Plots' + TabVisible = False + end + end + object ChartStyles: TChartStyles[3] + Styles = <> + Left = 450 + Top = 148 + end end diff --git a/applications/lazstats/source/forms/analysis/comparisons/axsanovaunit.pas b/applications/lazstats/source/forms/analysis/comparisons/axsanovaunit.pas index d4d1f087b..de7a55eb8 100644 --- a/applications/lazstats/source/forms/analysis/comparisons/axsanovaunit.pas +++ b/applications/lazstats/source/forms/analysis/comparisons/axsanovaunit.pas @@ -7,27 +7,22 @@ unit AxSANOVAUnit; interface uses - Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, - StdCtrls, Buttons, ExtCtrls, + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, + StdCtrls, Buttons, ExtCtrls, ComCtrls, TAStyles, MainUnit, FunctionsLib, GraphLib, Globals, - DataProcs, ContextHelpUnit; + DataProcs, ReportFrameUnit, BasicStatsReportAndChartFormUnit; type - { TAxSAnovaFrm } + { TAxSAnovaForm } - TAxSAnovaFrm = class(TForm) - Bevel1: TBevel; - Panel1: TPanel; + TAxSAnovaForm = class(TBasicStatsReportAndChartForm) + ChartStyles: TChartStyles; PosthocChk: TCheckBox; DepInBtn: TBitBtn; DepOutBtn: TBitBtn; - HelpBtn: TButton; RepInBtn: TBitBtn; RepOutBtn: TBitBtn; - ResetBtn: TButton; - ComputeBtn: TButton; - CloseBtn: TButton; PlotChk: TCheckBox; GrpVar: TEdit; GroupBox1: TGroupBox; @@ -35,26 +30,28 @@ type Label2: TLabel; Label3: TLabel; RepList: TListBox; + PosthocPage: TTabSheet; VarList: TListBox; - procedure ComputeBtnClick(Sender: TObject); procedure DepInBtnClick(Sender: TObject); procedure DepOutBtnClick(Sender: TObject); - procedure FormActivate(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure FormShow(Sender: TObject); procedure GrpVarChange(Sender: TObject); - procedure HelpBtnClick(Sender: TObject); procedure RepInBtnClick(Sender: TObject); + procedure RepListDblClick(Sender: TObject); procedure RepOutBtnClick(Sender: TObject); - procedure ResetBtnClick(Sender: TObject); + procedure VarListDblClick(Sender: TObject); procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean); private - { private declarations } - FAutoSized: Boolean; + FPosthocReportFrame: TReportFrame; + + procedure Plot(AData: DblDyneMat; ANumRows, ANumCols: Integer); procedure PostHocTests(NoSelected: integer; MSerr: double; dferr: integer; Count: integer; ColMeans: DblDyneVec; AReport: TStrings); - procedure UpdateBtnStates; + + protected + procedure AdjustConstraints; override; + procedure Compute; override; + procedure UpdateBtnStates; override; // wp: replace the following methods by those in ANOVATestUnit? procedure Tukey( @@ -107,130 +104,57 @@ type AReport : TStrings); public - { public declarations } + constructor Create(AOwner: TComponent); override; + procedure Reset; override; + end; var - AxSAnovaFrm: TAxSAnovaFrm; + AxSAnovaForm: TAxSAnovaForm; + implementation +{$R *.lfm} + uses Math, - MathUnit, OutputUnit; + TAChartUtils, TACustomSource, TACustomSeries, TASeries, + Utils, MathUnit, ChartFrameUnit; -{ TAxSAnovaFrm } -procedure TAxSAnovaFrm.ResetBtnClick(Sender: TObject); -var - i: integer; +{ TAxSAnovaForm } + +constructor TAxSAnovaForm.Create(AOwner: TComponent); begin - VarList.Items.Clear; - RepList.Items.Clear; - GrpVar.Text := ''; - for i := 1 to NoVariables do - VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); - PlotChk.Checked := false; - UpdateBtnStates; -end; + inherited; -procedure TAxSAnovaFrm.FormActivate(Sender: TObject); -var - w: Integer; -begin - if FAutoSized then - exit; + FPosthocReportFrame := TReportFrame.Create(PostHocPage); + FPosthocReportFrame.Parent := PostHocPage; + FPosthocReportFrame.Align := alClient; + InitToolbar(FPosthocReportFrame.ReportToolbar, tpTop); + PostHocPage.PageIndex := 1; - w := MaxValue([HelpBtn.Width, ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]); - HelpBtn.Constraints.MinWidth := w; - ResetBtn.Constraints.MinWidth := w; - ComputeBtn.Constraints.MinWidth := w; - CloseBtn.Constraints.MinWidth := w; - - Constraints.MinHeight := Height; - Constraints.MinWidth := Width; - - FAutoSized := true; -end; - -procedure TAxSAnovaFrm.FormCreate(Sender: TObject); -begin - Assert(OS3MainFrm <> nil); if GraphFrm = nil then Application.CreateForm(TGraphFrm, GraphFrm); end; -procedure TAxSAnovaFrm.FormShow(Sender: TObject); + +procedure TAxSAnovaForm.AdjustConstraints; begin - ResetBtnClick(self); + inherited; + + ParamsPanel.Constraints.MinWidth := Max( + 4*CloseBtn.Width + 3*CloseBtn.BorderSpacing.Left, + GroupBox1.Width + ); + ParamsPanel.Constraints.MinHeight := RepOutBtn.Top + RepOutBtn.Height + + GroupBox1.BorderSpacing.Top + GroupBox1.Height + + ButtonBevel.Height + CloseBtn.BorderSpacing.Top + CloseBtn.Height; end; -procedure TAxSAnovaFrm.GrpVarChange(Sender: TObject); -begin - UpdateBtnStates; -end; -procedure TAxSAnovaFrm.HelpBtnClick(Sender: TObject); -begin - if ContextHelpForm = nil then - Application.CreateForm(TContextHelpForm, ContextHelpForm); - ContextHelpForm.HelpMessage((Sender as TButton).tag); -end; - -procedure TAxSAnovaFrm.RepInBtnClick(Sender: TObject); -var - i: integer; -begin - i := 0; - while i < VarList.Items.Count do - begin - if (VarList.Selected[i]) then - begin - RepList.Items.Add(VarList.Items[i]); - VarList.Items.Delete(i); - i := 0; - end else - inc(i); - end; - VarList.ItemIndex := -1; - UpdateBtnStates; -end; - -procedure TAxSAnovaFrm.RepOutBtnClick(Sender: TObject); -var - i: integer; -begin - i := 0; - while i < RepList.Items.Count do - begin - if RepList.Selected[i] then - begin - VarList.Items.Add(RepList.Items[i]); - RepList.Items.Delete(i); - i := 0; - end else - inc(i); - end; - VarList.ItemIndex := -1; - RepList.ItemIndex := -1; - UpdateBtnStates; -end; - -procedure TAxSAnovaFrm.DepInBtnClick(Sender: TObject); -var - index: integer; -begin - index := VarList.ItemIndex; - if (index > -1) and (GrpVar.Text = '') then - begin - GrpVar.Text := VarList.Items[index]; - VarList.Items.Delete(index); - end; - VarList.ItemIndex := -1; - UpdateBtnStates; -end; - -procedure TAxSAnovaFrm.ComputeBtnClick(Sender: TObject); +procedure TAxSAnovaForm.Compute; var a1, a2, agrp, i, j, k, v1, totaln, NoSelected, range: integer; group, col: integer; @@ -558,9 +482,11 @@ begin value := Format('%7.3f', [TotStdDev]); outline := outline + value; lReport.Add(outline); + FReportFrame.DisplayReport(lReport); if PosthocChk.Checked then begin + lReport.Clear; // Do tests for the A (between groups) lReport.Add(''); lReport.Add('==============================================================='); @@ -575,16 +501,22 @@ begin lReport.Add(''); lReport.Add('COMPARISONS FOR THE REPEATED-MEASURES MEANS'); PostHocTests(k, ms[4], degfree[4], NoCases, coltot, lReport); - end; - DisplayReport(lReport); + FPostHocReportFrame.DisplayReport(lReport); + PostHocPage.TabVisible := true; + end else + PostHocPage.TabVisible := false; finally lReport.Free; end; + Plot(C, range, k); + + (* if PlotChk.Checked then // PlotMeans(C,range,k,this) begin + ChartPage.TabVisible := true; maxmean := 0.0; SetLength(GraphFrm.Ypoints,range,k); SetLength(GraphFrm.Xpoints,1,k); @@ -620,22 +552,115 @@ begin GraphFrm.FloorColor := clLtGray; GraphFrm.ShowBackWall := true; GraphFrm.ShowModal; - end; + end else + ChartPage.TabVisible := false; + *) - // Clean up - GraphFrm.Xpoints := nil; - GraphFrm.Ypoints := nil; - StdDev := nil; - sumsum := nil; - sumxsquared := nil; - coltot := nil; - squaredsumx := nil; - N := nil; - C := nil; - ColNoSelected := nil; end; -procedure TAxSAnovaFrm.DepOutBtnClick(Sender: TObject); + +procedure TAxSAnovaForm.Plot(AData: DblDyneMat; ANumRows, ANumCols: Integer); +var + ser: TChartSeries; + i, j, idx: Integer; + item: PChartDataItem; +begin + if not PlotChk.Checked then + begin + ChartPage.TabVisible := false; + exit; + end; + + FChartFrame.Clear; + FChartFrame.SetTitle('Treatments x Subject Replications ANOVA'); + FChartFrame.SetXTitle('Within (B) Treatment Group'); + FChartFrame.SetYTitle('Mean'); + + ser := FChartFrame.PlotXY(ptBars, nil, nil, nil, nil, '', DATA_COLORS[0]); + ser.ListSource.YCount := ANumRows; + for j := 0 to ANumCols-1 do + begin + idx := ser.AddXY(j+1, NaN); + item := ser.Source.Item[idx]; + for i := 0 to ANumRows-1 do + item^.SetY(i, AData[i, j]); + end; + + with (ser as TBarSeries) do + begin + Stacked := false; + Styles := ChartStyles; + end; + + for i := 0 to ANumRows-1 do + begin + with TChartStyle(ChartStyles.Styles.Add) do + begin + Brush.Color := DATA_COLORS[i mod Length(DATA_COLORS)]; + UseBrush := true; + Text := 'A' + IntToStr(i+1); + end; + end; + + FChartFrame.Chart.BottomAxis.Marks.Source := ser.Source; + FChartFrame.Chart.BottomAxis.Marks.Style := smsXValue; + FChartFrame.Chart.Legend.Visible := false; + ChartPage.TabVisible := true; + (* + maxmean := 0.0; + SetLength(GraphFrm.Ypoints,range,k); + SetLength(GraphFrm.Xpoints,1,k); + for i := 1 to range do + begin + GraphFrm.SetLabels[i] := 'A ' + IntToStr(i); + for j := 1 to k do + begin + GraphFrm.Ypoints[i-1,j-1] := C[i-1,j-1]; + if C[i-1,j-1] > maxmean then + maxmean := C[i-1,j-1]; + end; + end; + + for j := 1 to k do + begin + coltot[j-1] := j; + GraphFrm.Xpoints[0,j-1] := j; + end; + + GraphFrm.nosets := range; + GraphFrm.nbars := k; + GraphFrm.Heading := 'TREATMENTS X SUBJECT REPLICATIONS ANOVA'; + GraphFrm.XTitle := 'WITHIN (B) TREATMENT GROUP'; + GraphFrm.YTitle := 'Mean'; + GraphFrm.barwideprop := 0.5; + GraphFrm.AutoScaled := false; + GraphFrm.GraphType := 2; // 3d Vertical Bar Chart + GraphFrm.miny := 0.0; + GraphFrm.maxy := maxmean; + GraphFrm.BackColor := clCream; + GraphFrm.WallColor := clDkGray; + GraphFrm.FloorColor := clLtGray; + GraphFrm.ShowBackWall := true; + GraphFrm.ShowModal; + *) +end; + +procedure TAxSAnovaForm.DepInBtnClick(Sender: TObject); +var + index: integer; +begin + index := VarList.ItemIndex; + if (index > -1) and (GrpVar.Text = '') then + begin + GrpVar.Text := VarList.Items[index]; + VarList.Items.Delete(index); + end; + VarList.ItemIndex := -1; + UpdateBtnStates; +end; + + +procedure TAxSAnovaForm.DepOutBtnClick(Sender: TObject); begin if GrpVar.Text <> '' then begin @@ -645,7 +670,14 @@ begin UpdateBtnStates; end; -procedure TAxSAnovaFrm.PostHocTests(NoSelected: Integer; MSerr: double; + +procedure TAxSAnovaForm.GrpVarChange(Sender: TObject); +begin + UpdateBtnStates; +end; + + +procedure TAxSAnovaForm.PostHocTests(NoSelected: Integer; MSerr: double; dferr: integer; Count: integer; ColMeans: DblDyneVec; AReport: TStrings); var group_total: DblDyneVec = nil; @@ -668,7 +700,8 @@ begin Newman_Keuls(MSerr, dferr, Count, group_total, group_count, mingrp, NoSelected, AReport); end; -procedure TAxSAnovaFrm.Tukey( + +procedure TAxSAnovaForm.Tukey( error_ms : double; { mean squared for residual } error_df : double; { deg. freedom for residual } value : double; { size of smallest group } @@ -720,7 +753,7 @@ begin AReport.Add('---------------------------------------------------------------'); end; -procedure TAxSAnovaFrm.ScheffeTest( +procedure TAxSAnovaForm.ScheffeTest( error_ms : double; { mean squared residual } group_total : DblDyneVec; { sum of scores in a group } group_count : DblDyneVec; { count of cases in a group } @@ -772,7 +805,7 @@ begin AReport.Add('----------------------------------------------------------------'); end; -procedure TAxSAnovaFrm.Newman_Keuls( +procedure TAxSAnovaForm.Newman_Keuls( error_ms : double; { residual mean squared } error_df : double; { deg. freedom for error } value : double; { number in smallest group } @@ -859,7 +892,7 @@ begin groupno := nil; end; -procedure TAxSAnovaFrm.Tukey_Kramer( +procedure TAxSAnovaForm.Tukey_Kramer( error_ms : double; { residual mean squared } error_df : double; { deg. freedom for error } value : double; { number in smallest group } @@ -912,7 +945,7 @@ begin AReport.Add('---------------------------------------------------------------'); end; -procedure TAxSAnovaFrm.TukeyBTest( +procedure TAxSAnovaForm.TukeyBTest( ErrorMS : double; // within groups error ErrorDF : double; // degrees of freedom within group_total : DblDyneVec; // vector of group sums @@ -998,11 +1031,90 @@ begin groupno := nil; end; -procedure TAxSAnovaFrm.UpdateBtnStates; + +procedure TAxSAnovaForm.RepInBtnClick(Sender: TObject); +var + i: integer; +begin + i := 0; + while i < VarList.Items.Count do + begin + if (VarList.Selected[i]) then + begin + RepList.Items.Add(VarList.Items[i]); + VarList.Items.Delete(i); + i := 0; + end else + inc(i); + end; + VarList.ItemIndex := -1; + UpdateBtnStates; +end; + + +procedure TAxSAnovaForm.RepListDblClick(Sender: TObject); +var + index: Integer; +begin + index := RepList.ItemIndex; + if index > -1 then + begin + VarList.Items.Add(RepList.Items[index]); + RepList.Items.Delete(index); + UpdateBtnStates; + end; +end; + + +procedure TAxSAnovaForm.RepOutBtnClick(Sender: TObject); +var + i: integer; +begin + i := 0; + while i < RepList.Items.Count do + begin + if RepList.Selected[i] then + begin + VarList.Items.Add(RepList.Items[i]); + RepList.Items.Delete(i); + i := 0; + end else + inc(i); + end; + VarList.ItemIndex := -1; + RepList.ItemIndex := -1; + UpdateBtnStates; +end; + +procedure TAxSAnovaForm.Reset; +var + i: integer; +begin + inherited; + + if FPosthocReportFrame <> nil then + FPosthocReportFrame.Clear; + + VarList.Items.Clear; + for i := 1 to NoVariables do + VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); + RepList.Items.Clear; + GrpVar.Clear; + + UpdateBtnStates; +end; + + +procedure TAxSAnovaForm.UpdateBtnStates; var lSelected: Boolean; i: Integer; begin + inherited; + + if FPosthocReportFrame <> nil then + FPosthocReportFrame.UpdateBtnStates; + DepInBtn.Enabled := (VarList.ItemIndex > -1) and (GrpVar.Text = ''); DepOutBtn.Enabled := (GrpVar.Text <> ''); @@ -1025,13 +1137,31 @@ begin RepOutBtn.Enabled := lSelected; end; -procedure TAxSAnovaFrm.VarListSelectionChange(Sender: TObject; User: boolean); + +procedure TAxSAnovaForm.VarListDblClick(Sender: TObject); +var + index: Integer; + s: String; +begin + index := VarList.ItemIndex; + if index > -1 then + begin + s := VarList.Items[index]; + if GrpVar.Text = '' then + GrpVar.Text := s + else + RepList.Items.Add(s); + VarList.Items.Delete(index); + UpdateBtnStates; + end; +end; + + +procedure TAxSAnovaForm.VarListSelectionChange(Sender: TObject; User: boolean); begin UpdateBtnStates; end; -initialization - {$I axsanovaunit.lrs} end. diff --git a/applications/lazstats/source/forms/mainunit.pas b/applications/lazstats/source/forms/mainunit.pas index 9ec445158..77c7ad63b 100644 --- a/applications/lazstats/source/forms/mainunit.pas +++ b/applications/lazstats/source/forms/mainunit.pas @@ -1854,9 +1854,9 @@ end; // Menu "Analysis" > "Comparisons" > "A x S Anova" procedure TOS3MainFrm.mnuAnalysisComp_AxSAnovaClick(Sender: TObject); begin - if AxSAnovaFrm = nil then - Application.CreateForm(TAxSAnovaFrm, AxSAnovaFrm); - AxSAnovaFrm.ShowModal; + if AxSAnovaForm = nil then + Application.CreateForm(TAxSAnovaForm, AxSAnovaForm); + AxSAnovaForm.Show; end; // Menu "Analysis" > "Comparisons" > "B Nested in A Anova"