LazStats: Use TAChart and SPC template form in CUMSUMUnit

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7658 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-09-08 21:57:57 +00:00
parent 4bcda27b5f
commit df3f05d290
10 changed files with 535 additions and 829 deletions

View File

@ -49,7 +49,7 @@
<PackageName Value="LCL"/> <PackageName Value="LCL"/>
</Item7> </Item7>
</RequiredPackages> </RequiredPackages>
<Units Count="175"> <Units Count="176">
<Unit0> <Unit0>
<Filename Value="LazStats.lpr"/> <Filename Value="LazStats.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
@ -744,12 +744,11 @@
<UnitName Value="KaplanMeierUnit"/> <UnitName Value="KaplanMeierUnit"/>
</Unit88> </Unit88>
<Unit89> <Unit89>
<Filename Value="forms\analysis\statistical_process_control\cumsumunit.pas"/> <Filename Value="forms\analysis\statistical_process_control\cumsumunit1.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<ComponentName Value="CUMSUMFrm"/> <ComponentName Value="CUMSUMFrm"/>
<HasResources Value="True"/> <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/> <ResourceBaseClass Value="Form"/>
<UnitName Value="CUMSUMUnit"/>
</Unit89> </Unit89>
<Unit90> <Unit90>
<Filename Value="forms\simulations\corsimunit.pas"/> <Filename Value="forms\simulations\corsimunit.pas"/>
@ -1421,6 +1420,14 @@
<ResourceBaseClass Value="Form"/> <ResourceBaseClass Value="Form"/>
<UnitName Value="UChartUnit"/> <UnitName Value="UChartUnit"/>
</Unit174> </Unit174>
<Unit175>
<Filename Value="forms\analysis\statistical_process_control\cumsumunit.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="CUSUMChartForm"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="CUMSUMUnit"/>
</Unit175>
</Units> </Units>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>

View File

