LazStats: Improved pagecontrol usability in ABRAnovaUnit. 3D bar chart.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7798 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-10-24 22:07:31 +00:00
parent 8bdda9097d
commit 57aa148c56
2 changed files with 148 additions and 69 deletions

View File

@ -17,8 +17,8 @@ inherited ABRAnovaForm: TABRAnovaForm
AnchorSideLeft.Control = ParamsPanel AnchorSideLeft.Control = ParamsPanel
AnchorSideBottom.Control = ButtonBevel AnchorSideBottom.Control = ButtonBevel
Left = 0 Left = 0
Height = 51 Height = 72
Top = 244 Top = 223
Width = 324 Width = 324
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
AutoSize = True AutoSize = True
@ -29,7 +29,7 @@ inherited ABRAnovaForm: TABRAnovaForm
ChildSizing.HorizontalSpacing = 24 ChildSizing.HorizontalSpacing = 24
ChildSizing.VerticalSpacing = 2 ChildSizing.VerticalSpacing = 2
ChildSizing.ControlsPerLine = 2 ChildSizing.ControlsPerLine = 2
ClientHeight = 31 ClientHeight = 52
ClientWidth = 320 ClientWidth = 320
TabOrder = 10 TabOrder = 10
object PlotChk: TCheckBox object PlotChk: TCheckBox
@ -42,6 +42,7 @@ inherited ABRAnovaForm: TABRAnovaForm
Top = 6 Top = 6
Width = 79 Width = 79
Caption = 'Plot Means' Caption = 'Plot Means'
OnChange = PlotChkChange
TabOrder = 1 TabOrder = 1
end end
object TestChk: TCheckBox object TestChk: TCheckBox
@ -54,6 +55,20 @@ inherited ABRAnovaForm: TABRAnovaForm
Caption = 'Test Homogeneity of Covariance' Caption = 'Test Homogeneity of Covariance'
TabOrder = 0 TabOrder = 0
end 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 end
inherited CloseBtn: TButton[1] inherited CloseBtn: TButton[1]
Left = 274 Left = 274
@ -136,7 +151,7 @@ inherited ABRAnovaForm: TABRAnovaForm
AnchorSideRight.Control = AInBtn AnchorSideRight.Control = AInBtn
AnchorSideBottom.Control = OptionsGroup AnchorSideBottom.Control = OptionsGroup
Left = 0 Left = 0
Height = 219 Height = 198
Top = 17 Top = 17
Width = 145 Width = 145
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
@ -290,7 +305,7 @@ inherited ABRAnovaForm: TABRAnovaForm
AnchorSideBottom.Control = VarList AnchorSideBottom.Control = VarList
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 183 Left = 183
Height = 42 Height = 21
Top = 194 Top = 194
Width = 146 Width = 146
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
@ -314,9 +329,15 @@ inherited ABRAnovaForm: TABRAnovaForm
ActivePage = ReportPage ActivePage = ReportPage
TabIndex = 0 TabIndex = 0
inherited ReportPage: TTabSheet inherited ReportPage: TTabSheet
Caption = 'ANOVA Results' Caption = 'ANOVA Summary'
end 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' Caption = 'Charts'
end end
end end

View File

