diff --git a/applications/lazstats/source/LazStats.lpi b/applications/lazstats/source/LazStats.lpi
index c97b8fb83..484a66c44 100644
--- a/applications/lazstats/source/LazStats.lpi
+++ b/applications/lazstats/source/LazStats.lpi
@@ -49,7 +49,7 @@
-
+
@@ -744,12 +744,11 @@
-
+
-
@@ -1421,6 +1420,14 @@
+
+
+
+
+
+
+
+
diff --git a/applications/lazstats/source/LazStats.lpr b/applications/lazstats/source/LazStats.lpr
index 69c2a28dc..28053d22e 100644
--- a/applications/lazstats/source/LazStats.lpr
+++ b/applications/lazstats/source/LazStats.lpr
@@ -8,7 +8,8 @@ uses
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, tachartlazaruspkg, tachartprint, lhelpcontrolpkg,
- Globals, LicenseUnit, OptionsUnit, DictionaryUnit, MainDM, MainUnit;
+ Globals, LicenseUnit, OptionsUnit, DictionaryUnit, MainDM, MainUnit,
+cumsumunit;
{$R LazStats.res}
@@ -28,6 +29,7 @@ begin
end;
Application.CreateForm(TMainDataModule, MainDataModule);
Application.CreateForm(TOS3MainFrm, OS3MainFrm);
+ Application.CreateForm(TCUSUMChartForm, CUSUMChartForm);
Application.Run;
end.
diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.pas b/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.pas
index 44d7f38b8..1be1af2df 100644
--- a/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.pas
+++ b/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.pas
@@ -56,7 +56,7 @@ type
function GetFileName: String;
procedure PlotMeans(ATitle, AXTitle, AYTitle, ADataTitle, AGrandMeanTitle: String;
const Groups: StrDyneVec; const Means: DblDyneVec;
- UCL, LCL, GrandMean, TargetSpec, LowerSpec, UpperSpec: double);
+ UCL, LCL, GrandMean, TargetSpec, LowerSpec, UpperSpec: double); virtual;
procedure Reset; virtual;
procedure Compute; virtual;
function Validate(out AMsg: String; out AControl: TWinControl): Boolean; virtual;
@@ -243,14 +243,23 @@ begin
FChartFrame.Chart.BottomAxis.Marks.style := smsLabel;
end;
- FChartFrame.HorLine(GrandMean, clRed, psSolid, AGrandMeanTitle);
- rightLabels.Add(GrandMean, GrandMean, AGrandMeanTitle);
+ if not IsNaN(GrandMean) then
+ begin
+ FChartFrame.HorLine(GrandMean, clRed, psSolid, AGrandMeanTitle);
+ rightLabels.Add(GrandMean, GrandMean, AGrandMeanTitle);
+ end;
- FChartFrame.HorLine(UCL, CL_COLOR, CL_STYLE, 'UCL/LCL');
- rightLabels.Add(UCL, UCL, 'UCL');
+ if not IsNaN(UCL) then
+ begin
+ FChartFrame.HorLine(UCL, CL_COLOR, CL_STYLE, 'UCL/LCL');
+ rightLabels.Add(UCL, UCL, 'UCL');
+ end;
- FChartFrame.HorLine(LCL, CL_COLOR, CL_STYLE, '');
- rightLabels.Add(UCL, LCL, 'LCL');
+ if not IsNaN(LCL) then
+ begin
+ FChartFrame.HorLine(LCL, CL_COLOR, CL_STYLE, '');
+ rightLabels.Add(UCL, LCL, 'LCL');
+ end;
if not IsNan(UpperSpec) then
begin
diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/cumsumunit.lfm b/applications/lazstats/source/forms/analysis/statistical_process_control/cumsumunit.lfm
index d65cdd07b..7d037ee84 100644
--- a/applications/lazstats/source/forms/analysis/statistical_process_control/cumsumunit.lfm
+++ b/applications/lazstats/source/forms/analysis/statistical_process_control/cumsumunit.lfm
@@ -1,354 +1,234 @@
-object CUMSUMFrm: TCUMSUMFrm
- Left = 717
- Height = 346
- Top = 262
- Width = 476
+inherited CUSUMChartForm: TCUSUMChartForm
HelpType = htKeyword
HelpKeyword = 'html/CUMSUMChart.htm'
- AutoSize = True
- Caption = 'CUMSUM Chart'
- ClientHeight = 346
- ClientWidth = 476
+ Caption = 'Cumulative Sum Control Chart'
OnActivate = FormActivate
- OnCreate = FormCreate
- OnShow = FormShow
- Position = poMainFormCenter
- LCLVersion = '2.1.0.0'
- object Label1: TLabel
- AnchorSideLeft.Control = Owner
- AnchorSideTop.Control = Owner
- Left = 8
- Height = 15
- Top = 8
- Width = 97
- BorderSpacing.Left = 8
- BorderSpacing.Top = 8
- Caption = 'Selection Variables'
- ParentColor = False
- end
- object Label2: TLabel
- AnchorSideLeft.Control = GroupEdit
- AnchorSideTop.Control = Owner
- Left = 242
- Height = 15
- Top = 8
- Width = 77
- BorderSpacing.Top = 8
- Caption = 'Group Variable'
- ParentColor = False
- end
- object Label3: TLabel
- AnchorSideLeft.Control = MeasEdit
- AnchorSideTop.Control = GroupEdit
- AnchorSideTop.Side = asrBottom
- Left = 242
- Height = 15
- Top = 64
- Width = 117
- BorderSpacing.Top = 16
- Caption = 'Measurement Variable'
- ParentColor = False
- end
- object VarList: TListBox
- AnchorSideLeft.Control = Owner
- AnchorSideTop.Control = Label1
- AnchorSideTop.Side = asrBottom
- AnchorSideRight.Control = GroupBox2
- AnchorSideBottom.Control = Bevel2
- Left = 8
- Height = 272
- Top = 25
- Width = 226
- Anchors = [akTop, akLeft, akRight, akBottom]
- BorderSpacing.Left = 8
- BorderSpacing.Top = 2
- BorderSpacing.Right = 8
- ItemHeight = 0
- OnClick = VarListClick
- TabOrder = 0
- end
- object GroupEdit: TEdit
- AnchorSideLeft.Control = GroupBox2
- AnchorSideTop.Control = Label2
- AnchorSideTop.Side = asrBottom
- AnchorSideRight.Control = Owner
- AnchorSideRight.Side = asrBottom
- Left = 242
- Height = 23
- Top = 25
- Width = 226
- Anchors = [akTop, akLeft, akRight]
- BorderSpacing.Top = 2
- BorderSpacing.Right = 8
- ReadOnly = True
- TabOrder = 1
- Text = 'GroupEdit'
- end
- object MeasEdit: TEdit
- AnchorSideLeft.Control = GroupBox2
- AnchorSideTop.Control = Label3
- AnchorSideTop.Side = asrBottom
- AnchorSideRight.Control = Owner
- AnchorSideRight.Side = asrBottom
- Left = 242
- Height = 23
- Top = 81
- Width = 226
- Anchors = [akTop, akLeft, akRight]
- BorderSpacing.Top = 2
- BorderSpacing.Right = 8
- ReadOnly = True
- TabOrder = 2
- Text = 'MeasEdit'
- end
- object GroupBox1: TGroupBox
- AnchorSideLeft.Control = GroupBox2
- AnchorSideTop.Control = MeasEdit
- AnchorSideTop.Side = asrBottom
- AnchorSideRight.Control = Owner
- AnchorSideRight.Side = asrBottom
- Left = 242
- Height = 107
- Top = 120
- Width = 226
- Anchors = [akTop, akLeft, akRight]
- BorderSpacing.Top = 16
- BorderSpacing.Right = 8
- Caption = 'CUMSUM V-Mask Specifications'
- ClientHeight = 87
- ClientWidth = 222
- TabOrder = 3
- object Label4: TLabel
- AnchorSideLeft.Control = GroupBox1
- AnchorSideTop.Control = DeltaEdit
- AnchorSideTop.Side = asrCenter
- Left = 12
- Height = 15
- Top = 6
- Width = 94
- BorderSpacing.Left = 12
- Caption = 'Delta (Effect Size):'
- ParentColor = False
+ inherited SpecsPanel: TPanel
+ Width = 432
+ ClientWidth = 432
+ inherited ButtonPanel: TPanel
+ Width = 432
+ ClientWidth = 432
+ TabOrder = 5
+ inherited CloseBtn: TButton
+ Left = 377
+ TabOrder = 3
+ end
+ inherited ComputeBtn: TButton
+ Left = 293
+ TabOrder = 2
+ end
+ inherited ResetBtn: TButton
+ Left = 231
+ TabOrder = 1
+ end
+ inherited HelpBtn: TButton
+ Left = 180
+ TabOrder = 0
+ end
+ inherited Bevel1: TBevel
+ Width = 424
+ end
end
- object Label5: TLabel
- AnchorSideLeft.Control = GroupBox1
- AnchorSideTop.Control = AlphaEdit
- AnchorSideTop.Side = asrCenter
- Left = 12
- Height = 15
- Top = 33
- Width = 94
- BorderSpacing.Left = 12
- Caption = 'Alpha Probability:'
- ParentColor = False
- end
- object Label6: TLabel
- AnchorSideLeft.Control = GroupBox1
- AnchorSideTop.Control = BetaEdit
- AnchorSideTop.Side = asrCenter
- Left = 12
- Height = 15
- Top = 60
- Width = 86
- BorderSpacing.Left = 12
- Caption = 'Beta Probability:'
- ParentColor = False
- end
- object DeltaEdit: TEdit
- AnchorSideLeft.Control = AlphaEdit
- AnchorSideTop.Control = GroupBox1
- AnchorSideRight.Control = GroupBox1
- AnchorSideRight.Side = asrBottom
- Left = 114
- Height = 23
- Top = 2
- Width = 100
- Alignment = taRightJustify
- Anchors = [akTop, akLeft, akRight]
- BorderSpacing.Top = 2
- BorderSpacing.Right = 8
- TabOrder = 0
- Text = 'DeltaEdit'
- end
- object AlphaEdit: TEdit
- AnchorSideLeft.Control = Label5
- AnchorSideLeft.Side = asrBottom
- AnchorSideTop.Control = DeltaEdit
- AnchorSideTop.Side = asrBottom
- AnchorSideRight.Control = GroupBox1
- AnchorSideRight.Side = asrBottom
- Left = 114
- Height = 23
- Top = 29
- Width = 100
- Alignment = taRightJustify
- Anchors = [akTop, akLeft, akRight]
- BorderSpacing.Left = 8
- BorderSpacing.Top = 4
- BorderSpacing.Right = 8
- TabOrder = 1
- Text = 'AlphaEdit'
- end
- object BetaEdit: TEdit
- AnchorSideLeft.Control = AlphaEdit
- AnchorSideTop.Control = AlphaEdit
- AnchorSideTop.Side = asrBottom
- AnchorSideRight.Control = GroupBox1
- AnchorSideRight.Side = asrBottom
- Left = 114
- Height = 23
- Top = 56
- Width = 100
- Alignment = taRightJustify
- Anchors = [akTop, akLeft, akRight]
- BorderSpacing.Top = 4
- BorderSpacing.Right = 8
- BorderSpacing.Bottom = 8
- TabOrder = 2
- Text = 'BetaEdit'
- end
- end
- object GroupBox2: TGroupBox
- AnchorSideTop.Control = GroupBox1
- AnchorSideTop.Side = asrBottom
- AnchorSideRight.Control = Owner
- AnchorSideRight.Side = asrBottom
- Left = 242
- Height = 51
- Top = 243
- Width = 226
- Anchors = [akTop, akRight]
- AutoSize = True
- BorderSpacing.Top = 16
- BorderSpacing.Right = 8
- Caption = 'Option:'
- ClientHeight = 31
- ClientWidth = 222
- TabOrder = 4
- object TargetChk: TCheckBox
- AnchorSideLeft.Control = GroupBox2
- AnchorSideTop.Control = TargetEdit
- AnchorSideTop.Side = asrCenter
- Left = 12
- Height = 19
- Top = 2
- Width = 141
- AutoSize = False
- BorderSpacing.Left = 12
- BorderSpacing.Right = 12
- Caption = 'Use Target Specification:'
+ inherited VarList: TListBox
+ Width = 212
TabOrder = 0
end
- object TargetEdit: TEdit
- AnchorSideLeft.Control = TargetChk
- AnchorSideLeft.Side = asrBottom
- AnchorSideTop.Control = GroupBox2
- AnchorSideRight.Side = asrBottom
- Left = 165
- Height = 23
- Top = 0
- Width = 49
- Alignment = taRightJustify
- BorderSpacing.Left = 12
- BorderSpacing.Right = 8
- BorderSpacing.Bottom = 8
- TabOrder = 1
- Text = 'TargetEdit'
+ inherited GroupLabel: TLabel
+ Left = 228
end
- end
- object Bevel2: TBevel
- AnchorSideTop.Control = Panel1
- AnchorSideRight.Control = Owner
- AnchorSideRight.Side = asrBottom
- AnchorSideBottom.Control = Panel1
- Left = 0
- Height = 8
- Top = 297
- Width = 476
- Anchors = [akLeft, akRight, akBottom]
- Shape = bsBottomLine
- end
- object Panel1: TPanel
- Left = 0
- Height = 41
- Top = 305
- Width = 476
- Align = alBottom
- AutoSize = True
- BevelOuter = bvNone
- ClientHeight = 41
- ClientWidth = 476
- TabOrder = 5
- object ResetBtn: TButton
- AnchorSideLeft.Control = Panel1
- AnchorSideTop.Control = Panel1
- AnchorSideRight.Control = ComputeBtn
- Left = 267
- Height = 25
- Top = 8
- Width = 54
- Anchors = [akTop, akRight]
- AutoSize = True
- BorderSpacing.Top = 8
- BorderSpacing.Right = 8
- BorderSpacing.Bottom = 8
- Caption = 'Reset'
- OnClick = ResetBtnClick
+ inherited GroupEdit: TEdit
+ Left = 228
+ Width = 204
TabOrder = 1
end
- object ComputeBtn: TButton
- AnchorSideLeft.Control = Panel1
- AnchorSideTop.Control = Panel1
- AnchorSideRight.Control = CloseBtn
- Left = 329
- Height = 25
- Top = 8
- Width = 76
- Anchors = [akTop, akRight]
- AutoSize = True
- BorderSpacing.Top = 8
- BorderSpacing.Right = 8
- BorderSpacing.Bottom = 8
- Caption = 'Compute'
- OnClick = ComputeBtnClick
+ inherited MeasLabel: TLabel
+ Left = 228
+ end
+ inherited MeasEdit: TEdit
+ Left = 228
+ Width = 204
TabOrder = 2
end
- object HelpBtn: TButton
- Tag = 141
- AnchorSideLeft.Control = Panel1
- AnchorSideTop.Control = Panel1
- AnchorSideRight.Control = ResetBtn
- Left = 208
- Height = 25
- Top = 8
- Width = 51
- Anchors = [akTop, akRight]
- AutoSize = True
- BorderSpacing.Left = 8
- BorderSpacing.Top = 8
- BorderSpacing.Right = 8
- BorderSpacing.Bottom = 8
- Caption = 'Help'
- OnClick = HelpBtnClick
- TabOrder = 0
+ inherited Bevel2: TBevel
+ Left = 205
end
- object CloseBtn: TButton
- AnchorSideLeft.Control = Panel1
- AnchorSideTop.Control = Panel1
- AnchorSideRight.Control = Panel1
+ object GroupBox1: TGroupBox[8]
+ AnchorSideLeft.Control = MeasEdit
+ AnchorSideTop.Control = MeasEdit
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = MeasEdit
AnchorSideRight.Side = asrBottom
- Left = 413
- Height = 25
- Top = 8
- Width = 55
- Anchors = [akTop, akRight]
- AutoSize = True
- BorderSpacing.Top = 8
- BorderSpacing.Right = 8
- BorderSpacing.Bottom = 8
- Caption = 'Close'
- ModalResult = 11
+ Left = 228
+ Height = 107
+ Top = 120
+ Width = 204
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Top = 24
+ Caption = 'CUMSUM V-Mask Specifications'
+ ClientHeight = 87
+ ClientWidth = 200
TabOrder = 3
+ object Label4: TLabel
+ AnchorSideLeft.Control = GroupBox1
+ AnchorSideTop.Control = DeltaEdit
+ AnchorSideTop.Side = asrCenter
+ Left = 12
+ Height = 15
+ Top = 6
+ Width = 94
+ BorderSpacing.Left = 12
+ Caption = 'Delta (Effect Size):'
+ ParentColor = False
+ end
+ object Label5: TLabel
+ AnchorSideLeft.Control = GroupBox1
+ AnchorSideTop.Control = AlphaEdit
+ AnchorSideTop.Side = asrCenter
+ Left = 12
+ Height = 15
+ Top = 33
+ Width = 94
+ BorderSpacing.Left = 12
+ Caption = 'Alpha Probability:'
+ ParentColor = False
+ end
+ object Label6: TLabel
+ AnchorSideLeft.Control = GroupBox1
+ AnchorSideTop.Control = BetaEdit
+ AnchorSideTop.Side = asrCenter
+ Left = 12
+ Height = 15
+ Top = 60
+ Width = 86
+ BorderSpacing.Left = 12
+ Caption = 'Beta Probability:'
+ ParentColor = False
+ end
+ object DeltaEdit: TEdit
+ AnchorSideLeft.Control = AlphaEdit
+ AnchorSideTop.Control = GroupBox1
+ AnchorSideRight.Control = GroupBox1
+ AnchorSideRight.Side = asrBottom
+ Left = 114
+ Height = 23
+ Top = 2
+ Width = 78
+ Alignment = taRightJustify
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Top = 2
+ BorderSpacing.Right = 8
+ Constraints.MinWidth = 64
+ TabOrder = 0
+ Text = 'DeltaEdit'
+ end
+ object AlphaEdit: TEdit
+ AnchorSideLeft.Control = Label5
+ AnchorSideLeft.Side = asrBottom
+ AnchorSideTop.Control = DeltaEdit
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = GroupBox1
+ AnchorSideRight.Side = asrBottom
+ Left = 114
+ Height = 23
+ Top = 29
+ Width = 78
+ Alignment = taRightJustify
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 8
+ BorderSpacing.Top = 4
+ BorderSpacing.Right = 8
+ Constraints.MinWidth = 64
+ TabOrder = 1
+ Text = 'AlphaEdit'
+ end
+ object BetaEdit: TEdit
+ AnchorSideLeft.Control = AlphaEdit
+ AnchorSideTop.Control = AlphaEdit
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = GroupBox1
+ AnchorSideRight.Side = asrBottom
+ Left = 114
+ Height = 23
+ Top = 56
+ Width = 78
+ Alignment = taRightJustify
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Top = 4
+ BorderSpacing.Right = 8
+ BorderSpacing.Bottom = 8
+ Constraints.MinWidth = 64
+ TabOrder = 2
+ Text = 'BetaEdit'
+ end
+ end
+ object GroupBox2: TGroupBox[9]
+ AnchorSideLeft.Control = GroupBox1
+ AnchorSideTop.Control = GroupBox1
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = MeasEdit
+ AnchorSideRight.Side = asrBottom
+ Left = 228
+ Height = 51
+ Top = 243
+ Width = 204
+ Anchors = [akTop, akLeft, akRight]
+ AutoSize = True
+ BorderSpacing.Top = 16
+ BorderSpacing.Bottom = 8
+ Caption = 'Option:'
+ ClientHeight = 31
+ ClientWidth = 200
+ TabOrder = 4
+ object TargetChk: TCheckBox
+ AnchorSideLeft.Control = GroupBox2
+ AnchorSideTop.Control = TargetEdit
+ AnchorSideTop.Side = asrCenter
+ Left = 12
+ Height = 19
+ Top = 2
+ Width = 108
+ BorderSpacing.Left = 12
+ BorderSpacing.Right = 8
+ Caption = 'Use Target Specs'
+ TabOrder = 0
+ end
+ object TargetEdit: TEdit
+ AnchorSideLeft.Control = TargetChk
+ AnchorSideLeft.Side = asrBottom
+ AnchorSideTop.Control = GroupBox2
+ AnchorSideRight.Control = GroupBox2
+ AnchorSideRight.Side = asrBottom
+ Left = 128
+ Height = 23
+ Top = 0
+ Width = 64
+ Alignment = taRightJustify
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 8
+ BorderSpacing.Right = 8
+ BorderSpacing.Bottom = 8
+ Constraints.MinWidth = 64
+ TabOrder = 1
+ Text = 'TargetEdit'
+ end
+ end
+ end
+ inherited SpecsSplitter: TSplitter
+ Left = 435
+ end
+ inherited PageControl1: TPageControl
+ Left = 443
+ Width = 478
+ inherited ReportPage: TTabSheet
+ ClientWidth = 470
+ inherited Panel1: TPanel
+ Width = 458
+ ClientWidth = 454
+ inherited ReportMemo: TMemo
+ Width = 446
+ end
+ end
end
end
end
diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/cumsumunit.pas b/applications/lazstats/source/forms/analysis/statistical_process_control/cumsumunit.pas
index f66aca8fd..5ffabf094 100644
--- a/applications/lazstats/source/forms/analysis/statistical_process_control/cumsumunit.pas
+++ b/applications/lazstats/source/forms/analysis/statistical_process_control/cumsumunit.pas
@@ -1,10 +1,3 @@
-// File for testing: "BoltSizes.laz"
-// Lot No --> Group variable
-// BoltLngth --> Measurement variable
-// Delta --> 0.01
-// Alpha --> 0.05
-// Beta ---> 0.20
-
unit CUMSUMUnit;
{$mode objfpc}{$H+}
@@ -12,527 +5,342 @@ unit CUMSUMUnit;
interface
uses
- Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
- StdCtrls, ExtCtrls, Buttons,
- MainUnit, Globals, DataProcs, OutputUnit, BlankFrmUnit, ContextHelpUnit;
+ Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, ExtCtrls,
+ StdCtrls, Globals, BasicSPCUnit;
type
- { TCUMSUMFrm }
+ { TCUSUMChartForm }
- TCUMSUMFrm = class(TForm)
- Bevel2: TBevel;
- ComputeBtn: TButton;
- HelpBtn: TButton;
- Panel1: TPanel;
- ResetBtn: TButton;
- CloseBtn: TButton;
- ReturnBtn1: TButton;
- TargetEdit: TEdit;
- TargetChk: TCheckBox;
- DeltaEdit: TEdit;
+ TCUSUMChartForm = class(TBasicSPCForm)
AlphaEdit: TEdit;
BetaEdit: TEdit;
+ DeltaEdit: TEdit;
GroupBox1: TGroupBox;
GroupBox2: TGroupBox;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
- MeasEdit: TEdit;
- GroupEdit: TEdit;
- Label1: TLabel;
- Label2: TLabel;
- Label3: TLabel;
- VarList: TListBox;
- procedure ComputeBtnClick(Sender: TObject);
+ TargetChk: TCheckBox;
+ TargetEdit: TEdit;
procedure FormActivate(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure FormShow(Sender: TObject);
- procedure HelpBtnClick(Sender: TObject);
- procedure ResetBtnClick(Sender: TObject);
- procedure VarListClick(Sender: TObject);
private
- { private declarations }
- FAutoSized: boolean;
- semean: double;
- procedure PlotMeans(var Means: DblDyneVec; NoGrps: integer; GrandMean: double);
- function Validate(out AMsg: String; out AControl: TWinControl): Boolean;
- public
- { public declarations }
- end;
+ SEMean: Double;
+ protected
+ procedure Compute; override;
+ procedure PlotMeans(ATitle, AXTitle, AYTitle, ADataTitle, AGrandMeanTitle: String;
+ const Groups: StrDyneVec; const Means: DblDyneVec;
+ UCL, LCL, GrandMean, TargetSpec, LowerSpec, UpperSpec: double); override;
+ procedure Reset; override;
+ function Validate(out AMsg: String; out AControl: TWinControl): Boolean; override;
+ end;
var
- CUMSUMFrm: TCUMSUMFrm;
+ CUSUMChartForm: TCUSUMChartForm;
+
implementation
+{$R *.lfm}
+
uses
- Math;
+ Math, TAChartUtils, TASeries,
+ Utils, MainUnit, DataProcs;
-{ TCUMSUMFrm }
+{ TCUSUMChartForm }
-procedure TCUMSUMFrm.ResetBtnClick(Sender: TObject);
-VAR i : integer;
-begin
- VarList.Clear;
- GroupEdit.Text := '';
- MeasEdit.Text := '';
- DeltaEdit.Text := '';
- TargetEdit.Text := '';
- TargetChk.Checked := false;
- for i := 1 to NoVariables do
- VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
-end;
-
-procedure TCUMSUMFrm.VarListClick(Sender: TObject);
+procedure TCUSUMChartForm.Compute;
var
- index: integer;
+ i, j, grpIndex, numGrps, grpSize, oldGrpSize, numValues: Integer;
+ X, Xsq, Xmin, Xmax, target, grandMean, grandSum, grandSD, UCL, LCL: Double;
+ sizeError: Boolean;
+ grp: String;
+ groups: StrDyneVec = nil;
+ means: DblDyneVec = nil;
+ stdDev: DblDyneVec = nil;
+ cumSums: DblDyneVec = nil;
+ count: IntDyneVec = nil;
+ ColNoSelected: IntDyneVec = nil;
+ lReport: TStrings;
+
begin
- index := VarList.ItemIndex;
- if index > -1 then
+ SetLength(ColNoSelected, 2);
+ ColNoSelected[0] := GrpVar;
+ ColNoSelected[1] := MeasVar;
+
+ groups := GetGroups();
+ numGrps := Length(groups);
+ grpSize := 0;
+ oldGrpSize := 0;
+
+ SetLength(means, numGrps);
+ SetLength(count, numGrps);
+ SetLength(stdDev, numGrps);
+ SetLength(cumSums, numGrps);
+ SEMean := 0.0;
+ grandMean := 0.0;
+ grandSum := 0.0;
+ sizeError := false;
+
+ // Count "good" data points
+ numValues := 0;
+ for i := 1 to NoCases do
+ if GoodRecord(i, Length(ColNoSelected), ColNoSelected) then inc(numValues);
+
+ // calculate group ranges, grand mean, group sd's, semeans
+ for j := 0 to numGrps - 1 do // groups
begin
- if GroupEdit.Text = '' then
- GroupEdit.Text := VarList.Items[index]
- else
- MeasEdit.Text := VarList.Items[index];
- VarList.Items.Delete(index);
+ Xmin := Infinity;
+ Xmax := -Infinity;
+ for i := 1 to NoCases do
+ begin
+ if not GoodRecord(i, Length(ColNoSelected), ColNoSelected) then continue;
+ grp := Trim(OS3MainFrm.DataGrid.Cells[GrpVar, i]);
+ grpIndex := IndexOfString(groups, grp);
+ if grpIndex = j then
+ begin
+ X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[MeasVar, i]));
+ Xsq := X * X;
+ if X > Xmax then Xmax := X;
+ if X < Xmin then Xmin := X;
+ inc(count[grpIndex]);
+ means[grpIndex] := means[grpIndex] + X;
+ stddev[grpIndex] := stddev[grpIndex] + Xsq;
+ SEMean := SEMean + Xsq;
+ grandMean := grandMean + X;
+ end;
+ end; // next case
+
+ grpSize := count[j];
+ if j = 0 then oldgrpSize := grpSize;
+ if (oldGrpsize <> grpSize) or (grpSize < 2) then
+ begin
+ sizeError := true;
+ break;
+ end;
+
+ stdDev[j] := stddev[j] - sqr(means[j]) / grpSize;
+ stddev[j] := stddev[j] / (grpSize - 1);
+ stddev[j] := sqrt(stddev[j]);
+ means[j] := means[j] / grpSize;
+ end; // next group
+
+ if (grpSize < 2) or (grpSize > 25) or sizeError then
+ begin
+ ErrorMsg('Group size error.');
+ exit;
end;
+
+ // now get cumulative deviations of means from target
+ if TargetChk.Checked then
+ target := StrToFloat(TargetEdit.Text)
+ else
+ target := means[numGrps-1];
+ cumsums[0] := means[0] - target;
+ grandSum := grandSum + (means[0] - target);
+ for j := 1 to numGrps-1 do
+ begin
+ cumsums[j] := cumsums[j-1] + (means[j] - target);
+ grandSum := grandSum + (means[j] - target);
+ end;
+
+ SEMean := SEMean - sqr(grandMean)/numValues;
+ SEMean := sqrt(SEMean/(numValues - 1));
+ grandSD := SEMean;
+ SEMean := SEMean/sqrt(numValues);
+ grandMean := grandMean/numValues; // mean of all observations
+ grandSum := grandSum/numGrps; // mean of the group means
+ UCL := grandMean + 3.0*SEMean;
+ LCL := grandMean - 3.0*SEMean;
+ if (LCL < 0.0) then LCL := 0.0;
+
+ // Print results
+ lReport := TStringList.Create;
+ try
+ lReport.Clear;
+ lReport.Add('CUMSUM Chart Results');
+ lReport.Add('');
+ lReport.Add(' Group Size Mean Std.Dev. Cum.Dev. of' );
+ lReport.Add(' Mean from Target');
+ lReport.Add('------- ---- -------- -------- ----------------');
+ for i := 0 to numGrps - 1 do
+ lReport.Add('%7d %4d %8.2f %8.2f %16.2f', [i+1, count[i], means[i], stddev[i], cumsums[i]]);
+ lReport.Add('');
+ lReport.Add('Mean of group deviations: %8.3f', [grandSum]);
+ lReport.Add('Mean of all observations: %8.3f', [grandMean]);
+ lReport.Add('Std. Dev. of Observations: %8.3f', [grandSD]);
+ lReport.Add('Standard Error of Mean: %8.3f', [SEMean]);
+ lReport.Add('Target Specification: %8.3f', [target]);
+ lReport.Add('Lower Control Limit: %8.3f', [LCL]);
+ lReport.Add('Upper Control Limit: %8.3f', [UCL]);
+
+ ReportMemo.Lines.Assign(lReport);
+ finally
+ lReport.Free;
+ end;
+
+ // Show graph
+ PlotMeans(
+ Format('Cumulative Sum Chart for "%s"', [GetFileName]), // chart title
+ GroupEdit.Text, // x title
+ 'CUSUM of ' + MeasEdit.Text, // y title
+ 'Data', // series title
+ 'Mean deviation', // mean label at right
+ groups, cumSums,
+ NaN, NaN, grandSum,
+ NaN, NaN, NaN
+ );
end;
-procedure TCUMSUMFrm.FormActivate(Sender: TObject);
+
+procedure TCUSUMChartForm.FormActivate(Sender: TObject);
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;
- VarList.Constraints.MinWidth := GroupBox1.Width * 8 div 10;
- VarList.Constraints.MinHeight := GroupBox2.Top + GroupBox2.Height - VarList.Top;
-
- Constraints.MinWidth := Width;
- Constraints.MinHeight := Height;
-
- FAutoSized := true;
+ DisableAutoSizing;
+ try
+ GroupBox2.Anchors := GroupBox2.Anchors - [akRight];
+ VarList.Constraints.MinWidth := VarListLabel.Width;
+ SpecsPanel.Constraints.MinWidth := Max(
+ CloseBtn.Left + CloseBtn.Width - HelpBtn.Left + HelpBtn.BorderSpacing.Around,
+ GroupBox2.Width * 2 + VarList.BorderSpacing.Right + VarList.BorderSpacing.Left
+ );
+ Constraints.MinHeight := GroupBox2.Top + GroupBox2.Height + GroupBox2.BorderSpacing.Bottom + ButtonPanel.Height;
+ GroupBox2.Anchors := GroupBox2.Anchors + [akRight];
+ finally
+ EnableAutoSizing;
+ end;
end;
-procedure TCUMSUMFrm.FormCreate(Sender: TObject);
+
+{ Overridden to draw the V-Mark }
+procedure TCUSUMChartForm.PlotMeans(ATitle, AXTitle, AYTitle, ADataTitle, AGrandMeanTitle: String;
+ const Groups: StrDyneVec; const Means: DblDyneVec;
+ UCL, LCL, GrandMean, TargetSpec, LowerSpec, UpperSpec: double);
+var
+ alpha, beta, delta, deltaSD, gamma, d, h, k: Double;
+ ser: TLineSeries;
+ ext: TDoubleRect;
+ x0, y0, x1, y1, x2, y2, x3, y3: Double;
begin
- Assert(OS3MainFrm <> nil);
- if BlankFrm = nil then
- Application.CreateForm(TBlankFrm, BlankFrm);
+ inherited;
+ if DeltaEdit.Text = '' then
+ exit;
+
+ alpha := StrToFloat(AlphaEdit.Text);
+ beta := StrToFloat(BetaEdit.Text);
+ delta := StrToFloat(DeltaEdit.Text); // This is in data units
+ deltaSD := delta / SEMean; // This is in multiples of std deviations
+
+ // see : https://www.itl.nist.gov/div898/handbook/pmc/section3/pmc323.htm
+ d := 2.0 / sqr(deltaSD) * ln((1.0 - beta)/alpha);
+ k := deltaSD * SEMean / 2.0;
+ h := d * k;
+
+ ser := TLineSeries.Create(FChartFrame.Chart);
+ FChartFrame.Chart.AddSeries(ser);
+ ser.SeriesColor := clBlue;
+ ser.Title := 'V-Mask';
+
+ ext := FChartFrame.Chart.GetFullExtent;
+ x1 := Length(Means); // 1-based!
+ y1 := Means[High(Means)] + h;
+ x0 := 1;
+ y0 := y1 - k*(x0 - x1);
+
+ x2 := x1;
+ y2 := Means[High(Means)] - h;
+ x3 := x0;
+ y3 := y2 + k*(x3 - x2);
+
+ ser.AddXY(x0, y0);
+ ser.AddXY(x1, y1);
+ ser.AddXY(x2, y2);
+ ser.AddXY(x3, y3);
+end;
+
+
+procedure TCUSUMChartForm.Reset;
+begin
+ inherited;
+ DeltaEdit.Clear;
AlphaEdit.Text := FormatFloat('0.00', DEFAULT_ALPHA_LEVEL);
BetaEdit.Text := FormatFloat('0.00', DEFAULT_BETA_LEVEL);
+ TargetEdit.Clear;
end;
-procedure TCUMSUMFrm.FormShow(Sender: TObject);
-begin
- ResetBtnClick(self);
-end;
-procedure TCUMSUMFrm.HelpBtnClick(Sender: TObject);
-begin
- if ContextHelpForm = nil then
- Application.CreateForm(TContextHelpForm, ContextHelpForm);
- ContextHelpForm.HelpMessage((Sender as TButton).tag);
-end;
-
-procedure TCUMSUMFrm.ComputeBtnClick(Sender: TObject);
-var
- i, j, GrpVar, MeasVar, mingrp, maxgrp, G, range, grpsize : integer;
- oldgrpsize : integer;
- X, UCL, LCL : double;
- xmin, xmax, GrandMean, GrandSD : double;
- Target, GrandSum : double;
- Means, StdDev, CumSums: DblDyneVec;
- count : IntDyneVec;
- cellstring: string;
- sizeError: boolean;
- ColNoSelected : IntDyneVec;
- NoSelected : integer;
- lReport: TStrings;
- msg: String;
- C: TWinControl;
-
- procedure CleanUp;
- begin
- CumSums := nil;
- StdDev := nil;
- Count := nil;
- Means := nil;
- ColNoSelected := nil;
- end;
-
-begin
- if not Validate(msg, C) then
- begin
- C.SetFocus;
- MessageDlg(msg, mtError, [mbOK], 0);
- exit;
- end;
-
- SetLength(ColNoSelected,NoVariables);
- GrpVar := 1;
- MeasVar := 2;
- grpsize := 0;
- oldgrpsize := 0;
-
- for i := 1 to NoVariables do
- begin
- cellstring := OS3MainFrm.DataGrid.Cells[i,0];
- if cellstring = GroupEdit.Text then GrpVar := i;
- if cellstring = MeasEdit.Text then MeasVar := i;
- end;
- NoSelected := 2;
- ColNoSelected[0] := GrpVar;
- ColNoSelected[1] := MeasVar;
-
- mingrp := 10000;
- maxgrp := -10000;
- for i := 1 to NoCases do
- begin
- if not GoodRecord(i,NoSelected,ColNoSelected) then continue;
- G := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[GrpVar,i])));
- if G < mingrp then mingrp := G;
- if G > maxgrp then maxgrp := G;
- end;
- range := maxgrp - mingrp + 1;
-
- SetLength(means,range);
- SetLength(count,range);
- SetLength(stddev,range);
- SetLength(cumsums,range);
-
- for i := 0 to range-1 do
- begin
- count[i] := 0;
- means[i] := 0.0;
- stddev[i] := 0.0;
- cumsums[i] := 0.0;
- end;
- semean := 0.0;
- GrandMean := 0.0;
- sizeerror := false;
- GrandSum := 0.0;
- if TargetChk.Checked then Target := StrToFloat(TargetEdit.Text)
- else Target := 0.0;
-
- // calculate group ranges, grand mean, group sd's, semeans
- for j := 1 to range do // groups
- begin
- xmin := 10000.0;
- xmax := -10000.0;
- for i := 1 to NoCases do
- begin
- if not GoodRecord(i,NoSelected,ColNoSelected) then continue;
- G := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[GrpVar,i])));
- G := G - mingrp + 1;
- if G = j then
- begin
- X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[MeasVar,i]));
- if X > xmax then xmax := X;
- if X < xmin then xmin := X;
- count[G-1] := count[G-1] + 1;
- stddev[G-1] := stddev[G-1] + (X * X);
- semean := semean + (X * X);
- means[G-1] := means[G-1] + X;
- GrandMean := GrandMean + X;
- end;
- end; // next case
- stddev[j-1] := stddev[j-1] - (means[j-1] * means[j-1] / count[j-1]);
- stddev[j-1] := stddev[j-1] / (count[j-1] - 1);
- stddev[j-1] := sqrt(stddev[j-1]);
- grpsize := count[j-1];
- means[j-1] := means[j-1] / count[j-1];
- if j = 1 then oldgrpsize := grpsize;
- if oldgrpsize <> grpsize then sizeerror := true;
- end; // next group
-
- // now get cumulative deviations of means from target
- if Target = 0.0 then Target := means[range-1];
- cumsums[0] := means[0] - Target;
- GrandSum := GrandSum + (means[0] - Target);
- for j := 2 to range do
- begin
- cumsums[j-1] := cumsums[j-2] + (means[j-1] - Target);
- GrandSum := GrandSum + (means[j-1] - Target);
- end;
-
- if (grpsize < 2) or (grpsize > 25) or (sizeerror) then
- begin
- MessageDlg('Group sizes error.', mtError, [mbOK], 0);
- CleanUp;
- exit;
- end;
-
- semean := semean - ((GrandMean * GrandMean) / NoCases);
- semean := semean / (NoCases - 1);
- semean := sqrt(semean);
- GrandSD := semean;
- semean := semean / sqrt(NoCases);
- GrandMean := GrandMean / NoCases; // mean of all observations
- GrandSum := GrandSum / range; // mean of the group means
- UCL := GrandMean + (3.0 * semean);
- LCL := GrandMean - (3.0 * semean);
- if (LCL < 0.0) then LCL := 0.0;
-
- // printed results
- lReport := TStringList.Create;
- try
- lReport.Clear;
- lReport.Add('CUMSUM Chart Results');
- lReport.Add('');
- lReport.Add('Group Size Mean Std.Dev. Cum.Dev. of');
- lReport.Add(' Mean from Target');
- lReport.Add('----- ---- -------- -------- ----------------');
- for i := 0 to range-1 do
- lReport.Add(' %3d %3d %8.2f %8.2f %8.2f', [i+1, count[i], means[i], stddev[i], cumsums[i]]);
- lReport.Add('');
- lReport.Add('Mean of group deviations: %8.3f', [GrandSum]);
- lReport.Add('Mean of all observations: %8.3f', [GrandMean]);
- lReport.Add('Std. Dev. of Observations: %8.3f', [GrandSD]);
- lReport.Add('Standard Error of Mean: %8.3f', [seMean]);
- lReport.Add('Target Specification: %8.3f', [Target]);
- lReport.Add('Lower Control Limit: %8.3f', [LCL]);
- lReport.Add('Upper Control Limit: %8.3f', [UCL]);
-
- DisplayReport(lReport);
- finally
- lReport.Free;
- end;
-
- // show graph
- PlotMeans(cumsums, range, GrandSum);
-
- // Clean up
- CleanUp;
-end;
-
-procedure TCUMSUMFrm.PlotMeans(var Means: DblDyneVec; NoGrps: integer;
- GrandMean: double);
-var
- i, xpos, ypos, hleft, hright, vtop, vbottom, imagewide : integer;
- vhi, hwide, offset, strhi, grpnospc, distx : integer;
- imagehi, maxval, minval, valincr, Yvalue : double;
- alpha, beta, delta, gamma, theta, kfactor, d : double;
- Title : string;
-begin
- maxval := -10000.0;
- minval := 10000.0;
- for i := 0 to NoGrps-1 do
- begin
- if means[i] > maxval then maxval := means[i];
- if means[i] < minval then minval := means[i];
- end;
-// BlankFrm.Image1.Canvas.Clear;
- BlankFrm.Show;
- Title := 'CUMSUM CHART FOR : ' + OS3MainFrm.FileNameEdit.Text;
- BlankFrm.Caption := Title;
- imagewide := BlankFrm.Image1.Width;
- imagehi := BlankFrm.Image1.Height;
- vtop := 20;
- vbottom := round(imagehi) - 80;
- vhi := vbottom - vtop;
- hleft := 100;
- hright := imagewide - 80;
- hwide := hright - hleft;
-
- BlankFrm.Image1.Canvas.Brush.Color := clLtGray;
- BlankFrm.Image1.Canvas.FillRect(0, 0, BlankFrm.Image1.Width, BlankFrm.Image1.Height);
-
- // Draw chart border
- BlankFrm.Image1.Canvas.Pen.Color := clBlack;
- BlankFrm.Image1.Canvas.Brush.Color := clWhite;
- BlankFrm.Image1.Canvas.Rectangle(hleft,vtop-10,hleft+hwide,vtop+vhi+10);
-
- // draw Grand Mean
- ypos := round(vhi * ( (maxval - GrandMean) / (maxval - minval)));
- ypos := ypos + vtop;
- xpos := hleft;
- BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
- xpos := hright;
- BlankFrm.Image1.Canvas.Pen.Color := clRed;
- BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
- Title := 'AVG.DEV.';
- strhi := BlankFrm.Image1.Canvas.TextHeight(Title);
- ypos := ypos - strhi div 2;
- BlankFrm.Image1.Canvas.Brush.Style := bsClear;
- BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
-
- // draw horizontal axis
- BlankFrm.Image1.Canvas.MoveTo(hleft,vbottom + 20);
- BlankFrm.Image1.Canvas.LineTo(hright,vbottom + 20);
- for i := 1 to NoGrps do
- begin
- ypos := vbottom + 10;
- xpos := round((hwide / NoGrps)* i + hleft);
- BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
- ypos := ypos + 10;
- BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
- Title := format('%d',[i]);
- offset := BlankFrm.Image1.Canvas.TextWidth(Title) div 2;
- strhi := BlankFrm.Image1.Canvas.TextHeight(Title);
- xpos := xpos - offset;
- ypos := ypos + strhi;
- BlankFrm.Image1.Canvas.Pen.Color := clBlack;
- BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
- xpos := 10;
- BlankFrm.Image1.Canvas.TextOut(xpos,ypos,'GROUPS:');
- end;
-
- // Draw vertical axis
- valincr := (maxval - minval) / 10.0;
- for i := 1 to 11 do
- begin
- Title := format('%8.2f',[maxval - ((i-1)*valincr)]);
- strhi := BlankFrm.Image1.Canvas.TextHeight(Title);
- xpos := 10;
- Yvalue := maxval - (valincr * (i-1));
- ypos := round(vhi * ( (maxval - Yvalue) / (maxval - minval)));
- ypos := ypos + vtop - strhi div 2;
- BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
- end;
-
- // draw lines for means of the groups
- ypos := round(vhi * ( (maxval - means[0]) / (maxval - minval)));
- ypos := ypos + vtop;
- xpos := round((hwide / NoGrps) + hleft);
- BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
- BlankFrm.Image1.Canvas.Pen.Color := clBlack;
- for i := 2 to NoGrps do
- begin
- ypos := round(vhi * ( (maxval - means[i-1]) / (maxval - minval)));
- ypos := ypos + vtop;
- xpos := round((hwide / NoGrps)* i + hleft);
- BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
- end;
-
- // Draw V Mask
- if DeltaEdit.Text = '' then exit; // not elected
- BlankFrm.Image1.Canvas.Pen.Color := clBlue;
- delta := StrToFloat(DeltaEdit.Text);
- gamma := delta / semean;
- alpha := StrToFloat(AlphaEdit.Text);
- beta := StrToFloat(BetaEdit.Text);
- kfactor := 2.0 * semean;
- d := (2.0 / (gamma * gamma)) * ln((1.0 - beta)/alpha);
- theta := arctan(delta / (2.0 * kfactor));
- grpnospc := round(hwide / NoGrps);
- xpos := hleft + (grpnospc * (NoGrps)); // last group
- ypos := round(vhi * ( (maxval - means[NoGrps-1]) / (maxval - minval)));
- ypos := ypos + vtop;
- BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
- xpos := round(xpos + (d * grpnospc / hwide)); // scaled d
- BlankFrm.Image1.Canvas.LineTo(xpos,ypos); // line 0 to A
-
- // draw upper angle line
- xpos := hleft + (grpnospc * NoGrps); // last group
- xpos := round(xpos + (d * grpnospc / hwide)); // plus scaled d
- ypos := round(vhi * ( (maxval - means[NoGrps-1]) / (maxval - minval)));
- ypos := ypos + vtop;
- BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
- ypos := vtop; // draw angle up to top of graph
- distx := round(vhi / tan(theta)); // x unscaled distance
- xpos := round(xpos - (distx * grpnospc / hwide));
- BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
-
- // draw lower angle line
- xpos := hleft + (grpnospc * NoGrps); // last group
- xpos := round(xpos + (d * grpnospc / hwide)); // plus scaled d
- ypos := round(vhi * ( (maxval - means[NoGrps-1]) / (maxval - minval)));
- ypos := ypos + vtop;
- BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
- ypos := vbottom;
- xpos := round(xpos - (distx * grpnospc / hwide));
- BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
- BlankFrm.Image1.Canvas.Pen.Color := clBlack;
-end;
-
-function TCUMSUMFrm.Validate(out AMsg: String; out AControl: TWinControl): Boolean;
+function TCUSUMChartForm.Validate(out AMsg: String; out AControl: TWinControl): Boolean;
var
x: Double;
+ n: Integer;
begin
- Result := False;
-
- if GroupEdit.Text = '' then
- begin
- AMsg := 'Group variable not specified.';
- AControl := GroupEdit;
+ Result := inherited;
+ if not Result then
exit;
+
+ Result := false;
+
+ if (DeltaEdit.Text <> '') then
+ begin
+ if not TryStrToFloat(DeltaEdit.Text, x) then
+ begin
+ AMsg := 'No valid number given for Delta.';
+ AControl := DeltaEdit;
+ exit;
+ end;
+
+ if (AlphaEdit.Text = '') then
+ begin
+ AMsg := 'Alpha not specified.';
+ AControl := AlphaEdit;
+ exit;
+ end;
+ if not TryStrToFloat(AlphaEdit.Text, x) then
+ begin
+ AMsg := 'No valid number given for Alpha.';
+ AControl := AlphaEdit;
+ exit;
+ end;
+
+ if (BetaEdit.Text = '') then
+ begin
+ AMsg := 'Beta not specified.';
+ AControl := BetaEdit;
+ exit;
+ end;
+ if not TryStrToFloat(BetaEdit.Text, x) then
+ begin
+ AMsg := 'No valid number given for Beta.';
+ AControl := BetaEdit;
+ exit;
+ end;
end;
- if MeasEdit.Text = '' then
+ if TargetChk.Checked then
begin
- AMsg := 'Measurement variable not specified.';
- AControl := MeasEdit;
- exit;
+ if (TargetEdit.Text = '') then
+ begin
+ AMsg := 'Target not specified.';
+ AControl := TargetEdit;
+ exit;
+ end;
+ if not TryStrToFloat(TargetEdit.Text, x) then
+ begin
+ AMsg := 'No valid number given for target specification.';
+ AControl := TargetEdit;
+ exit;
+ end;
end;
- if DeltaEdit.Text = '' then
- begin
- AMsg := 'Delta parameter not specified.';
- AControl := DeltaEdit;
- exit;
- end;
- if not TryStrToFloat(DeltaEdit.Text, x) then
- begin
- AMsg := 'Delta parameter is not a valid number.';
- AControl := DeltaEdit;
- exit;
- end;
-
- if AlphaEdit.Text = '' then
- begin
- AMsg := 'Alpha probability is not specified.';
- AControl := AlphaEdit;
- exit;
- end;
- if not TryStrToFloat(AlphaEdit.Text, x) then
- begin
- AMsg := 'Alpha probability is not a valid number.';
- AControl := AlphaEdit;
- exit;
- end;
-
- if BetaEdit.Text = '' then
- begin
- AMsg := 'Beta probability is not specified.';
- AControl := BetaEdit;
- exit;
- end;
- if not TryStrtoFloat(BetaEdit.Text, x) then
- begin
- AMsg := 'Beta probability is not a valid number,';
- AControl := BetaEdit;
- exit;
- end;
-
- if TargetChk.Checked then
- begin
- if TargetEdit.Text = '' then
- begin
- AMsg := 'Target is not specified.';
- AControl := TargetEdit;
- exit;
- end;
- if not TryStrToFloat(TargetEdit.Text, x) then
- begin
- AMsg := 'Target specification is not a valid number.';
- AControl := TargetEdit;
- exit;
- end;
- end;
-
Result := true;
end;
-initialization
- {$I cumsumunit.lrs}
-
end.
diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/rchartunit.lfm b/applications/lazstats/source/forms/analysis/statistical_process_control/rchartunit.lfm
index 27bc3ed67..29158f0a3 100644
--- a/applications/lazstats/source/forms/analysis/statistical_process_control/rchartunit.lfm
+++ b/applications/lazstats/source/forms/analysis/statistical_process_control/rchartunit.lfm
@@ -1,7 +1,7 @@
inherited RChartForm: TRChartForm
HelpType = htKeyword
HelpKeyword = 'html/RangeChart.htm'
- Caption = 'Range Chart'
+ Caption = 'Range Control Chart'
inherited SpecsPanel: TPanel
HelpType = htKeyword
HelpKeyword = 'html/RangeChart.htm'
diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.lfm b/applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.lfm
index 065a945a2..1ccce9ce8 100644
--- a/applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.lfm
+++ b/applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.lfm
@@ -1,5 +1,5 @@
inherited SChartForm: TSChartForm
HelpType = htKeyword
HelpKeyword = 'html/SControlChart.htm'
- Caption = 'Sigma Chart'
+ Caption = 'Sigma Control Chart'
end
diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/uchartunit.lfm b/applications/lazstats/source/forms/analysis/statistical_process_control/uchartunit.lfm
index 07743a2cc..a4800aae8 100644
--- a/applications/lazstats/source/forms/analysis/statistical_process_control/uchartunit.lfm
+++ b/applications/lazstats/source/forms/analysis/statistical_process_control/uchartunit.lfm
@@ -1,7 +1,7 @@
inherited UChartForm: TUChartForm
HelpType = htKeyword
HelpKeyword = 'html/DefectsperUnituChart.htm'
- Caption = 'Defects per unit U Chart'
+ Caption = 'Defects per unit U Control Chart'
OnActivate = FormActivate
inherited SpecsPanel: TPanel
Width = 432
diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/xbarchartunit.lfm b/applications/lazstats/source/forms/analysis/statistical_process_control/xbarchartunit.lfm
index 95520a265..63f13af68 100644
--- a/applications/lazstats/source/forms/analysis/statistical_process_control/xbarchartunit.lfm
+++ b/applications/lazstats/source/forms/analysis/statistical_process_control/xbarchartunit.lfm
@@ -3,7 +3,7 @@ inherited XBarChartForm: TXBarChartForm
Top = 215
HelpType = htKeyword
HelpKeyword = 'html/XBarChart.htm'
- Caption = 'X-Bar Chart'
+ Caption = 'X-Bar Control Chart'
OnActivate = FormActivate
inherited SpecsPanel: TPanel
Width = 475
diff --git a/applications/lazstats/source/forms/mainunit.pas b/applications/lazstats/source/forms/mainunit.pas
index 59cd683a9..7159db56a 100644
--- a/applications/lazstats/source/forms/mainunit.pas
+++ b/applications/lazstats/source/forms/mainunit.pas
@@ -510,7 +510,7 @@ uses
BinomialUnit, KendallTauUnit, KaplanMeierUnit,
// Statistical process control
- XBarChartUnit, RChartUnit, SChartUnit, CUMSUMUNIT, CChartUnit,
+ XBarChartUnit, RChartUnit, SChartUnit, CUMSUMUnit, CChartUnit,
PChartUnit, UChartUnit,
CorSimUnit,
@@ -2130,9 +2130,9 @@ end;
// Menu "Analysis" > "Statistical Process Control" > "CUMSUM Chart"
procedure TOS3MainFrm.mnuAnalysisSPC_CUMSUMClick(Sender: TObject);
begin
- if CUMSUMFrm = nil then
- Application.CreateForm(TCUMSUMFrm, CUMSUMFrm);
- CUMSUMFrm.ShowModal;
+ if CUMSUMChartForm = nil then
+ Application.CreateForm(TCUMSUMChartForm, CUMSUMChartForm);
+ CUMSUMChartForm.ShowModal;
end;