From 9da0a4334a194868893346b2815cf9747547992d Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Sun, 22 Nov 2020 18:48:59 +0000 Subject: [PATCH] LazStats: Inherit RaschUnit from BasicStatisReportAndChartUnit. Some refactoring. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7896 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- applications/lazstats/source/LazStats.lpi | 2 +- .../measurement_programs/raschunit.lfm | 451 ++++----- .../measurement_programs/raschunit.pas | 889 +++++++++--------- .../lazstats/source/forms/mainunit.pas | 8 +- 4 files changed, 633 insertions(+), 717 deletions(-) diff --git a/applications/lazstats/source/LazStats.lpi b/applications/lazstats/source/LazStats.lpi index a8e0f2e98..60ca4c590 100644 --- a/applications/lazstats/source/LazStats.lpi +++ b/applications/lazstats/source/LazStats.lpi @@ -637,7 +637,7 @@ - + diff --git a/applications/lazstats/source/forms/analysis/measurement_programs/raschunit.lfm b/applications/lazstats/source/forms/analysis/measurement_programs/raschunit.lfm index d6a204e1d..24bb08011 100644 --- a/applications/lazstats/source/forms/analysis/measurement_programs/raschunit.lfm +++ b/applications/lazstats/source/forms/analysis/measurement_programs/raschunit.lfm @@ -1,263 +1,224 @@ -object RaschFrm: TRaschFrm +inherited RaschForm: TRaschForm Left = 673 Height = 419 Top = 319 - Width = 406 + Width = 855 HelpType = htKeyword HelpKeyword = 'html/RaschTestCalibration.htm' - AutoSize = True Caption = 'Rasch One Parameter Item Scaling' ClientHeight = 419 - ClientWidth = 406 - OnActivate = FormActivate - OnCreate = FormCreate - OnShow = FormShow - Position = poMainFormCenter - LCLVersion = '2.1.0.0' - object GroupBox1: TGroupBox - AnchorSideLeft.Control = Owner - AnchorSideLeft.Side = asrCenter - AnchorSideTop.Side = asrBottom - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = Bevel1 - Left = 36 - Height = 93 - Top = 277 - Width = 334 - Anchors = [akLeft, akBottom] - AutoSize = True - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - Caption = 'Output Options:' - ChildSizing.LeftRightSpacing = 12 - ChildSizing.TopBottomSpacing = 6 - ChildSizing.VerticalSpacing = 2 - ChildSizing.Layout = cclLeftToRightThenTopToBottom - ChildSizing.ControlsPerLine = 2 - ClientHeight = 73 - ClientWidth = 330 - TabOrder = 4 - object ProxChk: TCheckBox - Left = 12 - Height = 19 - Top = 6 - Width = 179 - Caption = 'Show Prox Calculations' + ClientWidth = 855 + inherited ParamsPanel: TPanel + Height = 403 + Width = 336 + ClientHeight = 403 + ClientWidth = 336 + inherited CloseBtn: TButton + Left = 281 + Top = 378 + TabOrder = 8 + end + inherited ComputeBtn: TButton + Left = 197 + Top = 378 + TabOrder = 7 + end + inherited ResetBtn: TButton + Left = 135 + Top = 378 + TabOrder = 6 + end + inherited HelpBtn: TButton + Tag = 140 + Left = 76 + Top = 378 + TabOrder = 5 + end + inherited ButtonBevel: TBevel + Top = 362 + Width = 336 + end + object OptionsGroup: TGroupBox[5] + AnchorSideLeft.Control = ParamsPanel + AnchorSideLeft.Side = asrCenter + AnchorSideTop.Side = asrBottom + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = ButtonBevel + Left = 0 + Height = 93 + Top = 269 + Width = 336 + Anchors = [akLeft, akBottom] + AutoSize = True + BorderSpacing.Left = 8 + BorderSpacing.Top = 8 + BorderSpacing.Right = 8 + Caption = 'Output Options:' + ChildSizing.LeftRightSpacing = 12 + ChildSizing.TopBottomSpacing = 6 + ChildSizing.VerticalSpacing = 2 + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 2 + ClientHeight = 73 + ClientWidth = 332 + TabOrder = 4 + object ProxChk: TCheckBox + Left = 12 + Height = 19 + Top = 6 + Width = 181 + Caption = 'Show Prox Calculations' + TabOrder = 0 + end + object PlotItemDiffChk: TCheckBox + Left = 193 + Height = 19 + Top = 6 + Width = 127 + Caption = 'Plot Item Difficulties' + TabOrder = 1 + end + object PlotScrsChk: TCheckBox + Left = 12 + Height = 19 + Top = 27 + Width = 181 + Caption = 'Plot Log Abilities' + TabOrder = 2 + end + object ItemFuncsChk: TCheckBox + Left = 193 + Height = 19 + Top = 27 + Width = 127 + Caption = 'Plot Item Functions' + TabOrder = 3 + end + object TestInfoChk: TCheckBox + Left = 12 + Height = 19 + Top = 48 + Width = 181 + Caption = 'Plot Test Information Function' + TabOrder = 4 + end + end + object Label1: TLabel[6] + AnchorSideLeft.Control = ParamsPanel + AnchorSideTop.Control = ParamsPanel + Left = 0 + Height = 15 + Top = 0 + Width = 97 + Caption = 'Available Variables' + ParentColor = False + end + object Label2: TLabel[7] + AnchorSideLeft.Control = ItemList + AnchorSideTop.Control = ParamsPanel + Left = 187 + Height = 15 + Top = 0 + Width = 93 + BorderSpacing.Right = 8 + Caption = 'Selected Variables' + ParentColor = False + end + object VarList: TListBox[8] + AnchorSideLeft.Control = ParamsPanel + AnchorSideTop.Control = Label1 + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = InBtn + AnchorSideBottom.Control = OptionsGroup + Left = 0 + Height = 244 + Top = 17 + Width = 149 + Anchors = [akTop, akLeft, akRight, akBottom] + BorderSpacing.Top = 2 + BorderSpacing.Right = 6 + Constraints.MinHeight = 220 + ItemHeight = 0 + MultiSelect = True + OnSelectionChange = VarListSelectionChange TabOrder = 0 end - object PlotItemsChk: TCheckBox - Left = 191 - Height = 19 - Top = 6 - Width = 127 - Caption = 'Plot Item Difficulties' + object InBtn: TBitBtn[9] + AnchorSideLeft.Control = ParamsPanel + AnchorSideLeft.Side = asrCenter + AnchorSideTop.Control = VarList + Left = 155 + Height = 26 + Top = 17 + Width = 26 + Images = MainDataModule.ImageList + ImageIndex = 1 + OnClick = InBtnClick + Spacing = 0 TabOrder = 1 end - object PlotScrsChk: TCheckBox - Left = 12 - Height = 19 - Top = 27 - Width = 179 - Caption = 'Plot Log Abilities' - TabOrder = 2 - end - object ItemInfoChk: TCheckBox - Left = 191 - Height = 19 - Top = 27 - Width = 127 - Caption = 'Plot Item Functions' + object ItemList: TListBox[10] + AnchorSideLeft.Control = InBtn + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = Label2 + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = ParamsPanel + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = OptionsGroup + Left = 187 + Height = 244 + Top = 17 + Width = 149 + Anchors = [akTop, akLeft, akRight, akBottom] + BorderSpacing.Left = 6 + BorderSpacing.Top = 2 + ItemHeight = 0 + MultiSelect = True + OnSelectionChange = VarListSelectionChange TabOrder = 3 end - object TestInfoChk: TCheckBox - Left = 12 - Height = 19 - Top = 48 - Width = 179 - Caption = 'Plot Test Information function' - TabOrder = 4 + object OutBtn: TBitBtn[11] + AnchorSideLeft.Control = ParamsPanel + AnchorSideLeft.Side = asrCenter + AnchorSideTop.Control = InBtn + AnchorSideTop.Side = asrBottom + Left = 155 + Height = 26 + Top = 47 + Width = 26 + BorderSpacing.Top = 4 + Images = MainDataModule.ImageList + ImageIndex = 0 + OnClick = OutBtnClick + Spacing = 0 + TabOrder = 2 end end - object ResetBtn: TButton - AnchorSideRight.Control = ComputeBtn - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 197 - Height = 25 - Top = 386 - Width = 54 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - BorderSpacing.Bottom = 8 - Caption = 'Reset' - OnClick = ResetBtnClick - TabOrder = 6 + inherited ParamsSplitter: TSplitter + Left = 348 + Height = 419 end - object ComputeBtn: TButton - AnchorSideRight.Control = CloseBtn - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 259 - Height = 25 - Top = 386 - Width = 76 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - BorderSpacing.Bottom = 8 - Caption = 'Compute' - OnClick = ComputeBtnClick - TabOrder = 7 - end - object CloseBtn: TButton - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 343 - Height = 25 - Top = 386 - Width = 55 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - BorderSpacing.Bottom = 8 - Caption = 'Close' - ModalResult = 11 - TabOrder = 8 - end - object HelpBtn: TButton - Tag = 140 - AnchorSideRight.Control = ResetBtn - AnchorSideBottom.Control = Owner - AnchorSideBottom.Side = asrBottom - Left = 138 - Height = 25 - Top = 386 - Width = 51 - Anchors = [akRight, akBottom] - AutoSize = True - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - BorderSpacing.Bottom = 8 - Caption = 'Help' - OnClick = HelpBtnClick - TabOrder = 5 - end - object Bevel1: TBevel - AnchorSideLeft.Control = Owner - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = CloseBtn - Left = 0 - Height = 8 - Top = 370 - Width = 406 - Anchors = [akLeft, akRight, akBottom] - Shape = bsBottomLine - end - object Label1: TLabel - AnchorSideLeft.Control = Owner - AnchorSideTop.Control = Owner - Left = 8 - Height = 15 - Top = 8 - Width = 97 - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - Caption = 'Available Variables' - ParentColor = False - end - object Label2: TLabel - AnchorSideLeft.Control = ItemList - AnchorSideTop.Control = Owner - Left = 225 - Height = 15 - Top = 8 - Width = 93 - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - Caption = 'Selected Variables' - ParentColor = False - end - object VarList: TListBox - AnchorSideLeft.Control = Owner - AnchorSideTop.Control = Label1 - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = InBtn - AnchorSideBottom.Control = GroupBox1 - Left = 8 - Height = 244 - Top = 25 - Width = 173 - Anchors = [akTop, akLeft, akRight, akBottom] - BorderSpacing.Left = 8 - BorderSpacing.Top = 2 - BorderSpacing.Right = 8 - Constraints.MinHeight = 220 - ItemHeight = 0 - MultiSelect = True - OnSelectionChange = VarListSelectionChange - TabOrder = 0 - end - object InBtn: TBitBtn - AnchorSideLeft.Control = Owner - AnchorSideLeft.Side = asrCenter - AnchorSideTop.Control = VarList - Left = 189 - Height = 28 - Top = 25 - Width = 28 - Images = MainDataModule.ImageList - ImageIndex = 1 - OnClick = InBtnClick - Spacing = 0 - TabOrder = 1 - end - object ItemList: TListBox - AnchorSideLeft.Control = InBtn - AnchorSideLeft.Side = asrBottom - AnchorSideTop.Control = Label2 - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = GroupBox1 - Left = 225 - Height = 244 - Top = 25 - Width = 173 - Anchors = [akTop, akLeft, akRight, akBottom] - BorderSpacing.Left = 8 - BorderSpacing.Top = 2 - BorderSpacing.Right = 8 - ItemHeight = 0 - MultiSelect = True - OnSelectionChange = VarListSelectionChange - TabOrder = 3 - end - object OutBtn: TBitBtn - AnchorSideLeft.Control = Owner - AnchorSideLeft.Side = asrCenter - AnchorSideTop.Control = InBtn - AnchorSideTop.Side = asrBottom - Left = 189 - Height = 28 - Top = 57 - Width = 28 - BorderSpacing.Top = 4 - Images = MainDataModule.ImageList - ImageIndex = 0 - OnClick = OutBtnClick - Spacing = 0 - TabOrder = 2 + inherited PageControl: TPageControl + Left = 357 + Height = 403 + Width = 490 + ActivePage = ItemFuncsPage + TabIndex = 3 + inherited ChartPage: TTabSheet + Caption = 'Plot Item Difficulties' + TabVisible = False + end + object ScoresPage: TTabSheet[2] + Caption = 'Plot Log Abilities' + TabVisible = False + end + object ItemFuncsPage: TTabSheet[3] + Caption = 'Plot Item Functions' + TabVisible = False + end + object TestInfoPage: TTabSheet[4] + Caption = 'Plot Test Info' + TabVisible = False + end end end diff --git a/applications/lazstats/source/forms/analysis/measurement_programs/raschunit.pas b/applications/lazstats/source/forms/analysis/measurement_programs/raschunit.pas index d2942dbad..a66490abd 100644 --- a/applications/lazstats/source/forms/analysis/measurement_programs/raschunit.pas +++ b/applications/lazstats/source/forms/analysis/measurement_programs/raschunit.pas @@ -4,51 +4,40 @@ unit RaschUnit; {$mode objfpc}{$H+} +{$WARN 6058 off : Call to subroutine "$1" marked as inline is not inlined} interface uses - Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, - StdCtrls, Buttons, ExtCtrls, - MainUnit, OutputUnit, FunctionsLib, GraphLib, Globals, - DataProcs, ContextHelpUnit; + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons, + ExtCtrls, ComCtrls, MainUnit, FunctionsLib, Globals, + ChartFrameUnit, BasicStatsReportAndChartFormUnit; type - { TRaschFrm } + { TRaschForm } - TRaschFrm = class(TForm) - Bevel1: TBevel; - HelpBtn: TButton; - ResetBtn: TButton; - ComputeBtn: TButton; - CloseBtn: TButton; + TRaschForm = class(TBasicStatsReportAndChartForm) ProxChk: TCheckBox; - PlotItemsChk: TCheckBox; + PlotItemDiffChk: TCheckBox; PlotScrsChk: TCheckBox; - ItemInfoChk: TCheckBox; + ItemFuncsChk: TCheckBox; + ScoresPage: TTabSheet; + ItemFuncsPage: TTabSheet; + TestInfoPage: TTabSheet; TestInfoChk: TCheckBox; - GroupBox1: TGroupBox; + OptionsGroup: TGroupBox; InBtn: TBitBtn; Label2: TLabel; ItemList: TListBox; OutBtn: TBitBtn; Label1: TLabel; VarList: TListBox; - procedure ComputeBtnClick(Sender: TObject); - procedure FormActivate(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure FormShow(Sender: TObject); - procedure HelpBtnClick(Sender: TObject); procedure InBtnClick(Sender: TObject); procedure OutBtnClick(Sender: TObject); - procedure ResetBtnClick(Sender: TObject); procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean); - private - { private declarations } - FAutoSized: Boolean; - procedure UpdateBtnStates; + private procedure Analyze(const itemfail, grpfail: IntDyneVec; const f: IntDyneMat; var T: integer; const grppass, itempass: IntDyneVec; r, C1: integer; out min, max: double; const p2: DblDyneVec); @@ -86,99 +75,154 @@ type procedure TestFit(r, C1: integer; const f: IntDyneMat; const S: IntDyneVec; const P, P2: DblDyneVec; T: integer; AReport: TStrings); - procedure PlotInfo(k, r: integer; const Info, A: DblDyneMat; + procedure PlotInfo(r: integer; const Info, A: DblDyneMat; const Slope, P: DblDyneVec); - procedure Plot(const xyArray: DblDyneMat; ArraySize: integer; - const Title: string; Vdivisions, Hdivisions: integer); + procedure Plot(const xyArray: DblDyneMat; ArraySize: integer); procedure PlotItems(r: integer; const i5: IntDyneVec; const P: DblDyneVec); procedure PlotScrs(C1: integer; const s5: IntDyneVec; const p2: DblDyneVec); procedure PlotTest(const TestInfo: DblDyneMat; ArraySize: integer; - const Title: string; Vdivisions, Hdivisions: integer); + const Title: string{; Vdivisions, Hdivisions: integer}); + + private + FChartCombobox: TCombobox; + FItemDiffsChartFrame: TChartFrame; + FScoresChartFrame: TChartFrame; + FItemFuncsChartFrame: TChartFrame; + FTestInfoChartFrame: TChartFrame; + procedure SelectItemFuncsPlot(Sender: TObject); + + protected + procedure AdjustConstraints; override; + procedure Compute; override; + procedure UpdateBtnStates; override; + function Validate(out AMsg: String; out AControl: TWinControl): Boolean; override; + public - { public declarations } + constructor Create(AOwner: TComponent); override; + procedure Reset; override; + end; var - RaschFrm: TRaschFrm; + RaschForm: TRaschForm; implementation +{$R *.lfm} + uses - Math, Utils; + Math, + TAChartUtils, TACustomSeries, + Utils, GridProcs; -{ TRaschFrm } +{ TRaschForm } -procedure TRaschFrm.ResetBtnClick(Sender: TObject); +constructor TRaschForm.Create(AOwner: TComponent); +begin + inherited; + + FItemDiffsChartFrame := FChartFrame; // already created by ancestor + + FScoresChartFrame := TChartFrame.Create(self); + FScoresChartFrame.Parent := ScoresPage; + FScoresChartFrame.Align := alClient; + + FItemFuncsChartFrame := TChartFrame.Create(self); + FItemFuncsChartFrame.Parent := ItemFuncsPage; + FItemFuncsChartFrame.Align := alClient; + AddComboboxToToolbar(FItemFuncsChartFrame.ChartToolbar, 'Plots:', FChartCombobox); + FChartCombobox.OnSelect := @SelectItemFuncsPlot; + + FTestInfoChartFrame := TChartFrame.Create(self); + FTestInfoChartFrame.Parent := TestInfoPage; + FTestInfoChartFrame.Align := alClient; +end; + + +procedure TRaschForm.AdjustConstraints; +begin + inherited; + ParamsPanel.Constraints.MinWidth := Max( + 4*CloseBtn.Width + 3*CloseBtn.BorderSpacing.Left, + OptionsGroup.Width + ); + ParamsPanel.Constraints.MinHeight := OutBtn.Top + OutBtn.Height + + VarList.BorderSpacing.Bottom + ButtonBevel.Height + + CloseBtn.Borderspacing.Top + CloseBtn.Height; +end; + + +procedure TRaschForm.Analyze(const itemfail, grpfail: IntDyneVec; + const f: IntDyneMat; var T: integer; const grppass, itempass: IntDyneVec; + r, C1: integer; out min, max: double; const p2: DblDyneVec); var - i: integer; + i, j: integer; begin - VarList.Clear; - ItemList.Clear; - ProxChk.Checked := false; - PlotItemsChk.Checked := false; - PlotScrsChk.Checked := false; - ItemInfoChk.Checked := false; - TestInfoChk.Checked := false; - for i := 1 to NoVariables do - VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); - UpdateBtnStates; + for i := 0 to r-1 do itemfail[i] := 0; + for j := 0 to C1-1 do grpfail[j] := 0; + for i := 0 to r-1 do + begin + for j := 0 to C1-1 do + begin + grpfail[j] := grpfail[j] + f[i,j]; + itemfail[i] := itemfail[i] + f[i,j]; + end; + end; + T := 0; + for j := 0 to C1-1 do T := T + grpfail[j]; + for j := 0 to C1-1 do grppass[j] := T - grpfail[j]; + for i := 0 to r-1 do itempass[i] := T - itemfail[i]; + min := p2[0]; + max := p2[0]; + for i := 0 to C1-1 do + begin + if (p2[i] < min) then min := p2[i]; + if (p2[i] > max) then max := p2[i]; + end; end; -procedure TRaschFrm.FormActivate(Sender: TObject); + +procedure TRaschForm.Compute; var - w: Integer; -begin - if FAutoSized then - exit; - - 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.MinWidth := Width; - Constraints.MinHeight := Height; - - FAutoSized := true; -end; - -procedure TRaschFrm.FormCreate(Sender: TObject); -begin - Assert(OS3MainFrm <> nil); - - if OutputFrm = nil then - Application.CreateForm(TOutputFrm, OutputFrm); - if GraphFrm = nil then - Application.CreateForm(TGraphFrm, GraphFrm); -end; - -procedure TRaschFrm.FormShow(Sender: TObject); -begin - ResetBtnClick(self); -end; - -procedure TRaschFrm.HelpBtnClick(Sender: TObject); -begin - if ContextHelpForm = nil then - Application.CreateForm(TContextHelpForm, ContextHelpForm); - ContextHelpForm.HelpMessage((Sender as TButton).tag); -end; - -procedure TRaschFrm.ComputeBtnClick(Sender: TObject); -var - i, j, k1, N, C1, r, T,noloops : integer; + i, k1, N, C1, r, T,noloops : integer; sumx, sumx2, v1, v2, xexpand, yexpand, d9, min, max : double; - X, rowtot, itemfail, itempass, grpfail, grppass, S, s5, i5 : IntDyneVec; - f : IntDyneMat; - mean, xsqr, sumxy, L, L1, L2, g, g2, f2, P, p2, R1, d1, e1 : DblDyneVec; - expdcnt, d2 : DblDyneVec; - e2, rptbis, rbis, slope : DblDyneVec; - p1, D, info, A : DblDyneMat; + X: IntDyneVec = nil; + rowtot: IntDyneVec = nil; + itemFail: IntDyneVec = nil; + itemPass: IntDyneVec = nil; + grpFail: IntDyneVec = nil; + grpPass: IntDyneVec = nil; + S: IntDyneVec = nil; + s5: IntDyneVec = nil; + i5: IntDyneVec = nil; + f: IntDyneMat = nil; + mean: DblDyneVec = nil; + xsqr: DblDyneVec = nil; + sumXY: DblDyneVec = nil; + L: DblDyneVec = nil; + L1: DblDyneVec = nil; + L2: DblDyneVec = nil; + g: DblDyneVec = nil; + g2: DblDyneVec = nil; + f2: DblDyneVec = nil; + P: DblDyneVec = nil; + p2: DblDyneVec = nil; + R1: DblDyneVec = nil; + d1: DblDyneVec = nil; + d2: DblDyneVec = nil; + e1: DblDyneVec = nil; + e2: DblDyneVec = nil; + expdcnt: DblDyneVec = nil; + rptbis: DblDyneVec = nil; + rbis: DblDyneVec = nil; + slope: DblDyneVec = nil; + p1: DblDyneMat = nil; + D: DblDyneMat = nil; + info: DblDyneMat = nil; + A: DblDyneMat = nil; NoSelected : integer; - ColNoSelected : IntDyneVec; + ColNoSelected : IntDyneVec = nil; finished : boolean; - cellstring : string; error : integer; lReport: TStrings; begin @@ -217,23 +261,11 @@ begin SetLength(s5,NoVariables); SetLength(i5,NoVariables); SetLength(f,NoVariables+2,NoVariables+2); - if (NoVariables < 1) then - begin - MessageDlg('You must have data in your data grid.', mtError, [mbOK], 0); - exit; - end; // Get selected variables NoSelected := ItemList.Items.Count; - for i := 1 to NoSelected do - begin - for j := 1 to NoVariables do - begin - cellstring := OS3MainFrm.DataGrid.Cells[j,0]; - if cellstring = ItemList.Items.Strings[i-1] then - ColNoSelected[i-1] := j; - end; - end; + for i := 0 to NoSelected-1 do + colNoSelected[i] := GetVariableIndex(OS3MainFrm.DataGrid, ItemList.Items[i]); //begin ( main program ) finished := false; @@ -276,127 +308,33 @@ begin Slopes(rptbis, rbis, slope, N, sumx, sumx2, sumxy, r, xsqr, mean); Analyze(itemfail, grpfail, f, T, grppass, itempass, r, C1, min, max, p2); - if PlotItemsChk.Checked then PlotItems(r, i5, P); + if PlotItemDiffChk.Checked then PlotItems(r, i5, P); if PlotScrsChk.Checked then PlotScrs(C1, s5, p2); - if TestInfoChk.Checked then PlotInfo(k1, r, info, A, slope, P); + PlotInfo(r, info, A, slope, P); + + ChartPage.TabVisible := PlotItemDiffChk.Checked; + ScoresPage.TabVisible := PlotScrsChk.Checked; + ItemFuncsPage.TabVisible := ItemFuncsChk.Checked; + TestInfopage.TabVisible := TestInfoChk.Checked; FinishIt(r, i5, rptbis, rbis, slope, mean, itemfail, P, lReport); - DisplayReport(lReport); + FReportFrame.DisplayReport(lReport); - finally - // cleanup - lReport.Free; - A := nil; - info := nil; - D := nil; - p1 := nil; - f := nil; - grppass := nil; - grpfail := nil; - itempass := nil; - itemfail := nil; - i5 := nil; - s5 := nil; - S := nil; - sumxy := nil; - xsqr := nil; - mean := nil; - rowtot := nil; - X := nil; - d1 := nil; - R1 := nil; - p2 := nil; - P := nil; - f2 := nil; - g2 := nil; - g := nil; - L2 := nil; - L1 := nil; - L := nil; - e1 := nil; - expdcnt := nil; - d2 := nil; - e2 := nil; - slope := nil; - rbis := nil; - rptbis := nil; - ColNoSelected := nil; - end; -end; - -procedure TRaschFrm.InBtnClick(Sender: TObject); -var - i: integer; -begin - i := 0; - while i < VarList.Items.Count do - begin - if VarList.Selected[i] then - begin - ItemList.Items.Add(VarList.Items[i]); - VarList.Items.Delete(i); - i := 0; - end else - i := i + 1; - end; - UpdateBtnStates; -end; - -procedure TRaschFrm.OutBtnClick(Sender: TObject); -var - i: integer; -begin - i := 0; - while i < ItemList.Items.Count do - begin - if ItemList.Selected[i] then - begin - VarList.Items.Add(ItemList.Items[i]); - ItemList.Items.Delete(i); - i := 0; - end else - i := i + 1; - end; - UpdateBtnStates; -end; - -procedure TRaschFrm.Analyze(const itemfail, grpfail: IntDyneVec; - const f: IntDyneMat; var T: integer; const grppass, itempass: IntDyneVec; - r, C1: integer; out min, max: double; const p2: DblDyneVec); -var - i, j: integer; -begin - for i := 0 to r-1 do itemfail[i] := 0; - for j := 0 to C1-1 do grpfail[j] := 0; - for i := 0 to r-1 do - begin - for j := 0 to C1-1 do - begin - grpfail[j] := grpfail[j] + f[i,j]; - itemfail[i] := itemfail[i] + f[i,j]; - end; - end; - T := 0; - for j := 0 to C1-1 do T := T + grpfail[j]; - for j := 0 to C1-1 do grppass[j] := T - grpfail[j]; - for i := 0 to r-1 do itempass[i] := T - itemfail[i]; - min := p2[0]; - max := p2[0]; - for i := 0 to C1-1 do - begin - if (p2[i] < min) then min := p2[i]; - if (p2[i] > max) then max := p2[i]; + finally + lReport.Free; end; end; -procedure TRaschFrm.Expand(v1, v2: double; out xExpand, yExpand: Double); + +procedure TRaschForm.Expand(v1, v2: double; out xExpand, yExpand: Double); begin yExpand := sqrt( (1.0 + (v2 / 2.89)) / (1.0 - (v1 * v2 / 8.35)) ); xExpand := sqrt( (1.0 + (v1 / 2.89)) / (1.0 - (v1 * v2 / 8.35)) ); end; -procedure TRaschFrm.FinishIt(r: integer; const i5: IntDyneVec; + +procedure TRaschForm.FinishIt(r: integer; const i5: IntDyneVec; const rptbis, rbis, slope, mean: DblDyneVec; const itemfail: IntDyneVec; const P: DblDyneVec; AReport: TStrings); var @@ -415,7 +353,8 @@ begin AReport.Add(''); end; -procedure TRaschFrm.Frequencies(C1, r: integer; + +procedure TRaschForm.Frequencies(C1, r: integer; const f: IntDyneMat; const rowtot, i5, s5: IntDyneVec; T: integer; const S: IntDyneVec; AReport: TStrings); var @@ -466,7 +405,8 @@ begin end; // end while not done end; // end sub frequencies -procedure TRaschFrm.GetLogs(const L, L1,L2, g, g2, f2: DblDyneVec; + +procedure TRaschForm.GetLogs(const L, L1,L2, g, g2, f2: DblDyneVec; const rowtot: IntDyneVec; k : integer; const s5, S: IntDyneVec; T, r, C1 : integer; var v1, v2: Double; AReport: TStrings); var @@ -520,7 +460,8 @@ begin AReport.Add(''); end; -procedure TRaschFrm.GetScores(NoSelected: integer; const Selected: IntDyneVec; + +procedure TRaschForm.GetScores(NoSelected: integer; const Selected: IntDyneVec; NoCases: integer; const f: IntDyneMat; const Mean, XSqr, SumXY: DblDyneVec; const S, X: IntDyneVec; out sumx, sumx2: double; var N: integer; AReport: TStrings); @@ -551,14 +492,14 @@ begin // that have a total score of zero or all items correct for i := 1 to NoCases do begin - if not GoodRecord(i, NoSelected, Selected) then + if not GoodRecord(OS3MainFrm.DataGrid, i, Selected) then continue; T := 0; for j := 1 to k1 do begin item := Selected[j-1]; - X[j-1] := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[item,i]))); + X[j-1] := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[item, i]))); T := T + X[j-1]; end; @@ -586,7 +527,27 @@ begin AReport.Add(''); end; -procedure TRaschFrm.Maxability(const expdcnt, d2, e2: DblDyneVec; + +procedure TRaschForm.InBtnClick(Sender: TObject); +var + i: integer; +begin + i := 0; + while i < VarList.Items.Count do + begin + if VarList.Selected[i] then + begin + ItemList.Items.Add(VarList.Items[i]); + VarList.Items.Delete(i); + i := 0; + end else + i := i + 1; + end; + UpdateBtnStates; +end; + + +procedure TRaschForm.Maxability(const expdcnt, d2, e2: DblDyneVec; const p1: DblDyneMat; const p2, P: DblDyneVec; C1, r: integer; const D: DblDyneMat; const s5: IntDyneVec; noloops: integer; AReport: TStrings); var @@ -629,7 +590,8 @@ begin } end; // end of maxability -function TRaschFrm.MaxItem(const R1, d1: DblDyneVec; const p1, D: DblDyneMat; + +function TRaschForm.MaxItem(const R1, d1: DblDyneVec; const p1, D: DblDyneMat; const e1, p2, P: DblDyneVec; const S, rowtot: IntDyneVec; T, r, C1: integer): double; var @@ -682,7 +644,7 @@ begin Result := d9; end; -procedure TRaschFrm.MAXOUT(r, C1: integer; const i5, s5: IntDyneVec; +procedure TRaschForm.MAXOUT(r, C1: integer; const i5, s5: IntDyneVec; const P, p2: DblDyneVec; AReport: TStrings); var i, j: integer; @@ -705,7 +667,172 @@ begin AReport.Add(' %3d %6.2f', [s5[j], p2[j]]); end; -procedure TRaschFrm.Prox(const P, p2: DblDyneVec; k, r, C1 : integer; + +procedure TRaschForm.OutBtnClick(Sender: TObject); +var + i: integer; +begin + i := 0; + while i < ItemList.Items.Count do + begin + if ItemList.Selected[i] then + begin + VarList.Items.Add(ItemList.Items[i]); + ItemList.Items.Delete(i); + i := 0; + end else + i := i + 1; + end; + UpdateBtnStates; +end; + + +procedure TRaschForm.Plot(const xyArray: DblDyneMat; Arraysize: integer); +var + ser: TChartSeries; + i: integer; +begin + ser := FItemFuncsChartFrame.PlotXY(ptLines, nil, nil, nil, nil, '', DATA_COLORS[0]); + for i := 0 to ArraySize-1 do + ser.AddXY(xyArray[i, 0], xyArray[i, 1]); + ser.Active := false; +end; + + +procedure TRaschForm.PlotInfo(r: integer; const Info, A: DblDyneMat; + const Slope, P: DblDyneVec); +const + MIN = -3.5; + MAX = +3.5; +var + cg, hincrement, Ymax, elg, term1, term2, jx: double; + i, j, jj, size: integer; + TestInfo: DblDyneMat = nil; +begin + // Prepare charts + FChartCombobox.Items.Clear; + FItemFuncsChartFrame.Clear; + FItemFuncsChartFrame.SetXTitle('log ability'); + FItemFuncsChartFrame.SetYTitle('Info'); + + size := 0; + hIncrement := (MAX - MIN) / 50; + + SetLength(TestInfo, 52,2); + cg := 0.2; + Ymax := 0; + for i := 1 to r do // item loop + begin + TestInfo[i-1, 0] := 0.0; + TestInfo[i-1, 1] := 0.0; + jj := 1; + jx := MIN; + while (jx <= MAX + hIncrement) do + begin + if (slope[i-1] > 30) then slope[i-1] := 30; + elg := 1.7 * slope[i-1] * (P[i-1] - jx); + elg := exp(elg); + term1 := 2.89 * sqr(slope[i-1] * (1.0 - cg)); + term2 := (cg + elg) * sqr(1.0 + 1.0 / elg); + info[i-1, jj-1] := term1 / term2; + if (info[i-1, jj-1] > Ymax) then + Ymax := info[i-1, jj-1]; + jj := jj + 1; + jx := jx + hIncrement; + end; + size := jj-1; + end; + + // Item loop + for i := 0 to r-1 do + begin + for j := 0 to size-1 do + begin + A[j, 0] := MIN + (hIncrement * (j+1)); + A[j, 1] := info[i, j]; + TestInfo[j, 1] := TestInfo[j, 1] + info[i, j]; + end; + if ItemFuncsChk.Checked then + begin + FChartCombobox.Items.Add(Format('Item %d', [i+1])); + Plot(A, size); + end; + end; + + for j := 0 to size-1 do + TestInfo[j, 0] := MIN + hIncrement * (j+1); + + if TestInfoChk.Checked then + PlotTest(TestInfo, size, 'Item Information Function for Test'); + + FChartCombobox.ItemIndex := 0; + SelectItemFuncsPlot(FChartCombobox); + FItemFuncsChartFrame.Chart.Legend.Visible := false; +end; + + +procedure TRaschForm.PlotItems(r: integer; const i5: IntDyneVec; + const P: DblDyneVec); +var + i: integer; + ser: TChartSeries; +begin + FItemDiffsChartFrame.Clear; + FItemDiffsChartFrame.SetTitle('LOG DIFFICULTIES FOR ITEMS'); + FItemDiffsChartFrame.SetXTitle('Item'); + FItemDiffsChartFrame.SetYTitle('Log Difficulty'); + FItemDiffsChartFrame.HorLine(0, clBlack, psSolid, ''); + + ser := FItemDiffsChartFrame.PlotXY(ptBars, nil, nil, nil, nil, '', DATA_COLORS[0]); + for i := 0 to r-1 do + ser.AddXY(i5[i], P[i], '', DATA_COLORS[i mod Length(DATA_COLORS)]); + + FItemDiffsChartFrame.Chart.BottomAxis.Marks.Source := ser.Source; + FItemDiffsChartFrame.Chart.BottomAxis.Marks.Style := smsXValue; + FItemDiffsChartFrame.Chart.Legend.Visible := false; +end; + + +procedure TRaschForm.PlotScrs(C1: integer; const s5: IntDyneVec; const + p2: DblDyneVec); +var + i: integer; + ser: TChartSeries; +begin + FScoresChartFrame.Clear; + FScoresChartFrame.SetTitle('LOG ABILITIES FOR SCORE GROUPS'); + FScoresChartFrame.SetXTitle('Score'); + FScoresChartFrame.SetYTitle('Log Ability'); + FScoresChartFrame.HorLine(0, clBlack, psSolid, ''); + ser := FScoresChartFrame.PlotXY(ptBars, nil, nil, nil, nil, '', DATA_COLORS[0]); + for i := 0 to C1-1 do + ser.AddXY(s5[i], p2[i], '', DATA_COLORS[i mod Length(DATA_COLORS)]); + FScoresChartFrame.Chart.BottomAxis.Marks.Source := ser.Source; + FScoresChartFrame.Chart.BottomAxis.Marks.Style := smsXValue; + FScoresChartFrame.Chart.Legend.Visible := false; +end; + + +procedure TRaschForm.PlotTest(const TestInfo: DblDyneMat; + ArraySize: integer; const Title: string{; Vdivisions, Hdivisions: integer}); +var + i: integer; + ser: TChartSeries; +begin + FTestInfoChartFrame.Clear; + FTestInfoChartFrame.SetTitle(Title); + FTestInfoChartFrame.SetXTitle('log ability'); + FTestInfoChartFrame.SetYTitle('Info'); + + ser := FTestInfoChartFrame.PlotXY(ptLines, nil, nil, nil, nil, '', DATA_COLORS[0]); + for i := 0 to ArraySize-1 do + ser.AddXY(TestInfo[i, 0], TestInfo[i, 1]); + + FTestInfoChartFrame.Chart.Legend.Visible := false; +end; + + +procedure TRaschForm.Prox(const P, p2: DblDyneVec; k, r, C1 : integer; const L1: DblDyneVec; yexpand, xexpand: double; const g: DblDyneVec; T: integer; const rowtot, i5, s5: IntDyneVec; AReport: TStrings); var @@ -749,7 +876,8 @@ begin AReport.Add(''); end; -Function TRaschFrm.Reduce(k: integer; out r, T, C1: Integer; + +function TRaschForm.Reduce(k: integer; out r, T, C1: Integer; const i5, RowTot, s5: IntDyneVec; const f: IntDyneMat; const S: IntDyneVec; AReport: TStrings): integer; var @@ -836,7 +964,7 @@ begin if C1 = 0 then begin MessageDlg('Too many cases or variables eliminated', mtError, [mbOK], 0); - DisplayReport(AReport); + FReportFrame.DisplayReport(AReport); AReport.clear; Result := 1; exit; @@ -853,7 +981,7 @@ begin if C1 = 0 then begin MessageDlg('Too many cases or variables eliminated', mtError, [mbOK], 0); - DisplayReport(AReport); + FReportFrame.DisplayReport(AReport); AReport.Clear; Result := 1; exit; @@ -868,7 +996,45 @@ begin Result := 0; end; // end of reduce -procedure TRaschFrm.Slopes(const rptbis, rbis, slope: DblDyneVec; + +procedure TRaschForm.Reset; +var + i: integer; +begin + inherited; + + if FItemDiffsChartFrame <> nil then FItemDiffsChartFrame.Clear; + if FScoresChartFrame <> nil then FScoresChartFrame.Clear; + if FItemFuncsChartFrame <> nil then FItemFuncsChartFrame.Clear; + if FTestInfoChartFrame <> nil then FTestInfoChartFrame.Clear; + + VarList.Clear; + for i := 1 to NoVariables do + VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); + ItemList.Clear; + + ProxChk.Checked := false; + PlotItemDiffChk.Checked := false; + PlotScrsChk.Checked := false; + ItemFuncsChk.Checked := false; + TestInfoChk.Checked := false; + + UpdateBtnStates; +end; + + +procedure TRaschForm.SelectItemFuncsPlot(Sender: TObject); +var + i, index: Integer; +begin + index := FChartCombobox.ItemIndex; + for i := 0 to FItemFuncsChartFrame.Chart.SeriesCount-1 do + FItemFuncsChartFrame.Chart.Series[i].Active := (i = index); + FItemFuncsChartFrame.SetTitle(Format('Item Information Function for Item %d', [index+1])); +end; + + +procedure TRaschForm.Slopes(const rptbis, rbis, slope: DblDyneVec; N: integer; sumx, sumx2: double; const sumxy: DblDyneVec; r: integer; const xsqr, mean: DblDyneVec); var @@ -907,7 +1073,8 @@ begin end; end; // end of slopes procedure -procedure TRaschFrm.TestFit(r, C1: integer; const f: IntDyneMat; + +procedure TRaschForm.TestFit(r, C1: integer; const f: IntDyneMat; const S: IntDyneVec; const P, P2: DblDyneVec; T: integer; AReport: TStrings); var ct, ch, prob: double; @@ -935,253 +1102,41 @@ begin AReport.Add(''); end; -procedure TRaschFrm.PlotInfo(k, r : integer; const Info, A: DblDyneMat; - const Slope, P: DblDyneVec); -var - min, max, cg, hincrement, Ymax, elg, term1, term2, jx : double; - headstring, valstring : string; - i, j, jj, size : integer; - TestInfo: DblDyneMat; + +procedure TRaschForm.UpdateBtnStates; begin - min := -3.5; - max := 3.5; - size := 0; - hincrement := (max - min) / 50; - SetLength(TestInfo, 52,2); - cg := 0.2; - Ymax := 0; - for i := 1 to r do // item loop - begin - TestInfo[i-1,0] := 0.0; - TestInfo[i-1,1] := 0.0; - jj := 1; - jx := min; - while (jx <= (max + hincrement)) do - begin - if (slope[i-1] > 30) then slope[i-1] := 30; - elg := 1.7 * slope[i-1] * (P[i-1] - jx); - elg := exp(elg); - term1 := 2.89 * (slope[i-1]) * (1.0 - cg) * (slope[i-1]) * (1.0 - cg); - term2 := (cg + elg) * (1.0 + 1.0 / elg) * (1.0 + 1.0 / elg); - info[i-1,jj-1] := term1 / term2; - if (info[i-1,jj-1] > Ymax) then Ymax := info[i-1,jj-1]; - jj := jj + 1; - jx := jx + hincrement; - end; - size := jj-1; - end; - for i := 1 to r do //item loop - begin - headstring := 'Item Information Function for Item '; - valstring := format('%3d',[i]); - headstring := headstring + valstring; - for j := 1 to size do - begin - A[j-1,0] := min + (hincrement * j ); - A[j-1,1] := info[i-1,j-1]; - TestInfo[j-1,1] := TestInfo[j-1,1] + info[i-1,j-1]; - end; - if ItemInfoChk.Checked then plot(A, size, headstring, 50, 50); - end; - for j := 1 to size do TestInfo[j-1,0] := min + (hincrement * j ); + inherited; - headstring := 'Item Information Function for Test'; - PlotTest(TestInfo,size,headstring,50,50); + if FItemDiffsChartFrame <> nil then FItemDiffsChartFrame.UpdateBtnStates; + if FScoresChartFrame <> nil then FScoresChartFrame.UpdateBtnStates; + if FItemFuncsChartFrame <> nil then FItemFuncsChartFrame.UpdateBtnStates; + if FTestInfoChartFrame <> nil then FTestInfoChartFrame.UpdateBtnStates; - TestInfo := nil; -end; //end of PlotInfo - -procedure TRaschFrm.Plot(const xyArray: DblDyneMat; Arraysize: integer; - const Title: string; Vdivisions, Hdivisions: integer); -var - i : integer; - //xvalue, yvalue : DblDyneVec; -begin - // Allocate space for point sets of means - //SetLength(xvalue,arraysize); - //SetLength(yvalue,arraysize); - SetLength(GraphFrm.Ypoints, 1, ArraySize); - SetLength(GraphFrm.Xpoints, 1, ArraySize); - - // store points for means - for i := 0 to ArraySize-1 do - begin - GraphFrm.XPoints[0, i] := xyArray[i, 0]; - GraphFrm.YPoints[0, i] := xyArray[i, 1]; - { - yvalue[i] := xyarray[i,1]; - xvalue[i] := xyarray[i,0]; - GraphFrm.Ypoints[0,i] := yvalue[i]; - GraphFrm.Xpoints[0,i] := xvalue[i]; - } - end; - GraphFrm.nosets := 1; - GraphFrm.nbars := arraysize; - GraphFrm.Heading := Title; - GraphFrm.XTitle := 'log ability'; - GraphFrm.YTitle := 'Info'; -// GraphFrm.Ypoints[1] := yvalue; -// GraphFrm.Xpoints[1] := xvalue; - GraphFrm.barwideprop := 0.5; - GraphFrm.AutoScaled := true; - GraphFrm.GraphType := 5; // 2d line chart - GraphFrm.BackColor := GRAPH_BACK_COLOR; - GraphFrm.WallColor := GRAPH_WALL_COLOR; - GraphFrm.FloorColor := GRAPH_FLOOR_COLOR; - GraphFrm.ShowBackWall := true; - GraphFrm.ShowModal; - -// xvalue := nil; -// yvalue := nil; - GraphFrm.Xpoints := nil; - GraphFrm.Ypoints := nil; -end; //end plot subroutine - -procedure TRaschFrm.PlotItems(r: integer; const i5: IntDyneVec; - const P: DblDyneVec); -var - i : integer; -// xvalues : DblDyneVec; -begin -// SetLength(xvalues,r); - SetLength(GraphFrm.Ypoints,1,r); - SetLength(GraphFrm.Xpoints,1,r); - for i := 0 to r-1 do - begin - GraphFrm.XPoints[0, i] := i5[i]; - GraphFrm.YPoints[0, i] := P[i]; - end; - { - for i := 1 to r do - begin - xvalues[i-1] := i5[i-1]; - GraphFrm.Xpoints[0,i-1] := xvalues[i-1]; - GraphFrm.Ypoints[0,i-1] := P[i-1]; - end; - } - GraphFrm.nosets := 1; - GraphFrm.nbars := r; - GraphFrm.Heading := 'LOG DIFFICULTIES FOR ITEMS'; - GraphFrm.XTitle := 'ITEM'; - GraphFrm.YTitle := 'LOG DIFFICULTY'; - GraphFrm.barwideprop := 0.5; - GraphFrm.AutoScaled := true; - GraphFrm.GraphType := 2; // bar chart - GraphFrm.BackColor := GRAPH_BACK_COLOR; - GraphFrm.WallColor := GRAPH_WALL_COLOR; - GraphFrm.FloorColor := GRAPH_FLOOR_COLOR; - GraphFrm.ShowBackWall := true; - GraphFrm.ShowModal; - - //xvalues := nil; - GraphFrm.Xpoints := nil; - GraphFrm.Ypoints := nil; -end; - -procedure TRaschFrm.PlotScrs(C1: integer; const s5: IntDyneVec; const - p2: DblDyneVec); -var - i: integer; - //xvalues: DblDyneVec; -begin - //SetLength(xvalues,C1); - SetLength(GraphFrm.Ypoints,1,C1); - SetLength(GraphFrm.Xpoints,1,C1); - for i := 0 to C1-1 do - begin - GraphFrm.XPoints[0, i] := s5[i]; - GraphFrm.YPoints[0, i] := p2[i]; - end; - { - for i := 1 to C1 do - begin - xvalues[i-1] := s5[i-1]; - GraphFrm.Xpoints[0,i-1] := xvalues[i-1]; - GraphFrm.Ypoints[0,i-1] := p2[i-1]; - end; - } - GraphFrm.nosets := 1; - GraphFrm.nbars := C1; - GraphFrm.Heading := 'LOG ABILITIES FOR SCORE GROUPS'; - GraphFrm.XTitle := 'SCORE'; - GraphFrm.YTitle := 'LOG ABILITY'; -// GraphFrm.Ypoints[1] := p2; -// GraphFrm.Xpoints[1] := xvalues; - GraphFrm.barwideprop := 0.5; - GraphFrm.AutoScaled := true; - GraphFrm.GraphType := 2; // bar chart - GraphFrm.BackColor := GRAPH_BACK_COLOR; - GraphFrm.WallColor := GRAPH_WALL_COLOR; - GraphFrm.FloorColor := GRAPH_FLOOR_COLOR; - GraphFrm.ShowBackWall := true; - GraphFrm.ShowModal; - - //xvalues := nil; - GraphFrm.Xpoints := nil; - GraphFrm.Ypoints := nil; -end; - -procedure TRaschFrm.PlotTest(const TestInfo: DblDyneMat; - ArraySize: integer; const Title: string; Vdivisions, Hdivisions: integer); -var - i: integer; -// xvalue, yvalue: DblDyneVec; -begin - // Allocate space for point sets of means - //SetLength(xvalue,arraysize); - //SetLength(yvalue,arraysize); - SetLength(GraphFrm.Ypoints, 1, Arraysize); - SetLength(GraphFrm.Xpoints, 1, Arraysize); - - // store points for means - for i := 0 to ArraySize-1 do - begin - GraphFrm.XPoints[0, i] := TestInfo[i, 0]; - GraphFrm.YPoints[0, i] := TestInfo[i, 1]; - end; - { - for i := 1 to arraysize do - begin - yvalue[i-1] := TestInfo[i-1,1]; - xvalue[i-1] := TestInfo[i-1,0]; - GraphFrm.Ypoints[0,i-1] := yvalue[i-1]; - GraphFrm.Xpoints[0,i-1] := xvalue[i-1]; - end; - } - GraphFrm.nosets := 1; - GraphFrm.nbars := arraysize; - GraphFrm.Heading := Title; - GraphFrm.XTitle := 'log ability'; - GraphFrm.YTitle := 'Info'; - GraphFrm.barwideprop := 0.5; - GraphFrm.AutoScaled := true; - GraphFrm.GraphType := 5; // 2d line chart - GraphFrm.BackColor := GRAPH_BACK_COLOR; - GraphFrm.WallColor := GRAPH_WALL_COLOR; - GraphFrm.FloorColor := GRAPH_FLOOR_COLOR; - GraphFrm.ShowBackWall := true; - GraphFrm.ShowModal; - - //xvalue := nil; - //yvalue := nil; - GraphFrm.Xpoints := nil; - GraphFrm.Ypoints := nil; -end; //end plot subroutine - -procedure TRaschFrm.UpdateBtnStates; -begin InBtn.Enabled := AnySelected(VarList); OutBtn.Enabled := AnySelected(ItemList); end; -procedure TRaschFrm.VarListSelectionChange(Sender: TObject; User: boolean); + +function TRaschForm.Validate(out AMsg: String; out AControl: TWinControl): Boolean; +begin + Result := false; + + if (NoVariables < 1) then + begin + AMsg := 'You must have data in your data grid.'; + AControl := VarList; + exit; + end; + + Result := True; +end; + + +procedure TRaschForm.VarListSelectionChange(Sender: TObject; User: boolean); begin UpdateBtnStates; end; -initialization - {$I raschunit.lrs} - end. diff --git a/applications/lazstats/source/forms/mainunit.pas b/applications/lazstats/source/forms/mainunit.pas index ba8b331ae..aaf54d447 100644 --- a/applications/lazstats/source/forms/mainunit.pas +++ b/applications/lazstats/source/forms/mainunit.pas @@ -776,9 +776,9 @@ end; // Menu "Analysis" > "Measurement Programs" > "Rasch Test Calibration" procedure TOS3MainFrm.mnuAnalysisMeas_RashClick(Sender: TObject); begin - if RaschFrm = nil then - Application.CreateForm(TRaschFrm, RaschFrm); - RaschFrm.ShowModal; + if RaschForm = nil then + Application.CreateForm(TRaschForm, RaschForm); + RaschForm.Show; end; // Menu "Analysis" > "Measurement Programs" > "Successive Interval Scaling" @@ -786,7 +786,7 @@ procedure TOS3MainFrm.mnuAnalysisMeas_IntervalClick(Sender: TObject); begin if SuccIntFrm = nil then Application.CreateForm(TSuccIntFrm, SuccIntFrm); - SuccIntFrm.ShowModal; + SuccIntFrm.Show; end; // Menu "Analysis" > "Measurement Programs" > "Guttman Scalogram Analysis