@ -7,9 +7,11 @@ unit ABRANOVAUnit;
interface interface
uses uses
Classes, SysUtils, FileUtil, TASources, TAStyles, Forms, Classes, SysUtils, Forms, Controls, Graphics, Dialogs, LCLVersion,
Controls, Graphics, Dialogs, StdCtrls, Buttons, ExtCtrls, ComCtrls, MainUnit, StdCtrls, Buttons, ExtCtrls, ComCtrls,
FunctionsLib, Globals, DataProcs, MatrixLib, BasicStatsReportAndChartFormUnit; TASources, TAStyles, TASeries,
MainUnit, FunctionsLib, Globals, DataProcs, MatrixLib,
ReportFrameUnit, BasicStatsReportAndChartFormUnit;
type type
@ -21,6 +23,7 @@ type
BInBtn: TBitBtn; BInBtn: TBitBtn;
BOutBtn: TBitBtn; BOutBtn: TBitBtn;
ChartStyles: TChartStyles; ChartStyles: TChartStyles;
ThreeDChk: TCheckBox;
CInBtn: TBitBtn; CInBtn: TBitBtn;
COutBtn: TBitBtn; COutBtn: TBitBtn;
ACodesEdit: TEdit; ACodesEdit: TEdit;
@ -28,6 +31,8 @@ type
ListChartSource_AB: TListChartSource; ListChartSource_AB: TListChartSource;
ListChartSource_AC: TListChartSource; ListChartSource_AC: TListChartSource;
ListChartSource_BC: TListChartSource; ListChartSource_BC: TListChartSource;
MeansPage: TTabSheet;
BoxTestsPage: TTabSheet;
TestChk: TCheckBox; TestChk: TCheckBox;
PlotChk: TCheckBox; PlotChk: TCheckBox;
OptionsGroup: TGroupBox; OptionsGroup: TGroupBox;
@ -46,6 +51,8 @@ type
procedure CListDblClick(Sender: TObject); procedure CListDblClick(Sender: TObject);
procedure CListSelectionChange(Sender: TObject; {%H-}User: boolean); procedure CListSelectionChange(Sender: TObject; {%H-}User: boolean);
procedure COutBtnClick(Sender: TObject); procedure COutBtnClick(Sender: TObject);
procedure PlotChkChange(Sender: TObject);
procedure ThreeDChkChange(Sender: TObject);
procedure VarListDblClick(Sender: TObject); procedure VarListDblClick(Sender: TObject);
private private
type TInteraction = (AB, AC, BC); type TInteraction = (AB, AC, BC);
@ -70,7 +77,10 @@ type
RowLabels, ColLabels : StrDyneVec; RowLabels, ColLabels : StrDyneVec;
selected : integer; selected : integer;
FMeansReportFrame: TReportFrame;
FBoxTestsReportFrame: TReportFrame;
FBtnAB, FBtnAC, FBtnBC: TToolButton; FBtnAB, FBtnAC, FBtnBC: TToolButton;
FBarSeries: TBarSeries;
procedure InteractionChanged(Sender: TObject); procedure InteractionChanged(Sender: TObject);
function InitData: Boolean; function InitData: Boolean;
@ -79,6 +89,7 @@ type
procedure Summarize(AReport: TStrings); procedure Summarize(AReport: TStrings);
procedure MeansReport(AReport: TStrings); procedure MeansReport(AReport: TStrings);
procedure BoxTests(AReport: TStrings); procedure BoxTests(AReport: TStrings);
procedure PreparePlot;
procedure PlotMeans(AInteraction: TInteraction); procedure PlotMeans(AInteraction: TInteraction);
procedure CleanUp; procedure CleanUp;
@ -103,7 +114,7 @@ implementation
uses uses
Math, Math,
TAChartUtils, TALegend, TACustomSource, TACustomSeries, TASeries, TAChartUtils, TALegend, TACustomSource, TACustomSeries,
Utils, MathUnit, GridProcs, ChartFrameUnit; Utils, MathUnit, GridProcs, ChartFrameUnit;
{ TABRAnovaForm } { TABRAnovaForm }
@ -114,6 +125,24 @@ var
begin begin
inherited; 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.Margins.Bottom := 0;
FChartFrame.Chart.BottomAxis.AxisPen.Visible := true; FChartFrame.Chart.BottomAxis.AxisPen.Visible := true;
FChartFrame.Chart.BottomAxis.ZPosition := 1; FChartFrame.Chart.BottomAxis.ZPosition := 1;
@ -122,7 +151,6 @@ begin
FChartFrame.ChartToolbar.ShowCaptions := true; FChartFrame.ChartToolbar.ShowCaptions := true;
FChartFrame.ChartToolbar.ButtonHeight := 40;; FChartFrame.ChartToolbar.ButtonHeight := 40;;
btn := TToolButton.Create(FChartFrame.ChartToolbar); btn := TToolButton.Create(FChartFrame.ChartToolbar);
btn.Style := tbsDivider; btn.Style := tbsDivider;
AddButtonToToolbar(btn, FChartFrame.ChartToolbar); AddButtonToToolbar(btn, FChartFrame.ChartToolbar);
@ -252,11 +280,11 @@ begin
Acnt := nil; Acnt := nil;
SumPSqr := nil; SumPSqr := nil;
AMatrix := nil; AMatrix := nil;
{ //{
BCSums := nil; // needed for plotting BCSums := nil; // needed for plotting
ACSums := nil; ACSums := nil;
ABSums := nil; ABSums := nil;
} //}
CSums := nil; CSums := nil;
BSums := nil; BSums := nil;
ASums := nil; ASums := nil;
@ -297,19 +325,22 @@ begin
Calculate; Calculate;
Summarize(lReport); Summarize(lReport);
MeansReport(lReport); MeansReport(lReport);
if TestChk.Checked then if TestChk.Checked then
BoxTests(lReport); BoxTests(lReport);
BoxTestsPage.TabVisible := TestChk.Checked;
FReportFrame.DisplayReport(lReport); BoxTestsPage.PageIndex := PageControl.PageCount-2;
if PlotChk.Checked then if PlotChk.Checked then
begin begin
PreparePlot;
if FBtnAB.Down then interaction := AB else if FBtnAB.Down then interaction := AB else
if FBtnAC.Down then interaction := AC else if FBtnAC.Down then interaction := AC else
if FBtnBC.Down then interaction := BC; if FBtnBC.Down then interaction := BC;
PlotMeans(interaction); PlotMeans(interaction);
end; end;
ChartPage.TabVisible := PlotChk.Checked; ChartPage.TabVisible := PlotChk.Checked;
ChartPage.PageIndex := PageControl.PageCount-1;
end; end;
finally finally
lReport.Free; lReport.Free;
@ -337,6 +368,19 @@ begin
UpdateBtnStates; UpdateBtnStates;
end; 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; function TABRAnovaForm.InitData: Boolean;
var var
@ -679,15 +723,20 @@ begin
AReport.Add(''); AReport.Add('');
AReport.Add('Total %5.0f%10.3f', [DFBetween + DFWithin, SSBetweenSubjects + SSWithinSubjects]); AReport.Add('Total %5.0f%10.3f', [DFBetween + DFWithin, SSBetweenSubjects + SSWithinSubjects]);
AReport.Add(''); AReport.Add('');
// OutputFrm.ShowModal;
FReportFrame.DisplayReport(AReport);
AReport.Clear;
end; end;
procedure TABRAnovaForm.MeansReport(AReport: TStrings); procedure TABRAnovaForm.MeansReport(AReport: TStrings);
var var
ColHeader, LabelStr: string; ColHeader, LabelStr: string;
Title: string; Title: string;
i, j, k, row: integer; i, j, k, row: integer;
begin begin
AReport.Clear;
row := 1; row := 1;
//OutputFrm.Clear; //OutputFrm.Clear;
Title := 'ABR Means Table'; Title := 'ABR Means Table';
@ -756,7 +805,8 @@ begin
end; end;
MatPrint(AMatrix,NoBGrps,NoSelected,Title,RowLabels,ColLabels,NinGrp*NoAGrps, AReport); MatPrint(AMatrix,NoBGrps,NoSelected,Title,RowLabels,ColLabels,NinGrp*NoAGrps, AReport);
// OutputFrm.ShowModal; FMeansReportFrame.DisplayReport(AReport);
AReport.Clear;
end; end;
procedure TABRAnovaForm.BoxTests(AReport: TStrings); procedure TABRAnovaForm.BoxTests(AReport: TStrings);
@ -766,7 +816,6 @@ var
XVector: DblDyneVec = nil; XVector: DblDyneVec = nil;
XSums: DblDyneVec = nil; XSums: DblDyneVec = nil;
DetMat: DblDyneMat = nil; DetMat: DblDyneMat = nil;
MeanCovMat: DblDyneMat = nil;
M1, M2, Sum1, C1, C2, f1, f2, chi, ProbChi, X, avgvar,avgcov : double; M1, M2, Sum1, C1, C2, f1, f2, chi, ProbChi, X, avgvar,avgcov : double;
ColHeader, LabelStr : string; ColHeader, LabelStr : string;
Title : string; Title : string;
@ -774,10 +823,11 @@ var
errorcode : boolean = false; // to silence the compiler errorcode : boolean = false; // to silence the compiler
Det: Double = 0.0; Det: Double = 0.0;
begin begin
AReport.Clear;
SetLength(XVector, NoSelected); SetLength(XVector, NoSelected);
SetLength(XSums, NoSelected); SetLength(XSums, NoSelected);
SetLength(DetMat, NoSelected+1, NoSelected+1); SetLength(DetMat, NoSelected+1, NoSelected+1);
SetLength(MeanCovMat, NoSelected+1, NoSelected+1);
SetLength(PooledMat, NoSelected+1, NoSelected+1); SetLength(PooledMat, NoSelected+1, NoSelected+1);
for i := 0 to NoSelected-1 do for i := 0 to NoSelected-1 do
@ -936,32 +986,15 @@ begin
ErrorMsg('Determinant of theoretical covariance AMatrix near zero.'); ErrorMsg('Determinant of theoretical covariance AMatrix near zero.');
end; end;
// cleanup FBoxTestsReportFrame.DisplayReport(AReport);
PooledMat := nil; AReport.Clear;
MeanCovMat := nil;
DetMat := nil;
XSums := nil;
XVector := nil;
end; end;
procedure TABRAnovaForm.PlotMeans(AInteraction: TInteraction); procedure TABRAnovaForm.PreparePlot;
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 var
idx: Integer; idx: Integer;
item: PChartDataItem; item: PChartDataItem;
ser: TChartSeries;
serSource: TListChartSource;
i, j: Integer; i, j: Integer;
begin begin
FChartFrame.Clear; FChartFrame.Clear;
@ -997,22 +1030,46 @@ begin
item^.SetY(i, BCSums[i, j] / (NInGrp * NoAGrps)); item^.SetY(i, BCSums[i, j] / (NInGrp * NoAGrps));
end; 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 case AInteraction of
AB: serSource := ListChartSource_AB; AB: serSource := ListChartSource_AB;
AC: serSource := ListChartSource_AC; AC: serSource := ListChartSource_AC;
BC: serSource := ListChartSource_BC; BC: serSource := ListChartSource_BC;
end; end;
ser := FChartFrame.PlotXY(ptBars, nil, nil, nil, nil, '', clDefault); FBarSeries.Source := serSource;
with TBarSeries(ser) do
begin
Source := serSource;
Legend.Multiplicity := lmStyle;
Stacked := false;
Styles := ChartStyles;
end;
for i := 0 to ser.Source.YCount-1 do ChartStyles.Styles.Clear;
for i := 0 to serSource.YCount-1 do
begin begin
with TChartStyle(ChartStyles.Styles.Add) do with TChartStyle(ChartStyles.Styles.Add) do
begin begin
@ -1022,7 +1079,7 @@ begin
end; end;
end; end;
FChartFrame.Chart.BottomAxis.Marks.Source := ser.Source; FChartFrame.Chart.BottomAxis.Marks.Source := FBarSeries.Source;
FChartFrame.Chart.BottomAxis.Marks.Style := smsXValue; FChartFrame.Chart.BottomAxis.Marks.Style := smsXValue;
FChartFrame.SetTitle('AxBxR ANOVA'); FChartFrame.SetTitle('AxBxR ANOVA');
FChartFrame.SetXTitle(X_TITLE[AInteraction]); FChartFrame.SetXTitle(X_TITLE[AInteraction]);
@ -1040,6 +1097,7 @@ begin
ListChartSource_AC.Clear; ListChartSource_AC.Clear;
ListChartSource_BC.Clear; ListChartSource_BC.Clear;
BoxTestsPage.TabVisible := false;
ChartPage.TabVisible := false; ChartPage.TabVisible := false;
VarList.Items.Clear; VarList.Items.Clear;