@ -8,7 +8,8 @@ uses
{$ENDIF}{$ENDIF} {$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset Interfaces, // this includes the LCL widgetset
Forms, tachartlazaruspkg, tachartprint, lhelpcontrolpkg, Forms, tachartlazaruspkg, tachartprint, lhelpcontrolpkg,
Globals, LicenseUnit, OptionsUnit, DictionaryUnit, MainDM, MainUnit; Globals, LicenseUnit, OptionsUnit, DictionaryUnit, MainDM, MainUnit,
cumsumunit;
{$R LazStats.res} {$R LazStats.res}
@ -28,6 +29,7 @@ begin
end; end;
Application.CreateForm(TMainDataModule, MainDataModule); Application.CreateForm(TMainDataModule, MainDataModule);
Application.CreateForm(TOS3MainFrm, OS3MainFrm); Application.CreateForm(TOS3MainFrm, OS3MainFrm);
Application.CreateForm(TCUSUMChartForm, CUSUMChartForm);
Application.Run; Application.Run;
end. end.

View File

@ -56,7 +56,7 @@ type
function GetFileName: String; function GetFileName: String;
procedure PlotMeans(ATitle, AXTitle, AYTitle, ADataTitle, AGrandMeanTitle: String; procedure PlotMeans(ATitle, AXTitle, AYTitle, ADataTitle, AGrandMeanTitle: String;
const Groups: StrDyneVec; const Means: DblDyneVec; 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 Reset; virtual;
procedure Compute; virtual; procedure Compute; virtual;
function Validate(out AMsg: String; out AControl: TWinControl): Boolean; virtual; function Validate(out AMsg: String; out AControl: TWinControl): Boolean; virtual;
@ -243,14 +243,23 @@ begin
FChartFrame.Chart.BottomAxis.Marks.style := smsLabel; FChartFrame.Chart.BottomAxis.Marks.style := smsLabel;
end; end;
if not IsNaN(GrandMean) then
begin
FChartFrame.HorLine(GrandMean, clRed, psSolid, AGrandMeanTitle); FChartFrame.HorLine(GrandMean, clRed, psSolid, AGrandMeanTitle);
rightLabels.Add(GrandMean, GrandMean, AGrandMeanTitle); rightLabels.Add(GrandMean, GrandMean, AGrandMeanTitle);
end;
if not IsNaN(UCL) then
begin
FChartFrame.HorLine(UCL, CL_COLOR, CL_STYLE, 'UCL/LCL'); FChartFrame.HorLine(UCL, CL_COLOR, CL_STYLE, 'UCL/LCL');
rightLabels.Add(UCL, UCL, 'UCL'); rightLabels.Add(UCL, UCL, 'UCL');
end;
if not IsNaN(LCL) then
begin
FChartFrame.HorLine(LCL, CL_COLOR, CL_STYLE, ''); FChartFrame.HorLine(LCL, CL_COLOR, CL_STYLE, '');
rightLabels.Add(UCL, LCL, 'LCL'); rightLabels.Add(UCL, LCL, 'LCL');
end;
if not IsNan(UpperSpec) then if not IsNan(UpperSpec) then
begin begin

View File

@ -1,122 +1,73 @@
object CUMSUMFrm: TCUMSUMFrm inherited CUSUMChartForm: TCUSUMChartForm
Left = 717
Height = 346
Top = 262
Width = 476
HelpType = htKeyword HelpType = htKeyword
HelpKeyword = 'html/CUMSUMChart.htm' HelpKeyword = 'html/CUMSUMChart.htm'
AutoSize = True Caption = 'Cumulative Sum Control Chart'
Caption = 'CUMSUM Chart'
ClientHeight = 346
ClientWidth = 476
OnActivate = FormActivate OnActivate = FormActivate
OnCreate = FormCreate inherited SpecsPanel: TPanel
OnShow = FormShow Width = 432
Position = poMainFormCenter ClientWidth = 432
LCLVersion = '2.1.0.0' inherited ButtonPanel: TPanel
object Label1: TLabel Width = 432
AnchorSideLeft.Control = Owner ClientWidth = 432
AnchorSideTop.Control = Owner TabOrder = 5
Left = 8 inherited CloseBtn: TButton
Height = 15 Left = 377
Top = 8 TabOrder = 3
Width = 97
BorderSpacing.Left = 8
BorderSpacing.Top = 8
Caption = 'Selection Variables'
ParentColor = False
end end
object Label2: TLabel inherited ComputeBtn: TButton
AnchorSideLeft.Control = GroupEdit Left = 293
AnchorSideTop.Control = Owner TabOrder = 2
Left = 242
Height = 15
Top = 8
Width = 77
BorderSpacing.Top = 8
Caption = 'Group Variable'
ParentColor = False
end end
object Label3: TLabel inherited ResetBtn: TButton
AnchorSideLeft.Control = MeasEdit Left = 231
AnchorSideTop.Control = GroupEdit TabOrder = 1
AnchorSideTop.Side = asrBottom
Left = 242
Height = 15
Top = 64
Width = 117
BorderSpacing.Top = 16
Caption = 'Measurement Variable'
ParentColor = False
end end
object VarList: TListBox inherited HelpBtn: TButton
AnchorSideLeft.Control = Owner Left = 180
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 TabOrder = 0
end end
object GroupEdit: TEdit inherited Bevel1: TBevel
AnchorSideLeft.Control = GroupBox2 Width = 424
AnchorSideTop.Control = Label2 end
AnchorSideTop.Side = asrBottom end
AnchorSideRight.Control = Owner inherited VarList: TListBox
AnchorSideRight.Side = asrBottom Width = 212
Left = 242 TabOrder = 0
Height = 23 end
Top = 25 inherited GroupLabel: TLabel
Width = 226 Left = 228
Anchors = [akTop, akLeft, akRight] end
BorderSpacing.Top = 2 inherited GroupEdit: TEdit
BorderSpacing.Right = 8 Left = 228
ReadOnly = True Width = 204
TabOrder = 1 TabOrder = 1
Text = 'GroupEdit'
end end
object MeasEdit: TEdit inherited MeasLabel: TLabel
AnchorSideLeft.Control = GroupBox2 Left = 228
AnchorSideTop.Control = Label3 end
AnchorSideTop.Side = asrBottom inherited MeasEdit: TEdit
AnchorSideRight.Control = Owner Left = 228
AnchorSideRight.Side = asrBottom Width = 204
Left = 242
Height = 23
Top = 81
Width = 226
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 2
BorderSpacing.Right = 8
ReadOnly = True
TabOrder = 2 TabOrder = 2
Text = 'MeasEdit'
end end
object GroupBox1: TGroupBox inherited Bevel2: TBevel
AnchorSideLeft.Control = GroupBox2 Left = 205
end
object GroupBox1: TGroupBox[8]
AnchorSideLeft.Control = MeasEdit
AnchorSideTop.Control = MeasEdit AnchorSideTop.Control = MeasEdit
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Owner AnchorSideRight.Control = MeasEdit
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 242 Left = 228
Height = 107 Height = 107
Top = 120 Top = 120
Width = 226 Width = 204
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 16 BorderSpacing.Top = 24
BorderSpacing.Right = 8
Caption = 'CUMSUM V-Mask Specifications' Caption = 'CUMSUM V-Mask Specifications'
ClientHeight = 87 ClientHeight = 87
ClientWidth = 222 ClientWidth = 200
TabOrder = 3 TabOrder = 3
object Label4: TLabel object Label4: TLabel
AnchorSideLeft.Control = GroupBox1 AnchorSideLeft.Control = GroupBox1
@ -162,11 +113,12 @@ object CUMSUMFrm: TCUMSUMFrm
Left = 114 Left = 114
Height = 23 Height = 23
Top = 2 Top = 2
Width = 100 Width = 78
Alignment = taRightJustify Alignment = taRightJustify
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 2 BorderSpacing.Top = 2
BorderSpacing.Right = 8 BorderSpacing.Right = 8
Constraints.MinWidth = 64
TabOrder = 0 TabOrder = 0
Text = 'DeltaEdit' Text = 'DeltaEdit'
end end
@ -180,12 +132,13 @@ object CUMSUMFrm: TCUMSUMFrm
Left = 114 Left = 114
Height = 23 Height = 23
Top = 29 Top = 29
Width = 100 Width = 78
Alignment = taRightJustify Alignment = taRightJustify
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 8 BorderSpacing.Left = 8
BorderSpacing.Top = 4 BorderSpacing.Top = 4
BorderSpacing.Right = 8 BorderSpacing.Right = 8
Constraints.MinWidth = 64
TabOrder = 1 TabOrder = 1
Text = 'AlphaEdit' Text = 'AlphaEdit'
end end
@ -198,32 +151,34 @@ object CUMSUMFrm: TCUMSUMFrm
Left = 114 Left = 114
Height = 23 Height = 23
Top = 56 Top = 56
Width = 100 Width = 78
Alignment = taRightJustify Alignment = taRightJustify
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 4 BorderSpacing.Top = 4
BorderSpacing.Right = 8 BorderSpacing.Right = 8
BorderSpacing.Bottom = 8 BorderSpacing.Bottom = 8
Constraints.MinWidth = 64
TabOrder = 2 TabOrder = 2
Text = 'BetaEdit' Text = 'BetaEdit'
end end
end end
object GroupBox2: TGroupBox object GroupBox2: TGroupBox[9]
AnchorSideLeft.Control = GroupBox1
AnchorSideTop.Control = GroupBox1 AnchorSideTop.Control = GroupBox1
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Owner AnchorSideRight.Control = MeasEdit
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 242 Left = 228
Height = 51 Height = 51
Top = 243 Top = 243
Width = 226 Width = 204
Anchors = [akTop, akRight] Anchors = [akTop, akLeft, akRight]
AutoSize = True AutoSize = True
BorderSpacing.Top = 16 BorderSpacing.Top = 16
BorderSpacing.Right = 8 BorderSpacing.Bottom = 8
Caption = 'Option:' Caption = 'Option:'
ClientHeight = 31 ClientHeight = 31
ClientWidth = 222 ClientWidth = 200
TabOrder = 4 TabOrder = 4
object TargetChk: TCheckBox object TargetChk: TCheckBox
AnchorSideLeft.Control = GroupBox2 AnchorSideLeft.Control = GroupBox2
@ -232,123 +187,48 @@ object CUMSUMFrm: TCUMSUMFrm
Left = 12 Left = 12
Height = 19 Height = 19
Top = 2 Top = 2
Width = 141 Width = 108
AutoSize = False
BorderSpacing.Left = 12 BorderSpacing.Left = 12
BorderSpacing.Right = 12 BorderSpacing.Right = 8
Caption = 'Use Target Specification:' Caption = 'Use Target Specs'
TabOrder = 0 TabOrder = 0
end end
object TargetEdit: TEdit object TargetEdit: TEdit
AnchorSideLeft.Control = TargetChk AnchorSideLeft.Control = TargetChk
AnchorSideLeft.Side = asrBottom AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = GroupBox2 AnchorSideTop.Control = GroupBox2
AnchorSideRight.Control = GroupBox2
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 165 Left = 128
Height = 23 Height = 23
Top = 0 Top = 0
Width = 49 Width = 64
Alignment = taRightJustify Alignment = taRightJustify
BorderSpacing.Left = 12 Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 8
BorderSpacing.Right = 8 BorderSpacing.Right = 8
BorderSpacing.Bottom = 8 BorderSpacing.Bottom = 8
Constraints.MinWidth = 64
TabOrder = 1 TabOrder = 1
Text = 'TargetEdit' Text = 'TargetEdit'
end end
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 end
object Panel1: TPanel inherited SpecsSplitter: TSplitter
Left = 0 Left = 435
Height = 41 end
Top = 305 inherited PageControl1: TPageControl
Width = 476 Left = 443
Align = alBottom Width = 478
AutoSize = True inherited ReportPage: TTabSheet
BevelOuter = bvNone ClientWidth = 470
ClientHeight = 41 inherited Panel1: TPanel
ClientWidth = 476 Width = 458
TabOrder = 5 ClientWidth = 454
object ResetBtn: TButton inherited ReportMemo: TMemo
AnchorSideLeft.Control = Panel1 Width = 446
AnchorSideTop.Control = Panel1 end
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
TabOrder = 1
end 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
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
end
object CloseBtn: TButton
AnchorSideLeft.Control = Panel1
AnchorSideTop.Control = Panel1
AnchorSideRight.Control = Panel1
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
TabOrder = 3
end end
end end
end end

View File

@ -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; unit CUMSUMUnit;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
@ -12,276 +5,156 @@ unit CUMSUMUnit;
interface interface
uses uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, ExtCtrls,
StdCtrls, ExtCtrls, Buttons, StdCtrls, Globals, BasicSPCUnit;
MainUnit, Globals, DataProcs, OutputUnit, BlankFrmUnit, ContextHelpUnit;
type type
{ TCUMSUMFrm } { TCUSUMChartForm }
TCUMSUMFrm = class(TForm) TCUSUMChartForm = class(TBasicSPCForm)
Bevel2: TBevel;
ComputeBtn: TButton;
HelpBtn: TButton;
Panel1: TPanel;
ResetBtn: TButton;
CloseBtn: TButton;
ReturnBtn1: TButton;
TargetEdit: TEdit;
TargetChk: TCheckBox;
DeltaEdit: TEdit;
AlphaEdit: TEdit; AlphaEdit: TEdit;
BetaEdit: TEdit; BetaEdit: TEdit;
DeltaEdit: TEdit;
GroupBox1: TGroupBox; GroupBox1: TGroupBox;
GroupBox2: TGroupBox; GroupBox2: TGroupBox;
Label4: TLabel; Label4: TLabel;
Label5: TLabel; Label5: TLabel;
Label6: TLabel; Label6: TLabel;
MeasEdit: TEdit; TargetChk: TCheckBox;
GroupEdit: TEdit; TargetEdit: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
VarList: TListBox;
procedure ComputeBtnClick(Sender: TObject);
procedure FormActivate(Sender: TObject); 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
{ private declarations } SEMean: Double;
FAutoSized: boolean; protected
semean: double; procedure Compute; override;
procedure PlotMeans(var Means: DblDyneVec; NoGrps: integer; GrandMean: double); procedure PlotMeans(ATitle, AXTitle, AYTitle, ADataTitle, AGrandMeanTitle: String;
function Validate(out AMsg: String; out AControl: TWinControl): Boolean; const Groups: StrDyneVec; const Means: DblDyneVec;
public UCL, LCL, GrandMean, TargetSpec, LowerSpec, UpperSpec: double); override;
{ public declarations } procedure Reset; override;
function Validate(out AMsg: String; out AControl: TWinControl): Boolean; override;
end; end;
var var
CUMSUMFrm: TCUMSUMFrm; CUSUMChartForm: TCUSUMChartForm;
implementation implementation
{$R *.lfm}
uses uses
Math; Math, TAChartUtils, TASeries,
Utils, MainUnit, DataProcs;
{ TCUMSUMFrm } { TCUSUMChartForm }
procedure TCUMSUMFrm.ResetBtnClick(Sender: TObject); procedure TCUSUMChartForm.Compute;
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);
var var
index: integer; i, j, grpIndex, numGrps, grpSize, oldGrpSize, numValues: Integer;
begin X, Xsq, Xmin, Xmax, target, grandMean, grandSum, grandSD, UCL, LCL: Double;
index := VarList.ItemIndex; sizeError: Boolean;
if index > -1 then grp: String;
begin groups: StrDyneVec = nil;
if GroupEdit.Text = '' then means: DblDyneVec = nil;
GroupEdit.Text := VarList.Items[index] stdDev: DblDyneVec = nil;
else cumSums: DblDyneVec = nil;
MeasEdit.Text := VarList.Items[index]; count: IntDyneVec = nil;
VarList.Items.Delete(index); ColNoSelected: IntDyneVec = nil;
end;
end;
procedure TCUMSUMFrm.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;
end;
procedure TCUMSUMFrm.FormCreate(Sender: TObject);
begin
Assert(OS3MainFrm <> nil);
if BlankFrm = nil then
Application.CreateForm(TBlankFrm, BlankFrm);
AlphaEdit.Text := FormatFloat('0.00', DEFAULT_ALPHA_LEVEL);
BetaEdit.Text := FormatFloat('0.00', DEFAULT_BETA_LEVEL);
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; lReport: TStrings;
msg: String;
C: TWinControl;
procedure CleanUp;
begin
CumSums := nil;
StdDev := nil;
Count := nil;
Means := nil;
ColNoSelected := nil;
end;
begin begin
if not Validate(msg, C) then SetLength(ColNoSelected, 2);
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[0] := GrpVar;
ColNoSelected[1] := MeasVar; ColNoSelected[1] := MeasVar;
mingrp := 10000; groups := GetGroups();
maxgrp := -10000; 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 for i := 1 to NoCases do
begin if GoodRecord(i, Length(ColNoSelected), ColNoSelected) then inc(numValues);
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 // calculate group ranges, grand mean, group sd's, semeans
for j := 1 to range do // groups for j := 0 to numGrps - 1 do // groups
begin begin
xmin := 10000.0; Xmin := Infinity;
xmax := -10000.0; Xmax := -Infinity;
for i := 1 to NoCases do for i := 1 to NoCases do
begin begin
if not GoodRecord(i,NoSelected,ColNoSelected) then continue; if not GoodRecord(i, Length(ColNoSelected), ColNoSelected) then continue;
G := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[GrpVar,i]))); grp := Trim(OS3MainFrm.DataGrid.Cells[GrpVar, i]);
G := G - mingrp + 1; grpIndex := IndexOfString(groups, grp);
if G = j then if grpIndex = j then
begin begin
X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[MeasVar, i])); X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[MeasVar, i]));
if X > xmax then xmax := X; Xsq := X * X;
if X < xmin then xmin := X; if X > Xmax then Xmax := X;
count[G-1] := count[G-1] + 1; if X < Xmin then Xmin := X;
stddev[G-1] := stddev[G-1] + (X * X); inc(count[grpIndex]);
semean := semean + (X * X); means[grpIndex] := means[grpIndex] + X;
means[G-1] := means[G-1] + X; stddev[grpIndex] := stddev[grpIndex] + Xsq;
GrandMean := GrandMean + X; SEMean := SEMean + Xsq;
grandMean := grandMean + X;
end; end;
end; // next case 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 grpSize := count[j];
if Target = 0.0 then Target := means[range-1]; if j = 0 then oldgrpSize := grpSize;
cumsums[0] := means[0] - Target; if (oldGrpsize <> grpSize) or (grpSize < 2) then
GrandSum := GrandSum + (means[0] - Target);
for j := 2 to range do
begin begin
cumsums[j-1] := cumsums[j-2] + (means[j-1] - Target); sizeError := true;
GrandSum := GrandSum + (means[j-1] - Target); break;
end; end;
if (grpsize < 2) or (grpsize > 25) or (sizeerror) then 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 begin
MessageDlg('Group sizes error.', mtError, [mbOK], 0); ErrorMsg('Group size error.');
CleanUp;
exit; exit;
end; end;
semean := semean - ((GrandMean * GrandMean) / NoCases); // now get cumulative deviations of means from target
semean := semean / (NoCases - 1); if TargetChk.Checked then
semean := sqrt(semean); target := StrToFloat(TargetEdit.Text)
GrandSD := semean; else
semean := semean / sqrt(NoCases); target := means[numGrps-1];
GrandMean := GrandMean / NoCases; // mean of all observations cumsums[0] := means[0] - target;
GrandSum := GrandSum / range; // mean of the group means grandSum := grandSum + (means[0] - target);
UCL := GrandMean + (3.0 * semean); for j := 1 to numGrps-1 do
LCL := GrandMean - (3.0 * semean); 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; if (LCL < 0.0) then LCL := 0.0;
// printed results // Print results
lReport := TStringList.Create; lReport := TStringList.Create;
try try
lReport.Clear; lReport.Clear;
@ -289,240 +162,178 @@ begin
lReport.Add(''); lReport.Add('');
lReport.Add(' Group Size Mean Std.Dev. Cum.Dev. of' ); lReport.Add(' Group Size Mean Std.Dev. Cum.Dev. of' );
lReport.Add(' Mean from Target'); lReport.Add(' Mean from Target');
lReport.Add('----- ---- -------- -------- ----------------'); lReport.Add('------- ---- -------- -------- ----------------');
for i := 0 to range-1 do for i := 0 to numGrps - 1 do
lReport.Add(' %3d %3d %8.2f %8.2f %8.2f', [i+1, count[i], means[i], stddev[i], cumsums[i]]); lReport.Add('%7d %4d %8.2f %8.2f %16.2f', [i+1, count[i], means[i], stddev[i], cumsums[i]]);
lReport.Add(''); lReport.Add('');
lReport.Add('Mean of group deviations: %8.3f', [GrandSum]); lReport.Add('Mean of group deviations: %8.3f', [grandSum]);
lReport.Add('Mean of all observations: %8.3f', [GrandMean]); lReport.Add('Mean of all observations: %8.3f', [grandMean]);
lReport.Add('Std. Dev. of Observations: %8.3f', [GrandSD]); lReport.Add('Std. Dev. of Observations: %8.3f', [grandSD]);
lReport.Add('Standard Error of Mean: %8.3f', [seMean]); lReport.Add('Standard Error of Mean: %8.3f', [SEMean]);
lReport.Add('Target Specification: %8.3f', [Target]); lReport.Add('Target Specification: %8.3f', [target]);
lReport.Add('Lower Control Limit: %8.3f', [LCL]); lReport.Add('Lower Control Limit: %8.3f', [LCL]);
lReport.Add('Upper Control Limit: %8.3f', [UCL]); lReport.Add('Upper Control Limit: %8.3f', [UCL]);
DisplayReport(lReport); ReportMemo.Lines.Assign(lReport);
finally finally
lReport.Free; lReport.Free;
end; end;
// show graph // Show graph
PlotMeans(cumsums, range, GrandSum); PlotMeans(
Format('Cumulative Sum Chart for "%s"', [GetFileName]), // chart title
// Clean up GroupEdit.Text, // x title
CleanUp; 'CUSUM of ' + MeasEdit.Text, // y title
'Data', // series title
'Mean deviation', // mean label at right
groups, cumSums,
NaN, NaN, grandSum,
NaN, NaN, NaN
);
end; end;
procedure TCUMSUMFrm.PlotMeans(var Means: DblDyneVec; NoGrps: integer;
GrandMean: double); procedure TCUSUMChartForm.FormActivate(Sender: TObject);
var var
i, xpos, ypos, hleft, hright, vtop, vbottom, imagewide : integer; w: 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 begin
maxval := -10000.0; w := MaxValue([HelpBtn.Width, ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]);
minval := 10000.0; HelpBtn.Constraints.MinWidth := w;
for i := 0 to NoGrps-1 do ResetBtn.Constraints.MinWidth := w;
begin ComputeBtn.Constraints.MinWidth := w;
if means[i] > maxval then maxval := means[i]; CloseBtn.Constraints.MinWidth := w;
if means[i] < minval then minval := means[i];
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;
// 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; 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 { Overridden to draw the V-Mark }
ypos := round(vhi * ( (maxval - means[0]) / (maxval - minval))); procedure TCUSUMChartForm.PlotMeans(ATitle, AXTitle, AYTitle, ADataTitle, AGrandMeanTitle: String;
ypos := ypos + vtop; const Groups: StrDyneVec; const Means: DblDyneVec;
xpos := round((hwide / NoGrps) + hleft); UCL, LCL, GrandMean, TargetSpec, LowerSpec, UpperSpec: double);
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos); var
BlankFrm.Image1.Canvas.Pen.Color := clBlack; alpha, beta, delta, deltaSD, gamma, d, h, k: Double;
for i := 2 to NoGrps do ser: TLineSeries;
ext: TDoubleRect;
x0, y0, x1, y1, x2, y2, x3, y3: Double;
begin begin
ypos := round(vhi * ( (maxval - means[i-1]) / (maxval - minval))); inherited;
ypos := ypos + vtop; if DeltaEdit.Text = '' then
xpos := round((hwide / NoGrps)* i + hleft); exit;
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); alpha := StrToFloat(AlphaEdit.Text);
beta := StrToFloat(BetaEdit.Text); beta := StrToFloat(BetaEdit.Text);
kfactor := 2.0 * semean; delta := StrToFloat(DeltaEdit.Text); // This is in data units
d := (2.0 / (gamma * gamma)) * ln((1.0 - beta)/alpha); deltaSD := delta / SEMean; // This is in multiples of std deviations
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 // see : https://www.itl.nist.gov/div898/handbook/pmc/section3/pmc323.htm
xpos := hleft + (grpnospc * NoGrps); // last group d := 2.0 / sqr(deltaSD) * ln((1.0 - beta)/alpha);
xpos := round(xpos + (d * grpnospc / hwide)); // plus scaled d k := deltaSD * SEMean / 2.0;
ypos := round(vhi * ( (maxval - means[NoGrps-1]) / (maxval - minval))); h := d * k;
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 ser := TLineSeries.Create(FChartFrame.Chart);
xpos := hleft + (grpnospc * NoGrps); // last group FChartFrame.Chart.AddSeries(ser);
xpos := round(xpos + (d * grpnospc / hwide)); // plus scaled d ser.SeriesColor := clBlue;
ypos := round(vhi * ( (maxval - means[NoGrps-1]) / (maxval - minval))); ser.Title := 'V-Mask';
ypos := ypos + vtop;
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos); ext := FChartFrame.Chart.GetFullExtent;
ypos := vbottom; x1 := Length(Means); // 1-based!
xpos := round(xpos - (distx * grpnospc / hwide)); y1 := Means[High(Means)] + h;
BlankFrm.Image1.Canvas.LineTo(xpos,ypos); x0 := 1;
BlankFrm.Image1.Canvas.Pen.Color := clBlack; 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; end;
function TCUMSUMFrm.Validate(out AMsg: String; out AControl: TWinControl): Boolean;
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;
function TCUSUMChartForm.Validate(out AMsg: String; out AControl: TWinControl): Boolean;
var var
x: Double; x: Double;
n: Integer;
begin begin
Result := False; Result := inherited;
if not Result then
if GroupEdit.Text = '' then
begin
AMsg := 'Group variable not specified.';
AControl := GroupEdit;
exit; exit;
end;
if MeasEdit.Text = '' then Result := false;
begin
AMsg := 'Measurement variable not specified.';
AControl := MeasEdit;
exit;
end;
if DeltaEdit.Text = '' then if (DeltaEdit.Text <> '') then
begin begin
AMsg := 'Delta parameter not specified.';
AControl := DeltaEdit;
exit;
end;
if not TryStrToFloat(DeltaEdit.Text, x) then if not TryStrToFloat(DeltaEdit.Text, x) then
begin begin
AMsg := 'Delta parameter is not a valid number.'; AMsg := 'No valid number given for Delta.';
AControl := DeltaEdit; AControl := DeltaEdit;
exit; exit;
end; end;
if AlphaEdit.Text = '' then if (AlphaEdit.Text = '') then
begin begin
AMsg := 'Alpha probability is not specified.'; AMsg := 'Alpha not specified.';
AControl := AlphaEdit; AControl := AlphaEdit;
exit; exit;
end; end;
if not TryStrToFloat(AlphaEdit.Text, x) then if not TryStrToFloat(AlphaEdit.Text, x) then
begin begin
AMsg := 'Alpha probability is not a valid number.'; AMsg := 'No valid number given for Alpha.';
AControl := AlphaEdit; AControl := AlphaEdit;
exit; exit;
end; end;
if BetaEdit.Text = '' then if (BetaEdit.Text = '') then
begin begin
AMsg := 'Beta probability is not specified.'; AMsg := 'Beta not specified.';
AControl := BetaEdit; AControl := BetaEdit;
exit; exit;
end; end;
if not TryStrtoFloat(BetaEdit.Text, x) then if not TryStrToFloat(BetaEdit.Text, x) then
begin begin
AMsg := 'Beta probability is not a valid number,'; AMsg := 'No valid number given for Beta.';
AControl := BetaEdit; AControl := BetaEdit;
exit; exit;
end; end;
end;
if TargetChk.Checked then if TargetChk.Checked then
begin begin
if TargetEdit.Text = '' then if (TargetEdit.Text = '') then
begin begin
AMsg := 'Target is not specified.'; AMsg := 'Target not specified.';
AControl := TargetEdit; AControl := TargetEdit;
exit; exit;
end; end;
if not TryStrToFloat(TargetEdit.Text, x) then if not TryStrToFloat(TargetEdit.Text, x) then
begin begin
AMsg := 'Target specification is not a valid number.'; AMsg := 'No valid number given for target specification.';
AControl := TargetEdit; AControl := TargetEdit;
exit; exit;
end; end;
@ -531,8 +342,5 @@ begin
Result := true; Result := true;
end; end;
initialization
{$I cumsumunit.lrs}
end. end.

