Files
lazarus-ccr/applications/lazstats/source/forms/analysis/descriptive/xvsmultyunit.pas

365 lines
8.7 KiB
ObjectPascal
Raw Normal View History

// Use file "SchoolsData.laz" for testing
unit XvsMultYUnit;
{$MODE objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
StdCtrls, Buttons, ExtCtrls, Printers, ComCtrls,
Globals, BasicStatsReportAndChartFormUnit, ReportFrameUnit, ChartFrameUnit;
type
{ TXvsMultYForm }
TXvsMultYForm = class(TBasicStatsReportAndChartForm)
LinesBox: TCheckBox;
GroupBox1: TGroupBox;
Panel1: TPanel;
PlotTitleEdit: TEdit;
Label4: TLabel;
YBox: TListBox;
XEdit: TEdit;
Label2: TLabel;
Label3: TLabel;
XInBtn: TBitBtn;
YInBtn: TBitBtn;
Label1: TLabel;
XOutBtn: TBitBtn;
YOutBtn: TBitBtn;
VarList: TListBox;
procedure VarListDblClick(Sender: TObject);
procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean);
procedure XInBtnClick(Sender: TObject);
procedure XOutBtnClick(Sender: TObject);
procedure YInBtnClick(Sender: TObject);
procedure YOutBtnClick(Sender: TObject);
private
procedure PlotXY(XValues: DblDyneVec; YValues: DblDyneMat);
procedure WriteToReport(const ASelected: IntDyneVec;
const ARowLabels, AColLabels: StrDyneVec);
protected
procedure AdjustConstraints; override;
procedure Compute; override;
procedure UpdateBtnStates; override;
public
constructor Create(AOwner: TComponent); override;
procedure Reset; override;
end;
var
XvsMultYForm: TXvsMultYForm;
implementation
{$R *.lfm}
uses
TAChartUtils,
MainUnit, MatrixLib, MathUnit, GridProcs, Utils;
{ TXvsMultYForm }
constructor TXvsMultYForm.Create(AOwner: TComponent);
begin
inherited;
PageControl.ActivePage := ChartPage;
end;
procedure TXvsMultYForm.Compute;
var
i, j, N, nY, xCol, NoSelected: integer;
xValues: DblDyneVec = nil;
yValues: DblDyneMat = nil;
RowLabels: StrDyneVec = nil;
ColLabels: StrDyneVec = nil;
selected: IntDyneVec = nil;
begin
if XEdit.Text = '' then
begin
ErrorMsg('No X variable selected.');
exit;
end;
if YBox.Items.Count = 0 then
begin
ErrorMsg('No Y variables selected.');
exit;
end;
xCol := OS3MainFrm.DataGrid.Rows[0].IndexOf(Trim(XEdit.Text));
if xCol = -1 then
begin
ErrorMsg('X variable not found.');
exit;
end;
nY := YBox.Items.Count;
SetLength(selected, nY + 1); // one more for the x column, needed by Correlations()
for j := 0 to nY - 1 do
selected[j] := OS3MainFrm.DataGrid.Rows[0].IndexOf(YBox.Items[j]);
selected[nY] := xCol;
NoSelected := nY + 1;
SetLength(RowLabels, NoVariables);
SetLength(ColLabels, NoVariables);
for i := 0 to NoSelected-1 do
begin
RowLabels[i] := Trim(OS3MainFrm.DataGrid.Cells[selected[i],0]);
ColLabels[i] := RowLabels[i];
end;
// Extract x and y values
xValues := CollectValues(OS3MainFrm.DataGrid, xCol, selected);
SetLength(yValues, nY);
for i := 0 to nY-1 do
yValues[i] := CollectValues(OS3MainFrm.DataGrid, selected[i], selected);
// Make sure that all y columns have the same length
N := Length(yValues[0]);
for i := 1 to nY-1 do
if N <> Length(yValues[i]) then
begin
ErrorMsg('Different count of cases.');
exit;
end;
// Print out correclations, means, etc to report frame
WriteToReport(selected, RowLabels, ColLabels);
// Sort on X
SortOnX(XValues, YValues);
// Plot x vs multiple y
PlotXY(XValues, YValues);
end;
procedure TXvsMultYForm.AdjustConstraints;
begin
Panel1.Constraints.MinHeight := YOutBtn.Top + YOutBtn.Height;
ParamsPanel.Constraints.MinWidth := 4*CloseBtn.Width + 3*CloseBtn.BorderSpacing.Left;
ParamsPanel.Constraints.MinHeight := Panel1.Constraints.MinHeight + Panel1.BorderSpacing.Bottom +
PlotTitleEdit.Height + GroupBox1.Height + 2*GroupBox1.BorderSpacing.Top +
ButtonBevel.Height + CloseBtn.Height + CloseBtn.BorderSpacing.Top;
Constraints.MinHeight := ParamsPanel.Constraints.MinHeight + 2*ParamsPanel.BorderSpacing.Top;
Constraints.MinWidth := ParamsPanel.Constraints.MinWidth + 200;
end;
// Routine to plot X versus multiple Y values
// Unlike many other routines in LazStats the curve index in YValues is the
// first one, the point index is the second one.
procedure TXvsMultYForm.PlotXY(XValues: DblDyneVec; YValues: DblDyneMat);
var
Ny, Nc: Integer;
j: Integer;
pt: TPlotType;
begin
// Preparations
if LinesBox.Checked then pt := ptLinesAndSymbols else pt := ptSymbols;
Ny := Length(YValues);
Nc := Length(DATA_COLORS);
FChartFrame.Clear;
// Titles
FChartFrame.SetTitle(PlotTitleEdit.Text);
FChartFrame.SetXTitle(XEdit.Text);
FChartFrame.SetYTitle('Y Values');
// Plot a series for each y value
for j := 0 to Ny - 1 do
FChartFrame.PlotXY(pt, XValues, YValues[j], nil, nil, Trim(YBox.Items[j]), DATA_COLORS[j mod Nc]);
end;
procedure TXvsMultYForm.Reset;
var
i: integer;
begin
VarList.Clear;
YBox.Clear;
XEdit.Clear;
XInBtn.Enabled := true;
XOutBtn.Enabled := false;
YInBtn.Enabled := true;
YOutBtn.Enabled := false;
PlotTitleEdit.Text := '';
for i := 1 to NoVariables do
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
if Assigned(FReportFrame) then
FReportFrame.Clear;
if Assigned(FChartFrame) then
FChartFrame.Clear;
end;
procedure TXvsMultYForm.UpdateBtnStates;
var
lSelected: Boolean;
begin
lSelected := AnySelected(VarList);
XInBtn.Enabled := lSelected and (XEdit.Text = '');
YInBtn.Enabled := lSelected;
xOutBtn.Enabled := (XEdit.Text <> '');
YOutBtn.Enabled := AnySelected(YBox);
if Assigned(FReportFrame) then FReportFrame.UpdateBtnStates;
if Assigned(FChartFrame) then FChartFrame.UpdateBtnStates;
end;
procedure TXvsMultYForm.VarListDblClick(Sender: TObject);
var
index: integer;
begin
index := VarList.ItemIndex;
if index > -1 then
begin
if XEdit.Text = '' then
XEdit.Text := VarList.Items[index]
else
YBox.Items.Add(VarList.Items[index]);
VarList.Items.Delete(index);
UpdateBtnStates;
end;
end;
procedure TXvsMultYForm.WriteToReport(const ASelected: IntDyneVec;
const ARowLabels, AColLabels: StrDyneVec);
var
lReport: TStrings;
i: Integer;
means: DblDyneVec = nil;
variances: DblDyneVec = nil;
stdDevs: DblDyneVec = nil;
RMatrix: DblDyneMat = nil;
nSelected: Integer = 0;
nCases: Integer = 0;
error: Boolean = false;
begin
lReport := TStringList.Create;
try
// get descriptive data
lReport.Add('X VERSUS MULTIPLE Y VALUES PLOT');
lReport.Add('');
nSelected := Length(ASelected);
SetLength(means, nSelected);
SetLength(variances, nSelected);
SetLength(stdDevs, nSelected);
SetLength(RMatrix, nSelected+1, nSelected+1);
Correlations(nSelected, ASelected, RMatrix, means, variances, stdDevs, error, nCases);
if error then
begin
lReport.Add('ERROR: zero variance detected.');
exit;
end;
//DynVectorPrint(means, nSelected, 'MEANS', ARowLabels, nSelected, lReport);
//DynVectorPrint(variances, nSelected, 'VARIANCES', ARowLabels, nCases, lReport);
//DynVectorPrint(stdDevs, nSelected, 'STANDARD DEVIATIONS', ARowLabels, nCases, lReport);
lReport.Add( ' Variable Mean Variance Std.Dev. ');
lReport.Add( '--------------- --------------- --------------- ---------------');
for i := 0 to nSelected-1 do
lReport.Add('%-15s %15.3f %15.3f %15.3f', [ARowLabels[i], means[i], variances[i], stdDevs[i]]);
lReport.Add('');
lReport.Add('');
MatPrint(RMatrix, nSelected, nSelected, 'CORRELATIONS', ARowLabels, AColLabels, nCases, lReport);
FReportFrame.DisplayReport(lReport);
finally
lReport.Free;
end;
end;
procedure TXvsMultYForm.VarListSelectionChange(Sender: TObject; User: boolean);
begin
UpdateBtnStates;
end;
procedure TXvsMultYForm.XInBtnClick(Sender: TObject);
var
index: integer;
begin
index := VarList.ItemIndex;
if (index > -1) and (XEdit.Text = '') then
begin
XEdit.Text := VarList.Items[index];
VarList.Items.Delete(index);
end;
UpdateBtnStates;
end;
procedure TXvsMultYForm.XOutBtnClick(Sender: TObject);
begin
if (XEdit.Text <> '') then
begin
VarList.Items.Add(XEdit.Text);
XEdit.Text := '';
end;
UpdateBtnStates;
end;
procedure TXvsMultYForm.YInBtnClick(Sender: TObject);
var
i: integer;
begin
i := 0;
while i < VarList.Items.Count do
begin
if VarList.Selected[i] then
begin
YBox.Items.Add(VarList.Items[i]);
VarList.Items.Delete(i);
i := 0;
end else
inc(i);
end;
UpdateBtnStates;
end;
procedure TXvsMultYForm.YOutBtnClick(Sender: TObject);
var
i: integer;
begin
i := 0;
while i < YBox.Items.Count do
begin
if (YBox.Selected[i]) then
begin
VarList.Items.Add(YBox.Items[i]);
YBox.Items.Delete(i);
i := 0;
end else
i := i + 1;
end;
UpdateBtnStates;
end;
end.