LazStats: Use TAChart in ABRAnovaUnit.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7796 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-10-24 20:38:29 +00:00
parent 1e7192bd8e
commit ea551b66f3
4 changed files with 166 additions and 121 deletions

View File

@ -311,8 +311,6 @@ inherited ABRAnovaForm: TABRAnovaForm
Left = 350 Left = 350
Height = 336 Height = 336
Width = 465 Width = 465
ActivePage = ChartPage
TabIndex = 1
end end
object ListChartSource_AB: TListChartSource[3] object ListChartSource_AB: TListChartSource[3]
Left = 465 Left = 465

View File

@ -7,10 +7,9 @@ unit ABRANOVAUnit;
interface interface
uses uses
contexthelpunit, Classes, SysUtils, FileUtil, TASources, TAStyles, Forms, Classes, SysUtils, FileUtil, TASources, TAStyles, Forms,
Controls, Graphics, Dialogs, StdCtrls, Buttons, ExtCtrls, ComCtrls, MainUnit, Controls, Graphics, Dialogs, StdCtrls, Buttons, ExtCtrls, ComCtrls, MainUnit,
FunctionsLib, GraphLib, Globals, DataProcs, MatrixLib, FunctionsLib, Globals, DataProcs, MatrixLib, BasicStatsReportAndChartFormUnit;
BasicStatsReportAndChartFormUnit;
type type
@ -49,7 +48,9 @@ type
procedure COutBtnClick(Sender: TObject); procedure COutBtnClick(Sender: TObject);
procedure VarListDblClick(Sender: TObject); procedure VarListDblClick(Sender: TObject);
private private
{ private declarations } type TInteraction = (AB, AC, BC);
private
ColNoSelected: IntDyneVec; ColNoSelected: IntDyneVec;
ACol, BCol, NoSelected, MinA, MaxA, MinB, MaxB, NoAGrps, NoBGrps : integer; ACol, BCol, NoSelected, MinA, MaxA, MinB, MaxB, NoAGrps, NoBGrps : integer;
group, MaxRows, MaxCols, TotalN, NinGrp : integer; group, MaxRows, MaxCols, TotalN, NinGrp : integer;
@ -69,13 +70,16 @@ type
RowLabels, ColLabels : StrDyneVec; RowLabels, ColLabels : StrDyneVec;
selected : integer; selected : integer;
FBtnAB, FBtnAC, FBtnBC: TToolButton;
procedure InteractionChanged(Sender: TObject);
function InitData: Boolean; function InitData: Boolean;
procedure GetData; procedure GetData;
procedure Calculate; procedure Calculate;
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 GraphMeans; procedure PlotMeans(AInteraction: TInteraction);
procedure CleanUp; procedure CleanUp;
protected protected
@ -99,15 +103,53 @@ implementation
uses uses
Math, Math,
MathUnit, GridProcs; TAChartUtils, TALegend, TACustomSource, TACustomSeries, TASeries,
Utils, MathUnit, GridProcs, ChartFrameUnit;
{ TABRAnovaForm } { TABRAnovaForm }
constructor TABRAnovaForm.Create(AOwner: TComponent); constructor TABRAnovaForm.Create(AOwner: TComponent);
var
btn: TToolButton;
begin begin
inherited; inherited;
if GraphFrm = nil then
Application.CreateForm(TGraphFrm, GraphFrm); FChartFrame.Chart.Margins.Bottom := 0;
FChartFrame.Chart.BottomAxis.AxisPen.Visible := true;
FChartFrame.Chart.BottomAxis.ZPosition := 1;
FChartFrame.Chart.BottomAxis.Grid.Visible := false;
FChartFrame.ChartToolbar.ShowCaptions := true;
FChartFrame.ChartToolbar.ButtonHeight := 40;;
btn := TToolButton.Create(FChartFrame.ChartToolbar);
btn.Style := tbsDivider;
AddButtonToToolbar(btn, FChartFrame.ChartToolbar);
FBtnAB := TToolButton.Create(FChartFrame.ChartToolbar);
FBtnAB.Caption := 'AB interaction';
FBtnAB.Down := true;
FBtnAB.Style := tbsCheck;
FBtnAB.Grouped := true;
FBtnAB.OnClick := @InteractionChanged;
AddButtonToToolbar(FBtnAB, FChartFrame.ChartToolbar);
FBtnAC := TToolButton.Create(FChartFrame.ChartToolbar);
FBtnAC.Caption := 'AC interaction';
FBtnAC.Grouped := true;
FBtnAC.Style := tbsCheck;
FBtnAC.OnClick := @InteractionChanged;
AddButtonToToolbar(FBtnAC, FChartFrame.ChartToolbar);
FBtnBC := TToolButton.Create(FChartFrame.ChartToolbar);
FbtnBC.Caption := 'BC interaction';
FBtnBC.Grouped := true;
FBtnBC.Style := tbsCheck;
FBtnBC.OnClick := @InteractionChanged;
AddButtonToToolbar(FBtnBC, FChartFrame.ChartToolbar);
PageControl.ActivePageIndex := 0;
end; end;
@ -210,9 +252,11 @@ begin
Acnt := nil; Acnt := nil;
SumPSqr := nil; SumPSqr := nil;
AMatrix := nil; AMatrix := nil;
BCSums := nil; {
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;
@ -243,6 +287,7 @@ end;
procedure TABRAnovaForm.Compute; procedure TABRAnovaForm.Compute;
var var
lReport: TStrings; lReport: TStrings;
interaction: TInteraction;
begin begin
lReport := TStringList.Create; lReport := TStringList.Create;
try try
@ -252,9 +297,18 @@ begin
Calculate; Calculate;
Summarize(lReport); Summarize(lReport);
MeansReport(lReport); MeansReport(lReport);
if TestChk.Checked then BoxTests(lReport); if TestChk.Checked then
BoxTests(lReport);
FReportFrame.DisplayReport(lReport); FReportFrame.DisplayReport(lReport);
if PlotChk.Checked then GraphMeans;
if PlotChk.Checked then
begin
if FBtnAB.Down then interaction := AB else
if FBtnAC.Down then interaction := AC else
if FBtnBC.Down then interaction := BC;
PlotMeans(interaction);
end;
end; end;
finally finally
lReport.Free; lReport.Free;
@ -389,6 +443,23 @@ begin
Result := true; Result := true;
end; end;
procedure TABRAnovaForm.InteractionChanged(Sender: TObject);
var
interaction: TInteraction;
begin
if TObject(Sender) is TToolButton then
TToolButton(Sender).Down := true;
if FBtnAB.Down then
interaction := AB
else if FBtnAC.Down then
interaction := AC
else if FBtnBC.Down then
interaction := BC;
PlotMeans(interaction);
end;
procedure TABRAnovaForm.GetData; procedure TABRAnovaForm.GetData;
var var
i, j, SubjA, SubjB: integer; i, j, SubjA, SubjB: integer;
@ -868,120 +939,93 @@ begin
XVector := nil; XVector := nil;
end; end;
procedure TABRAnovaForm.GraphMeans;
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 var
MaxMean : double; idx: Integer;
i, j : integer; item: PChartDataItem;
ser: TChartSeries;
serSource: TListChartSource;
i, j: Integer;
begin begin
// Do AB interaction FChartFrame.Clear;
// Get maximum cell mean ListChartSource_AB.Clear;
MaxMean := ABSums[0,0] / (NinGrp*NoSelected); ListChartSource_AC.Clear;
SetLength(GraphFrm.Ypoints,NoAGrps,NoBGrps); ListChartSource_BC.Clear;
SetLength(GraphFrm.Xpoints,1,NoBGrps); ChartStyles.Styles.Clear;
for i := 1 to NoAGrps do
begin
GraphFrm.SetLabels[i] := 'A ' + IntToStr(i);
for j := 1 to NoBGrps do
begin
GraphFrm.Ypoints[i-1,j-1] := ABSums[i-1,j-1] / (NinGrp * NoSelected);
if GraphFrm.Ypoints[i-1,j-1] > MaxMean then MaxMean := GraphFrm.Ypoints[i-1,j-1];
end;
end;
for j := 1 to NoBGrps do
begin
GraphFrm.Xpoints[0,j-1] := j;
end;
GraphFrm.nosets := NoAGrps; ListChartSource_AB.YCount := NoAGrps;
GraphFrm.nbars := NoBGrps; for j := 0 to NoBGrps-1 do
GraphFrm.Heading := 'AxBxR ANOVA'; begin
GraphFrm.XTitle := 'B TREATMENT GROUP'; idx := ListChartSource_AB.Add(j+1, 0);
GraphFrm.YTitle := 'Mean'; item := ListChartSource_AB.Item[idx];
GraphFrm.barwideprop := 0.5; for i := 0 to NoAGrps-1 do
GraphFrm.AutoScaled := false; item^.SetY(i, ABSums[i, j] / (NInGrp * NoSelected));
GraphFrm.GraphType := 2; // 3d Vertical Bar Chart end;
GraphFrm.miny := 0.0;
GraphFrm.maxy := maxmean;
GraphFrm.BackColor := clCream;
GraphFrm.WallColor := clDkGray;
GraphFrm.FloorColor := clLtGray;
GraphFrm.ShowBackWall := true;
GraphFrm.ShowModal;
// Do AC interaction ListChartSource_AC.YCount := NoAGrps;
MaxMean := ACSums[0,0] / (NinGrp*NoBGrps); for j := 0 to NoSelected-1 do
SetLength(GraphFrm.Ypoints,NoAGrps,NoSelected); begin
SetLength(GraphFrm.Xpoints,1,NoSelected); idx := ListChartSource_AC.Add(j+1, 0);
for i := 1 to NoAGrps do item := ListChartSource_AC.Item[idx];
begin for i := 0 to NoAGrps-1 do
GraphFrm.SetLabels[i] := 'A ' + IntToStr(i); item^.SetY(i, ACSums[i, j] / (NInGrp * NoBGrps));
for j := 1 to NoSelected do end;
begin
GraphFrm.Ypoints[i-1,j-1] := ACSums[i-1,j-1] / (NinGrp * NoBGrps);
if GraphFrm.Ypoints[i-1,j-1] > MaxMean then MaxMean := GraphFrm.Ypoints[i-1,j-1];
end;
end;
for j := 1 to NoSelected do
begin
GraphFrm.Xpoints[0,j-1] := j;
end;
GraphFrm.nosets := NoAGrps;
GraphFrm.nbars := NoSelected;
GraphFrm.Heading := 'AxBxR ANOVA';
GraphFrm.XTitle := 'C TREATMENT (WITHIN SUBJECTS) 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;
// Do BC interaction ListChartSource_BC.YCount := NoBGrps;
SetLength(GraphFrm.Ypoints,NoBGrps,NoSelected); for j := 0 to NoSelected-1 do
SetLength(GraphFrm.Xpoints,NoSelected); begin
MaxMean := BCSums[0,0] / (NinGrp*NoAGrps); idx := ListChartSource_BC.Add(j+1, 0);
for i := 1 to NoBGrps do item := ListChartSource_BC.Item[idx];
for j := 1 to NoSelected do for i := 0 to NoBGrps-1 do
if ((BCSums[i-1,j-1] / (NinGrp*NoAGrps)) > MaxMean) then item^.SetY(i, BCSums[i, j] / (NInGrp * NoAGrps));
MaxMean := BCSums[i-1,j-1] / (NinGrp*NoAGrps); end;
for i := 1 to NoBGrps do
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;
for i := 0 to ser.Source.YCount-1 do
begin
with TChartStyle(ChartStyles.Styles.Add) do
begin begin
GraphFrm.SetLabels[i] := 'B ' + IntToStr(i); Text := Format(SERIES_TITLE[AInteraction], [i+1]);
for j := 1 to NoSelected do Brush.Color := DATA_COLORS[i mod Length(DATA_COLORS)];
begin UseBrush := true;
GraphFrm.Ypoints[i-1,j-1] := BCSums[i-1,j-1] / (NinGrp * NoAGrps);
if GraphFrm.Ypoints[i-1,j-1] > MaxMean then MaxMean := GraphFrm.Ypoints[i-1,j-1];
end;
end; end;
for j := 1 to NoSelected do end;
begin
GraphFrm.Xpoints[0,j-1] := j; FChartFrame.Chart.BottomAxis.Marks.Source := ser.Source;
end; FChartFrame.Chart.BottomAxis.Marks.Style := smsXValue;
GraphFrm.nosets := NoBGrps; FChartFrame.SetTitle('AxBxR ANOVA');
GraphFrm.nbars := NoSelected; FChartFrame.SetXTitle(X_TITLE[AInteraction]);
GraphFrm.Heading := 'AxBxR ANOVA'; FChartFrame.SetYTitle('Means');
GraphFrm.XTitle := 'C TREATMENT (WITHIN SUBJECTS) 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;
// cleanup the heap
GraphFrm.Xpoints := nil;
GraphFrm.Ypoints := nil;
end; end;
procedure TABRAnovaForm.Reset; procedure TABRAnovaForm.Reset;
var var
i: integer; i: integer;
@ -1053,7 +1097,7 @@ begin
if CList.Items.Count = 0 then if CList.Items.Count = 0 then
begin begin
AMsg := 'No Repeated Measures variables specified.'; AMsg := 'No Repeated Measures variable(s) specified.';
AControl := CList; AControl := CList;
exit; exit;
end; end;

View File

@ -31,13 +31,13 @@ inherited BasicStatsReportAndChartForm: TBasicStatsReportAndChartForm
Height = 434 Height = 434
Top = 8 Top = 8
Width = 396 Width = 396
ActivePage = ReportPage ActivePage = ChartPage
Align = alClient Align = alClient
BorderSpacing.Left = 4 BorderSpacing.Left = 4
BorderSpacing.Top = 8 BorderSpacing.Top = 8
BorderSpacing.Right = 8 BorderSpacing.Right = 8
BorderSpacing.Bottom = 8 BorderSpacing.Bottom = 8
TabIndex = 0 TabIndex = 1
TabOrder = 2 TabOrder = 2
object ReportPage: TTabSheet object ReportPage: TTabSheet
Caption = 'Report' Caption = 'Report'

View File

@ -69,6 +69,7 @@ object ChartFrame: TChartFrame
Caption = 'Save' Caption = 'Save'
ImageIndex = 4 ImageIndex = 4
OnClick = tbSaveChartClick OnClick = tbSaveChartClick
ShowCaption = False
end end
object tbPrintChart: TToolButton object tbPrintChart: TToolButton
Left = 26 Left = 26
@ -77,6 +78,7 @@ object ChartFrame: TChartFrame
Caption = 'Print' Caption = 'Print'
ImageIndex = 5 ImageIndex = 5
OnClick = tbPrintChartClick OnClick = tbPrintChartClick
ShowCaption = False
end end
object tbCopyChart: TToolButton object tbCopyChart: TToolButton
Left = 51 Left = 51
@ -85,6 +87,7 @@ object ChartFrame: TChartFrame
Caption = 'Copy' Caption = 'Copy'
ImageIndex = 7 ImageIndex = 7
OnClick = tbCopyChartClick OnClick = tbCopyChartClick
ShowCaption = False
end end
end end
object PrintDialog: TPrintDialog object PrintDialog: TPrintDialog