View File

@ -1,7 +1,7 @@
inherited RChartForm: TRChartForm inherited RChartForm: TRChartForm
HelpType = htKeyword HelpType = htKeyword
HelpKeyword = 'html/RangeChart.htm' HelpKeyword = 'html/RangeChart.htm'
Caption = 'Range Chart' Caption = 'Range Control Chart'
inherited SpecsPanel: TPanel inherited SpecsPanel: TPanel
HelpType = htKeyword HelpType = htKeyword
HelpKeyword = 'html/RangeChart.htm' HelpKeyword = 'html/RangeChart.htm'

View File

@ -1,5 +1,5 @@
inherited SChartForm: TSChartForm inherited SChartForm: TSChartForm
HelpType = htKeyword HelpType = htKeyword
HelpKeyword = 'html/SControlChart.htm' HelpKeyword = 'html/SControlChart.htm'
Caption = 'Sigma Chart' Caption = 'Sigma Control Chart'
end end

View File

@ -1,7 +1,7 @@
inherited UChartForm: TUChartForm inherited UChartForm: TUChartForm
HelpType = htKeyword HelpType = htKeyword
HelpKeyword = 'html/DefectsperUnituChart.htm' HelpKeyword = 'html/DefectsperUnituChart.htm'
Caption = 'Defects per unit U Chart' Caption = 'Defects per unit U Control Chart'
OnActivate = FormActivate OnActivate = FormActivate
inherited SpecsPanel: TPanel inherited SpecsPanel: TPanel
Width = 432 Width = 432

View File

@ -3,7 +3,7 @@ inherited XBarChartForm: TXBarChartForm
Top = 215 Top = 215
HelpType = htKeyword HelpType = htKeyword
HelpKeyword = 'html/XBarChart.htm' HelpKeyword = 'html/XBarChart.htm'
Caption = 'X-Bar Chart' Caption = 'X-Bar Control Chart'
OnActivate = FormActivate OnActivate = FormActivate
inherited SpecsPanel: TPanel inherited SpecsPanel: TPanel
Width = 475 Width = 475

View File

@ -510,7 +510,7 @@ uses
BinomialUnit, KendallTauUnit, KaplanMeierUnit, BinomialUnit, KendallTauUnit, KaplanMeierUnit,
// Statistical process control // Statistical process control
XBarChartUnit, RChartUnit, SChartUnit, CUMSUMUNIT, CChartUnit, XBarChartUnit, RChartUnit, SChartUnit, CUMSUMUnit, CChartUnit,
PChartUnit, UChartUnit, PChartUnit, UChartUnit,
CorSimUnit, CorSimUnit,
@ -2130,9 +2130,9 @@ end;
// Menu "Analysis" > "Statistical Process Control" > "CUMSUM Chart" // Menu "Analysis" > "Statistical Process Control" > "CUMSUM Chart"
procedure TOS3MainFrm.mnuAnalysisSPC_CUMSUMClick(Sender: TObject); procedure TOS3MainFrm.mnuAnalysisSPC_CUMSUMClick(Sender: TObject);
begin begin
if CUMSUMFrm = nil then if CUMSUMChartForm = nil then
Application.CreateForm(TCUMSUMFrm, CUMSUMFrm); Application.CreateForm(TCUMSUMChartForm, CUMSUMChartForm);
CUMSUMFrm.ShowModal; CUMSUMChartForm.ShowModal;
end; end;