From f3a750effb3d0bb7f015e49e20c1627ba08d645a Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Sat, 12 Sep 2020 16:28:22 +0000 Subject: [PATCH] LazStats: Implement individuals xbar chart in XBarChartUnit. Add variable-selection buttons to SPC forms like in most other forms. Fix TabOrder in all SPC forms. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7663 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../basicspcunit.lfm | 122 ++++++++++----- .../basicspcunit.pas | 121 ++++++++++++++- .../cchartunit.lfm | 72 ++++++--- .../cchartunit.pas | 12 +- .../statistical_process_control/cusumunit.lfm | 84 ++++++---- .../statistical_process_control/cusumunit.pas | 8 +- .../pchartunit.lfm | 84 ++++++---- .../rchartunit.pas | 44 +++--- .../schartunit.pas | 43 +++--- .../uchartunit.lfm | 75 ++++++--- .../uchartunit.pas | 12 +- .../xbarchartunit.lfm | 79 ++++++---- .../xbarchartunit.pas | 143 ++++++++++++------ 13 files changed, 619 insertions(+), 280 deletions(-) diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.lfm b/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.lfm index 50579f163..f75123cb4 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.lfm +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.lfm @@ -31,7 +31,7 @@ object BasicSPCForm: TBasicSPCForm BevelOuter = bvNone ClientHeight = 42 ClientWidth = 357 - TabOrder = 0 + TabOrder = 3 object CloseBtn: TButton AnchorSideTop.Control = ButtonPanel AnchorSideTop.Side = asrCenter @@ -48,7 +48,7 @@ object BasicSPCForm: TBasicSPCForm Caption = 'Close' ModalResult = 11 OnClick = CloseBtnClick - TabOrder = 0 + TabOrder = 3 end object ComputeBtn: TButton AnchorSideTop.Control = ButtonPanel @@ -63,7 +63,7 @@ object BasicSPCForm: TBasicSPCForm BorderSpacing.Around = 8 Caption = 'Compute' OnClick = ComputeBtnClick - TabOrder = 1 + TabOrder = 2 end object ResetBtn: TButton AnchorSideTop.Control = ButtonPanel @@ -78,7 +78,7 @@ object BasicSPCForm: TBasicSPCForm BorderSpacing.Around = 8 Caption = 'Reset' OnClick = ResetBtnClick - TabOrder = 2 + TabOrder = 1 end object HelpBtn: TButton AnchorSideTop.Control = ButtonPanel @@ -92,7 +92,7 @@ object BasicSPCForm: TBasicSPCForm BorderSpacing.Around = 8 Caption = 'Help' OnClick = HelpBtnClick - TabOrder = 3 + TabOrder = 0 end object Bevel1: TBevel AnchorSideLeft.Control = ButtonPanel @@ -124,13 +124,12 @@ object BasicSPCForm: TBasicSPCForm AnchorSideLeft.Control = SpecsPanel AnchorSideTop.Control = VarListLabel AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = Bevel2 - AnchorSideRight.Side = asrBottom + AnchorSideRight.Control = MeasInBtn AnchorSideBottom.Control = ButtonPanel Left = 8 Height = 363 Top = 25 - Width = 174 + Width = 150 Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Left = 8 BorderSpacing.Top = 2 @@ -138,32 +137,33 @@ object BasicSPCForm: TBasicSPCForm BorderSpacing.Bottom = 8 ItemHeight = 0 OnClick = VarListClick - TabOrder = 1 + TabOrder = 0 end object GroupLabel: TLabel - AnchorSideLeft.Control = VarList - AnchorSideLeft.Side = asrBottom - AnchorSideTop.Control = VarListLabel - Left = 190 + AnchorSideLeft.Control = GroupEdit + AnchorSideTop.Control = GroupInBtn + Left = 198 Height = 15 - Top = 8 + Top = 93 Width = 105 + BorderSpacing.Top = 2 BorderSpacing.Bottom = 2 Caption = 'Group (Lot) Variable' ParentColor = False end object GroupEdit: TEdit - AnchorSideLeft.Control = VarList + AnchorSideLeft.Control = GroupInBtn AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = GroupLabel AnchorSideTop.Side = asrBottom AnchorSideRight.Control = SpecsPanel AnchorSideRight.Side = asrBottom - Left = 190 + Left = 198 Height = 23 - Top = 25 - Width = 167 + Top = 110 + Width = 159 Anchors = [akTop, akLeft, akRight] + BorderSpacing.Left = 8 BorderSpacing.Top = 2 BorderSpacing.Bottom = 8 ReadOnly = True @@ -171,34 +171,34 @@ object BasicSPCForm: TBasicSPCForm Text = 'GroupEdit' end object MeasLabel: TLabel - AnchorSideLeft.Control = VarList - AnchorSideLeft.Side = asrBottom - AnchorSideTop.Control = GroupEdit - AnchorSideTop.Side = asrBottom - Left = 190 + AnchorSideLeft.Control = MeasEdit + AnchorSideTop.Control = MeasInBtn + Left = 198 Height = 15 - Top = 56 + Top = 27 Width = 117 + BorderSpacing.Top = 2 BorderSpacing.Bottom = 2 Caption = 'Measurement Variable' ParentColor = False end object MeasEdit: TEdit - AnchorSideLeft.Control = VarList + AnchorSideLeft.Control = MeasInBtn AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = MeasLabel AnchorSideTop.Side = asrBottom AnchorSideRight.Control = SpecsPanel AnchorSideRight.Side = asrBottom - Left = 190 + Left = 198 Height = 23 - Top = 73 - Width = 167 + Top = 44 + Width = 159 Anchors = [akTop, akLeft, akRight] + BorderSpacing.Left = 8 BorderSpacing.Top = 2 BorderSpacing.Bottom = 8 ReadOnly = True - TabOrder = 3 + TabOrder = 1 Text = 'MeasEdit' end object Bevel2: TBevel @@ -210,6 +210,60 @@ object BasicSPCForm: TBasicSPCForm Width = 23 Shape = bsSpacer end + object MeasInBtn: TSpeedButton + AnchorSideLeft.Control = SpecsPanel + AnchorSideLeft.Side = asrCenter + AnchorSideTop.Control = VarList + Left = 166 + Height = 24 + Top = 25 + Width = 24 + Images = MainDataModule.ImageList + ImageIndex = 1 + OnClick = MeasInBtnClick + end + object MeasOutBtn: TSpeedButton + AnchorSideLeft.Control = SpecsPanel + AnchorSideLeft.Side = asrCenter + AnchorSideTop.Control = MeasInBtn + AnchorSideTop.Side = asrBottom + Left = 167 + Height = 22 + Top = 53 + Width = 23 + BorderSpacing.Top = 4 + Images = MainDataModule.ImageList + ImageIndex = 0 + OnClick = MeasOutBtnClick + end + object GroupInBtn: TSpeedButton + AnchorSideLeft.Control = SpecsPanel + AnchorSideLeft.Side = asrCenter + AnchorSideTop.Control = MeasOutBtn + AnchorSideTop.Side = asrBottom + Left = 166 + Height = 24 + Top = 91 + Width = 24 + BorderSpacing.Top = 16 + Images = MainDataModule.ImageList + ImageIndex = 1 + OnClick = GroupInBtnClick + end + object GroupOutBtn: TSpeedButton + AnchorSideLeft.Control = SpecsPanel + AnchorSideLeft.Side = asrCenter + AnchorSideTop.Control = GroupInBtn + AnchorSideTop.Side = asrBottom + Left = 167 + Height = 22 + Top = 119 + Width = 23 + BorderSpacing.Top = 4 + Images = MainDataModule.ImageList + ImageIndex = 0 + OnClick = GroupOutBtnClick + end end object SpecsSplitter: TSplitter Left = 360 @@ -218,7 +272,7 @@ object BasicSPCForm: TBasicSPCForm Width = 5 ResizeStyle = rsPattern end - object PageControl1: TPageControl + object PageControl: TPageControl Left = 368 Height = 426 Top = 6 @@ -262,7 +316,7 @@ object BasicSPCForm: TBasicSPCForm TabOrder = 0 end end - object ToolBar2: TToolBar + object ReportToolBar: TToolBar Left = 0 Height = 22 Top = 6 @@ -271,7 +325,7 @@ object BasicSPCForm: TBasicSPCForm BorderSpacing.Top = 6 BorderSpacing.Right = 4 BorderSpacing.Bottom = 6 - Caption = 'ToolBar2' + Caption = 'ReportToolBar' EdgeBorders = [] Images = MainDataModule.ImageList TabOrder = 1 @@ -306,7 +360,7 @@ object BasicSPCForm: TBasicSPCForm Caption = 'Chart' ClientHeight = 398 ClientWidth = 545 - object ToolBar1: TToolBar + object ChartToolBar: TToolBar Left = 0 Height = 22 Top = 6 @@ -315,7 +369,7 @@ object BasicSPCForm: TBasicSPCForm BorderSpacing.Top = 6 BorderSpacing.Right = 4 BorderSpacing.Bottom = 6 - Caption = 'ToolBar1' + Caption = 'ChartToolBar' EdgeBorders = [] Images = MainDataModule.ImageList TabOrder = 0 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 0663f98e6..5cb76d137 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.pas +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.pas @@ -6,7 +6,7 @@ interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, - StdCtrls, ComCtrls, PrintersDlgs, + StdCtrls, ComCtrls, Buttons, PrintersDlgs, Globals, MainUnit, ContextHelpUnit, ChartFrameUnit; type @@ -23,7 +23,7 @@ type MeasEdit: TEdit; PrintDialog: TPrintDialog; ReportMemo: TMemo; - PageControl1: TPageControl; + PageControl: TPageControl; Panel1: TPanel; ResetBtn: TButton; ComputeBtn: TButton; @@ -34,12 +34,16 @@ type SpecsSplitter: TSplitter; ReportPage: TTabSheet; ChartPage: TTabSheet; + MeasInBtn: TSpeedButton; + MeasOutBtn: TSpeedButton; + GroupInBtn: TSpeedButton; + GroupOutBtn: TSpeedButton; tbPrintChart: TToolButton; tbPrintReport: TToolButton; tbSaveChart: TToolButton; tbSaveReport: TToolButton; - ToolBar1: TToolBar; - ToolBar2: TToolBar; + ChartToolBar: TToolBar; + ReportToolBar: TToolBar; tbCopyReport: TToolButton; tbCopyChart: TToolButton; VarList: TListBox; @@ -49,7 +53,11 @@ type procedure FormActivate(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); + procedure GroupInBtnClick(Sender: TObject); + procedure GroupOutBtnClick(Sender: TObject); procedure HelpBtnClick(Sender: TObject); + procedure MeasInBtnClick(Sender: TObject); + procedure MeasOutBtnClick(Sender: TObject); procedure ResetBtnClick(Sender: TObject); procedure tbCopyChartClick(Sender: TObject); procedure tbCopyReportClick(Sender: TObject); @@ -59,11 +67,13 @@ type procedure tbSaveReportClick(Sender: TObject); procedure VarListClick(Sender: TObject); private + FNoGroupsAllowed: Boolean; protected FPrintY: Integer; GrpVar: Integer; MeasVar: Integer; + procedure Compute; virtual; function GetGroups: StrDyneVec; function GetFileName: String; procedure PlotMeans(ATitle, AXTitle, AYTitle, ADataTitle, AGrandMeanTitle: String; @@ -71,17 +81,37 @@ type UCL, LCL, GrandMean, TargetSpec, LowerSpec, UpperSpec: double); virtual; procedure PrintText; virtual; procedure Reset; virtual; - procedure Compute; virtual; + procedure UpdateBtnStates; virtual; function Validate(out AMsg: String; out AControl: TWinControl): Boolean; virtual; public FChartFrame: TChartFrame; + property NoGroupsAllowed: Boolean read FNoGroupsAllowed write FNoGroupsAllowed; end; var BasicSPCForm: TBasicSPCForm; +// Constants for correction of standard deviation, needed by some charts. +const + C4: array[1..24] of double = ( + 0.7979, 0.8862, 0.9213, 0.9400, 0.9515, 0.9594, 0.9650, 0.9693, + 0.9727, 0.9754, 0.9776, 0.9794, 0.9810, 0.9823, 0.9835, 0.9845, 0.9854, 0.9862, + 0.9869, 0.9876, 0.9882, 0.9887, 0.9892, 0.9896); + + D3: array[1..24] of double = ( + 0, 0, 0, 0, 0, 0.076, 0.136, 0.184, 0.223, 0.256, 0.283, 0.307, 0.328, + 0.347, 0.363, 0.378, 0.391, 0.403, 0.415, 0.425, 0.434, 0.443, + 0.451, 0.459 + ); + D4: array[1..24] of double = ( + 3.267, 2.574, 2.282, 2.114, 2.004, 1.924, 1.864, 1.816, 1.777, + 1.744, 1.717, 1.693, 1.672, 1.653, 1.637, 1.622, 1.608, 1.597, + 1.585, 1.575, 1.566, 1.557, 1.548, 1.541 + ); + + implementation {$R *.lfm} @@ -109,6 +139,7 @@ end; procedure TBasicSPCForm.Compute; begin + // end; @@ -133,7 +164,7 @@ begin if GroupEdit.Visible and (cellstring = GroupEdit.Text) then GrpVar := i; if MeasEdit.Visible and (cellstring = MeasEdit.Text) then MeasVar := i; end; - if GroupEdit.Visible and (GrpVar = -1) then + if not NoGroupsAllowed and GroupEdit.Visible and (GrpVar = -1) then begin GroupEdit.SetFocus; ErrorMsg('Group variable not found.'); @@ -147,6 +178,8 @@ begin end; Compute; + + UpdateBtnStates; end; procedure TBasicSPCForm.FormActivate(Sender: TObject); @@ -225,6 +258,31 @@ begin end; +procedure TBasicSPCForm.GroupInBtnClick(Sender: TObject); +var + index: integer; +begin + index := VarList.ItemIndex; + if (index > -1) and (GroupEdit.Text = '') then + begin + GroupEdit.Text := VarList.Items[index]; + VarList.Items.Delete(index); + UpdateBtnStates; + end; +end; + + +procedure TBasicSPCForm.GroupOutBtnClick(Sender: TObject); +begin + if GroupEdit.Text <> '' then + begin + VarList.Items.Add(GroupEdit.Text); + GroupEdit.Text := ''; + UpdateBtnStates; + end; +end; + + procedure TBasicSPCForm.HelpBtnClick(Sender: TObject); begin if ContextHelpForm = nil then @@ -233,6 +291,31 @@ begin end; +procedure TBasicSPCForm.MeasInBtnClick(Sender: TObject); +var + index: integer; +begin + index := VarList.ItemIndex; + if (index > -1) and (MeasEdit.Text = '') then + begin + MeasEdit.Text := VarList.Items[index]; + VarList.Items.Delete(index); + UpdateBtnStates; + end; +end; + + +procedure TBasicSPCForm.MeasOutBtnClick(Sender: TObject); +begin + if MeasEdit.Text <> '' then + begin + VarList.Items.Add(MeasEdit.Text); + MeasEdit.Text := ''; + UpdateBtnStates; + end; +end; + + procedure TBasicSPCForm.PlotMeans(ATitle, AXTitle, AYTitle, ADataTitle, AGrandMeanTitle: String; const Groups: StrDyneVec; const Means: DblDyneVec; UCL, LCL, GrandMean, TargetSpec, LowerSpec, UpperSpec: double); @@ -368,6 +451,7 @@ begin VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); FChartFrame.Clear; (FChartFrame.Chart.AxisList[2].Marks.Source as TListChartSource).Clear; + UpdateBtnStates; end; @@ -376,6 +460,7 @@ begin Reset; end; + procedure TBasicSPCForm.tbCopyChartClick(Sender: TObject); begin FChartFrame.Chart.CopyToClipboardBitmap; @@ -429,6 +514,23 @@ begin end; +procedure TBasicSPCForm.UpdateBtnStates; +begin + MeasInBtn.Enabled := (VarList.ItemIndex <> -1) and (MeasEdit.Text = ''); + MeasOutBtn.Enabled := (MeasEdit.Text <> ''); + GroupInBtn.Enabled := (VarList.ItemIndex <> -1) and (GroupEdit.Text = ''); + GroupOutBtn.Enabled := (GroupEdit.Text <> ''); + + tbSaveReport.Enabled := ReportMemo.Lines.Count > 0; + tbPrintReport.Enabled := ReportMemo.Lines.Count > 0; + tbCopyReport.Enabled := ReportMemo.Lines.Count > 0; + + tbSaveChart.Enabled := FChartFrame.Chart.SeriesCount > 0; + tbPrintChart.Enabled := FChartFrame.Chart.SeriesCount > 0; + tbCopyChart.Enabled := FChartFrame.Chart.SeriesCount > 0; +end; + + function TBasicSPCForm.Validate(out AMsg: String; out AControl: TWinControl): Boolean; var x: Double; @@ -450,9 +552,11 @@ end; procedure TBasicSPCForm.VarListClick(Sender: TObject); -var - index: integer; +//var +// index: integer; begin + UpdateBtnStates; + { index := VarList.ItemIndex; if index > -1 then begin @@ -462,6 +566,7 @@ begin MeasEdit.Text := VarList.Items[index]; VarList.Items.Delete(index); end; + } end; end. diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/cchartunit.lfm b/applications/lazstats/source/forms/analysis/statistical_process_control/cchartunit.lfm index 96792e479..20a88ba1a 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/cchartunit.lfm +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/cchartunit.lfm @@ -14,6 +14,7 @@ inherited CChartForm: TCChartForm Top = 378 Width = 440 ClientWidth = 440 + TabOrder = 4 inherited CloseBtn: TButton Left = 385 end @@ -32,42 +33,62 @@ inherited CChartForm: TCChartForm end inherited VarList: TListBox Height = 345 - Width = 216 + Width = 192 end inherited GroupLabel: TLabel - Left = 232 + Left = 240 + Top = 274 Visible = False end inherited GroupEdit: TEdit - Left = 232 - Width = 208 + Left = 240 + Top = 291 + Width = 200 + TabOrder = 3 Visible = False end inherited MeasLabel: TLabel - Left = 232 + Left = 240 end inherited MeasEdit: TEdit - Left = 232 - Width = 208 + Left = 240 + Width = 200 end inherited Bevel2: TBevel Left = 209 end - object SigmaOptns: TRadioGroup[8] + inherited MeasInBtn: TSpeedButton + Left = 208 + end + inherited MeasOutBtn: TSpeedButton + Left = 209 + end + inherited GroupInBtn: TSpeedButton + Left = 208 + Top = 272 + Anchors = [akLeft] + Visible = False + end + inherited GroupOutBtn: TSpeedButton + Left = 209 + Top = 300 + Visible = False + end + object SigmaOptns: TRadioGroup[12] AnchorSideLeft.Control = MeasEdit AnchorSideTop.Control = MeasEdit AnchorSideTop.Side = asrBottom AnchorSideRight.Control = SpecsPanel AnchorSideRight.Side = asrBottom - Left = 232 + Left = 240 Height = 128 - Top = 128 - Width = 208 + Top = 99 + Width = 200 Anchors = [akTop, akLeft, akRight] AutoFill = True BorderSpacing.Top = 32 BorderSpacing.Bottom = 8 - Caption = 'No. of Sigma Units for UCL and LCL' + Caption = 'Sigma Units for UCL and LCL' ChildSizing.LeftRightSpacing = 12 ChildSizing.TopBottomSpacing = 6 ChildSizing.EnlargeHorizontal = crsHomogenousChildResize @@ -77,15 +98,15 @@ inherited CChartForm: TCChartForm ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.ControlsPerLine = 1 ClientHeight = 108 - ClientWidth = 204 + ClientWidth = 196 ItemIndex = 0 Items.Strings = ( - '3 Sigma (default)' + '3 Sigma' '2 Sigma' '1 Sigma' 'x Sigmas with x = ' ) - TabOrder = 4 + TabOrder = 2 object XSigmaEdit: TEdit AnchorSideRight.Control = SigmaOptns AnchorSideRight.Side = asrBottom @@ -93,7 +114,7 @@ inherited CChartForm: TCChartForm Left = 128 Height = 23 Top = 80 - Width = 64 + Width = 56 Alignment = taRightJustify Anchors = [akLeft, akRight, akBottom] TabOrder = 0 @@ -105,7 +126,7 @@ inherited CChartForm: TCChartForm Left = 443 Height = 420 end - inherited PageControl1: TPageControl + inherited PageControl: TPageControl Left = 451 Height = 408 Width = 470 @@ -113,15 +134,26 @@ inherited CChartForm: TCChartForm ClientHeight = 380 ClientWidth = 462 inherited Panel1: TPanel - Height = 368 + Height = 340 Width = 450 - ClientHeight = 364 + ClientHeight = 336 ClientWidth = 446 inherited ReportMemo: TMemo - Height = 356 + Height = 328 Width = 438 end end + inherited ReportToolBar: TToolBar + Width = 458 + end end end + inherited SaveDialog: TSaveDialog + Left = 536 + Top = 96 + end + inherited PrintDialog: TPrintDialog + Left = 536 + Top = 154 + end end diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/cchartunit.pas b/applications/lazstats/source/forms/analysis/statistical_process_control/cchartunit.pas index 26b506224..bc356fb62 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/cchartunit.pas +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/cchartunit.pas @@ -80,17 +80,17 @@ begin try lReport.Add('DEFECTS c CONTROL CHART RESULTS'); lReport.Add(''); + lReport.Add('No. of samples: %8d', [numData]); //NoCases]); + lReport.Add('Total Nonconformities: %8.3f', [GrandMean]); + lReport.Add('Poisson mean and variance: %8.3f', [meanc]); + lReport.Add('Lower Control Limit: %8.3f', [LCL]); + lReport.Add('Upper Control Limit: %8.3f', [UCL]); + lReport.Add(''); lReport.Add('Sample Number of '); lReport.Add(' Nonconformities'); lReport.Add('------ ---------------'); for i := 1 to NoCases do lReport.Add('%6d %15.2f', [i, means[i]]); - lReport.Add(''); - lReport.Add('Total Nonconformities: %8.3f', [GrandMean]); - lReport.Add('No. of samples: %8d', [numData]); //NoCases]); - lReport.Add('Poisson mean and variance: %8.3f', [meanc]); - lReport.Add('Lower Control Limit: %8.3f', [LCL]); - lReport.Add('Upper Control Limit: %8.3f', [UCL]); ReportMemo.Lines.Assign(lReport); finally diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/cusumunit.lfm b/applications/lazstats/source/forms/analysis/statistical_process_control/cusumunit.lfm index 9c4412232..491da1aa1 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/cusumunit.lfm +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/cusumunit.lfm @@ -1,75 +1,90 @@ inherited CUSUMChartForm: TCUSUMChartForm + Height = 424 HelpType = htKeyword HelpKeyword = 'html/CUMSUMChart.htm' Caption = 'Cumulative Sum Control Chart' + ClientHeight = 424 OnActivate = FormActivate ShowHint = True inherited SpecsPanel: TPanel + Height = 424 Width = 432 + ClientHeight = 424 ClientWidth = 432 inherited ButtonPanel: TPanel + Top = 382 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 inherited VarList: TListBox - Width = 212 - TabOrder = 0 + Height = 349 + Width = 188 end inherited GroupLabel: TLabel - Left = 228 + Left = 236 end inherited GroupEdit: TEdit - Left = 228 - Width = 204 - TabOrder = 1 + Left = 236 + Width = 196 end inherited MeasLabel: TLabel - Left = 228 + Left = 236 end inherited MeasEdit: TEdit - Left = 228 - Width = 204 - TabOrder = 2 + Left = 236 + Width = 196 end inherited Bevel2: TBevel Left = 205 end - object GroupBox1: TGroupBox[8] + inherited MeasInBtn: TSpeedButton + Left = 204 + end + inherited MeasOutBtn: TSpeedButton + Left = 205 + end + inherited GroupInBtn: TSpeedButton + AnchorSideLeft.Control = MeasInBtn + AnchorSideLeft.Side = asrTop + Left = 204 + end + inherited GroupOutBtn: TSpeedButton + AnchorSideLeft.Control = GroupInBtn + Left = 205 + end + object GroupBox1: TGroupBox[12] AnchorSideLeft.Control = MeasEdit AnchorSideTop.Control = GroupBox2 AnchorSideTop.Side = asrBottom AnchorSideRight.Control = MeasEdit AnchorSideRight.Side = asrBottom - Left = 228 + Left = 236 Height = 153 - Top = 202 - Width = 204 + Top = 239 + Width = 196 Anchors = [akTop, akLeft, akRight] AutoSize = True BorderSpacing.Top = 16 + BorderSpacing.Bottom = 8 Caption = 'V-Mask Specifications' ClientHeight = 133 - ClientWidth = 200 + ClientWidth = 192 TabOrder = 4 object Label4: TLabel AnchorSideLeft.Control = GroupBox1 @@ -116,7 +131,7 @@ inherited CUSUMChartForm: TCUSUMChartForm Height = 23 Hint = 'Detection level for a shift in the process mean, '#13#10'expressed in data units (default), or'#13#10'as a multiple of the standard deviation of the '#13#10'data points (when "Normalized CUSUM" is checked).' Top = 2 - Width = 78 + Width = 70 Alignment = taRightJustify Anchors = [akTop, akLeft, akRight] BorderSpacing.Top = 2 @@ -136,7 +151,7 @@ inherited CUSUMChartForm: TCUSUMChartForm Height = 23 Hint = 'Probability of concluding that a shift in the process has occurred, when in fact it did not. ' Top = 29 - Width = 78 + Width = 70 Alignment = taRightJustify Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 8 @@ -156,7 +171,7 @@ inherited CUSUMChartForm: TCUSUMChartForm Height = 23 Hint = 'Probability of not detecting that a shift in the process mean has, in fact, occurred' Top = 56 - Width = 78 + Width = 70 Alignment = taRightJustify Anchors = [akTop, akLeft, akRight] BorderSpacing.Top = 4 @@ -175,7 +190,7 @@ inherited CUSUMChartForm: TCUSUMChartForm Left = 12 Height = 17 Top = 104 - Width = 180 + Width = 172 Anchors = [akTop, akLeft, akRight] BorderSpacing.Top = 2 BorderSpacing.Bottom = 12 @@ -194,23 +209,23 @@ inherited CUSUMChartForm: TCUSUMChartForm ParentColor = False end end - object GroupBox2: TGroupBox[9] + object GroupBox2: TGroupBox[13] AnchorSideLeft.Control = GroupBox1 - AnchorSideTop.Control = MeasEdit + AnchorSideTop.Control = GroupEdit AnchorSideTop.Side = asrBottom AnchorSideRight.Control = MeasEdit AnchorSideRight.Side = asrBottom - Left = 228 + Left = 236 Height = 74 - Top = 112 - Width = 204 + Top = 149 + Width = 196 Anchors = [akTop, akLeft, akRight] AutoSize = True BorderSpacing.Top = 16 BorderSpacing.Bottom = 8 Caption = 'Option:' ClientHeight = 54 - ClientWidth = 200 + ClientWidth = 192 TabOrder = 3 object TargetChk: TCheckBox AnchorSideLeft.Control = GroupBox2 @@ -261,19 +276,28 @@ inherited CUSUMChartForm: TCUSUMChartForm end inherited SpecsSplitter: TSplitter Left = 435 + Height = 424 end - inherited PageControl1: TPageControl + inherited PageControl: TPageControl Left = 443 + Height = 412 Width = 478 inherited ReportPage: TTabSheet + ClientHeight = 384 ClientWidth = 470 inherited Panel1: TPanel + Height = 344 Width = 458 + ClientHeight = 340 ClientWidth = 454 inherited ReportMemo: TMemo + Height = 332 Width = 446 end end + inherited ReportToolBar: TToolBar + Width = 466 + end end end end diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/cusumunit.pas b/applications/lazstats/source/forms/analysis/statistical_process_control/cusumunit.pas index bc8139d0b..6797a7622 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/cusumunit.pas +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/cusumunit.pas @@ -175,6 +175,7 @@ begin lReport.Clear; lReport.Add('CUSUM Chart Results'); lReport.Add(''); + lReport.Add('Number of Values: %8d', [numValues]); 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]); @@ -239,14 +240,15 @@ begin DisableAutoSizing; try - GroupBox2.Anchors := GroupBox2.Anchors - [akRight]; + GroupBox1.Anchors := GroupBox1.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]; + Constraints.MinHeight := GroupBox1.Top + GroupBox1.Height + GroupBox1.BorderSpacing.Bottom + ButtonPanel.Height; + Height := 1; // enforce autosizing of height + GroupBox1.Anchors := GroupBox1.Anchors + [akRight]; finally EnableAutoSizing; end; diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/pchartunit.lfm b/applications/lazstats/source/forms/analysis/statistical_process_control/pchartunit.lfm index f92bc1e81..9b0a9cfbe 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/pchartunit.lfm +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/pchartunit.lfm @@ -11,6 +11,7 @@ inherited PChartForm: TPChartForm inherited ButtonPanel: TPanel Width = 456 ClientWidth = 456 + TabOrder = 6 inherited CloseBtn: TButton Left = 401 end @@ -28,62 +29,82 @@ inherited PChartForm: TPChartForm end end inherited VarList: TListBox - Width = 224 + Width = 200 end inherited GroupLabel: TLabel - Left = 240 + Left = 248 + Top = 328 Visible = False end inherited GroupEdit: TEdit - Left = 240 - Width = 216 + Left = 248 + Top = 345 + Width = 208 + TabOrder = 5 Visible = False end inherited MeasLabel: TLabel - Left = 240 + Left = 248 end inherited MeasEdit: TEdit - Left = 240 - Width = 216 + Left = 248 + Width = 208 end inherited Bevel2: TBevel Left = 217 end - object Label3: TLabel[8] + inherited MeasInBtn: TSpeedButton + Left = 216 + end + inherited MeasOutBtn: TSpeedButton + Left = 217 + end + inherited GroupInBtn: TSpeedButton + Left = 216 + Top = 326 + Anchors = [akLeft] + Visible = False + end + inherited GroupOutBtn: TSpeedButton + Left = 217 + Top = 354 + Visible = False + end + object Label3: TLabel[12] AnchorSideLeft.Control = Label4 AnchorSideTop.Control = NEdit AnchorSideTop.Side = asrCenter AnchorSideRight.Control = NEdit Left = 270 Height = 15 - Top = 124 + Top = 95 Width = 114 Anchors = [akTop, akRight] BorderSpacing.Right = 8 Caption = 'No. of Parts Sampled:' ParentColor = False end - object NEdit: TEdit[9] + object NEdit: TEdit[13] AnchorSideTop.Control = MeasEdit AnchorSideTop.Side = asrBottom AnchorSideRight.Control = MeasEdit AnchorSideRight.Side = asrBottom Left = 392 Height = 23 - Top = 120 + Top = 91 Width = 64 Alignment = taRightJustify Anchors = [akTop, akRight] BorderSpacing.Top = 24 - TabOrder = 4 + TabOrder = 2 Text = 'NEdit' end - object Label4: TLabel[10] + object Label4: TLabel[14] AnchorSideTop.Control = PEdit AnchorSideTop.Side = asrCenter Left = 272 Height = 30 - Top = 147 + Top = 118 Width = 108 Alignment = taRightJustify Anchors = [akTop, akRight] @@ -91,36 +112,36 @@ inherited PChartForm: TPChartForm Caption = 'Expected Proportion'#13#10'of Defects:' ParentColor = False end - object PEdit: TEdit[11] + object PEdit: TEdit[15] AnchorSideTop.Control = NEdit AnchorSideTop.Side = asrBottom AnchorSideRight.Control = MeasEdit AnchorSideRight.Side = asrBottom Left = 392 Height = 23 - Top = 151 + Top = 122 Width = 64 Alignment = taRightJustify Anchors = [akTop, akRight] BorderSpacing.Top = 8 - TabOrder = 5 + TabOrder = 3 Text = 'PEdit' end - object SigmaOpts: TRadioGroup[12] + object SigmaOpts: TRadioGroup[16] AnchorSideLeft.Control = MeasEdit AnchorSideTop.Control = PEdit AnchorSideTop.Side = asrBottom AnchorSideRight.Control = SpecsPanel AnchorSideRight.Side = asrBottom - Left = 240 + Left = 248 Height = 128 - Top = 198 - Width = 216 + Top = 169 + Width = 208 Anchors = [akTop, akLeft, akRight] AutoFill = True BorderSpacing.Top = 24 BorderSpacing.Bottom = 8 - Caption = 'No. of Sigma Units for UCL and LCL' + Caption = 'Sigma Units for UCL and LCL' ChildSizing.LeftRightSpacing = 12 ChildSizing.TopBottomSpacing = 6 ChildSizing.EnlargeHorizontal = crsHomogenousChildResize @@ -130,15 +151,15 @@ inherited PChartForm: TPChartForm ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.ControlsPerLine = 1 ClientHeight = 108 - ClientWidth = 212 + ClientWidth = 204 ItemIndex = 0 Items.Strings = ( - '3 Sigma (default)' + '3 Sigma' '2 Sigma' '1 Sigma' 'x Sigmas with x = ' ) - TabOrder = 6 + TabOrder = 4 object XSigmaEdit: TEdit AnchorSideRight.Control = SigmaOpts AnchorSideRight.Side = asrBottom @@ -146,7 +167,7 @@ inherited PChartForm: TPChartForm Left = 128 Height = 23 Top = 80 - Width = 72 + Width = 64 Alignment = taRightJustify Anchors = [akLeft, akRight, akBottom] TabOrder = 0 @@ -157,7 +178,7 @@ inherited PChartForm: TPChartForm inherited SpecsSplitter: TSplitter Left = 459 end - inherited PageControl1: TPageControl + inherited PageControl: TPageControl Left = 467 Width = 454 inherited ReportPage: TTabSheet @@ -169,6 +190,15 @@ inherited PChartForm: TPChartForm Width = 422 end end + inherited ReportToolBar: TToolBar + Width = 442 + end end end + inherited SaveDialog: TSaveDialog + Left = 544 + end + inherited PrintDialog: TPrintDialog + Left = 544 + end end diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/rchartunit.pas b/applications/lazstats/source/forms/analysis/statistical_process_control/rchartunit.pas index c9078bbde..8992d180f 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/rchartunit.pas +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/rchartunit.pas @@ -23,24 +23,13 @@ implementation uses Math, - Globals, Utils, MainUnit; + Globals, Utils, MainUnit, DataProcs; procedure TRChartForm.Compute; -const - D3: array[1..24] of double = ( - 0,0,0,0,0,0.076,0.136,0.184,0.223,0.256,0.283,0.307,0.328, - 0.347,0.363,0.378,0.391,0.403,0.415,0.425,0.434,0.443, - 0.451,0.459 - ); - D4: array[1..24] of double = ( - 3.267, 2.574, 2.282, 2.114, 2.004, 1.924, 1.864, 1.816,1.777, - 1.744, 1.717, 1.693, 1.672, 1.653, 1.637, 1.622, 1.608,1.597, - 1.585, 1.575, 1.566, 1.557, 1.548, 1.541 - ); var i, j: Integer; grp: String; - grpIndex, grpSize, oldGrpSize, numGrps: Integer; + grpIndex, grpSize, oldGrpSize, numGrps, numValues: Integer; groups: StrDyneVec = nil; means: DblDyneVec = nil; stddev: DblDyneVec = nil; @@ -71,6 +60,11 @@ begin grandRange := 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 begin @@ -115,12 +109,12 @@ begin stddev[i] := sqrt(stddev[i]); means[i] := means[i] / count[i]; end; - seMean := seMean - grandMean * grandMean / NoCases; - seMean := seMean / (NoCases - 1); + seMean := seMean - grandMean * grandMean / numValues; + seMean := seMean / (numValues - 1); seMean := sqrt(seMean); GrandSD := seMean; - seMean := seMean / sqrt(NoCases); - grandMean := grandMean / NoCases; + seMean := seMean / sqrt(numValues); + grandMean := grandMean / numValues; grandRange := grandRange / numGrps; D3Value := D3[grpSize-1]; D4Value := D4[grpSize-1]; @@ -132,17 +126,19 @@ begin try lReport.Add('Range Chart Results'); lReport.Add(''); + lReport.Add('Number of values: %8d', [numValues]); + lReport.Add('Grand Mean: %8.3f', [GrandMean]); + lReport.Add('Standard Deviation: %8.3f', [GrandSD]); + lReport.Add('Standard Error of Mean: %8.3f', [semean]); + lReport.Add(''); + lReport.Add('Mean Range: %8.3f', [GrandRange]); + lReport.Add('Lower Control Limit: %8.3f', [LCL]); + lReport.Add('Upper Control Limit: %8.3f', [UCL]); + lReport.Add(''); lReport.Add(' Group Size Mean Std.Dev. Ranges '); lReport.Add('------- ---- -------- -------- --------'); for i := 0 to numGrps-1 do lReport.Add('%7d %4d %8.2f %8.2f %8.2f', [i+1, count[i], means[i], stddev[i], ranges[i]]); - lReport.Add(''); - lReport.Add('Grand Mean: %8.3f', [GrandMean]); - lReport.Add('Standard Deviation: %8.3f', [GrandSD]); - lReport.Add('Standard Error of Mean: %8.3f', [semean]); - lReport.Add('Mean Range: %8.3f', [GrandRange]); - lReport.Add('Lower Control Limit: %8.3f', [LCL]); - lReport.Add('Upper Control Limit: %8.3f', [UCL]); ReportMemo.Lines.Assign(lReport); finally diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.pas b/applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.pas index 68256ee43..5e5beca15 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.pas +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.pas @@ -28,17 +28,6 @@ uses Math, Globals, MathUnit, Utils, MainUnit, DataProcs; procedure TSChartForm.Compute; -const - D3: array[1..24] of double = ( - 0,0,0,0,0,0.076,0.136,0.184,0.223,0.256,0.283,0.307,0.328, - 0.347,0.363,0.378,0.391,0.403,0.415,0.425,0.434,0.443, - 0.451,0.459 - ); - D4 : array[1..24] of double = ( - 3.267,2.574,2.282,2.114,2.004,1.924,1.864,1.816,1.777, - 1.744,1.717,1.693,1.672,1.653,1.637,1.622,1.608,1.597, - 1.585,1.575,1.566,1.557,1.548,1.541 - ); var UCL, LCL: Double; grpSize, oldGrpSize: Integer; @@ -48,6 +37,7 @@ var stddev: DblDyneVec = nil; count: IntDyneVec = nil; numGrps: Integer = 0; + numValues: Integer = 0; grp: String; grpIndex: Integer; X, Xsq: Double; @@ -75,6 +65,11 @@ begin grandSigma := 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 @@ -83,7 +78,7 @@ begin for i := 1 to NoCases do begin if not GoodRecord(i, Length(ColNoSelected), ColNoSelected) then continue; - grp := Trim(OS3MainFrm.DataGrid.Cells[GrpVar,i]); + grp := Trim(OS3MainFrm.DataGrid.Cells[GrpVar, i]); grpIndex := IndexOfString(groups, grp); if grpIndex = j then begin @@ -115,12 +110,12 @@ begin exit; end; - seMean := seMean - sqr(grandMean)/NoCases; - seMean := seMean / (NoCases - 1); + seMean := seMean - sqr(grandMean)/numValues; + seMean := seMean / (numValues - 1); seMean := sqrt(seMean); grandSD := seMean; - seMean := seMean / sqrt(NoCases); - grandMean := grandMean / NoCases; + seMean := seMean / sqrt(numValues); + grandMean := grandMean / numValues; grandSigma := grandSigma / numGrps; D3Value := D3[grpSize-1]; D4Value := D4[grpSize-1]; @@ -139,17 +134,19 @@ begin try lReport.Add('Sigma Chart Results'); lReport.Add(''); + lReport.Add('Number of values: %8d', [numValues]); + lReport.Add('Grand Mean: %8.3f', [grandMean]); + lReport.Add('Standard Deviation: %8.3f', [grandSD]); + lReport.Add('Standard Error of Mean: %8.3f', [seMean]); + lReport.Add(''); + lReport.Add('Mean Sigma: %8.3f', [grandSigma]); + lReport.Add('Lower Control Limit: %8.3f', [LCL]); + lReport.Add('Upper Control Limit: %8.3f', [UCL]); + lReport.Add(''); lReport.Add(' Group Size Mean Std.Dev.'); lReport.Add('------- ---- -------- --------'); for i := 0 to numGrps - 1 do lReport.Add('%7d %4d %8.2f %8.2f', [i+1, count[i], means[i], stddev[i]]); - lReport.Add(''); - lReport.Add('Grand Mean: %8.3f', [grandMean]); - lReport.Add('Standard Deviation: %8.3f', [grandSD]); - lReport.Add('Standard Error of Mean: %8.3f', [seMean]); - lReport.Add('Mean Sigma: %8.3f', [grandSigma]); - lReport.Add('Lower Control Limit: %8.3f', [LCL]); - lReport.Add('Upper Control Limit: %8.3f', [UCL]); ReportMemo.Lines.Assign(lReport); finally 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 8f518f2d3..e091d383a 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/uchartunit.lfm +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/uchartunit.lfm @@ -9,6 +9,7 @@ inherited UChartForm: TUChartForm inherited ButtonPanel: TPanel Width = 432 ClientWidth = 432 + TabOrder = 5 inherited CloseBtn: TButton Left = 377 end @@ -26,34 +27,54 @@ inherited UChartForm: TUChartForm end end inherited VarList: TListBox - Width = 212 + Width = 188 end inherited GroupLabel: TLabel - Left = 228 + Left = 236 + Top = 302 Visible = False end inherited GroupEdit: TEdit - Left = 228 - Width = 204 + Left = 236 + Top = 319 + Width = 196 + TabOrder = 4 Visible = False end inherited MeasLabel: TLabel - Left = 228 + Left = 236 end inherited MeasEdit: TEdit - Left = 228 - Width = 204 + Left = 236 + Width = 196 end inherited Bevel2: TBevel Left = 205 end - object Label3: TLabel[8] + inherited MeasInBtn: TSpeedButton + Left = 204 + end + inherited MeasOutBtn: TSpeedButton + Left = 205 + end + inherited GroupInBtn: TSpeedButton + Left = 204 + Top = 300 + Anchors = [akLeft] + Visible = False + end + inherited GroupOutBtn: TSpeedButton + Left = 205 + Top = 328 + Visible = False + end + object Label3: TLabel[12] AnchorSideTop.Control = NoInspEdit AnchorSideTop.Side = asrCenter AnchorSideRight.Control = NoInspEdit Left = 288 Height = 30 - Top = 112 + Top = 83 Width = 73 Alignment = taRightJustify Anchors = [akTop, akRight] @@ -61,36 +82,36 @@ inherited UChartForm: TUChartForm Caption = 'No. inspected'#13#10'per group:' ParentColor = False end - object NoInspEdit: TEdit[9] + object NoInspEdit: TEdit[13] AnchorSideTop.Control = MeasEdit AnchorSideTop.Side = asrBottom AnchorSideRight.Control = MeasEdit AnchorSideRight.Side = asrBottom Left = 369 Height = 23 - Top = 116 + Top = 87 Width = 63 Alignment = taRightJustify Anchors = [akTop, akRight] BorderSpacing.Top = 20 - TabOrder = 4 + TabOrder = 2 Text = 'NoInspEdit' end - object SigmaOpts: TRadioGroup[10] + object SigmaOpts: TRadioGroup[14] AnchorSideLeft.Control = MeasEdit AnchorSideTop.Control = NoInspEdit AnchorSideTop.Side = asrBottom AnchorSideRight.Control = SpecsPanel AnchorSideRight.Side = asrBottom - Left = 228 + Left = 236 Height = 128 - Top = 163 - Width = 204 + Top = 134 + Width = 196 Anchors = [akTop, akLeft, akRight] AutoFill = True BorderSpacing.Top = 24 BorderSpacing.Bottom = 8 - Caption = 'No. of Sigma Units for UCL and LCL' + Caption = 'Sigma Units for UCL and LCL' ChildSizing.LeftRightSpacing = 12 ChildSizing.TopBottomSpacing = 6 ChildSizing.EnlargeHorizontal = crsHomogenousChildResize @@ -100,15 +121,15 @@ inherited UChartForm: TUChartForm ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.ControlsPerLine = 1 ClientHeight = 108 - ClientWidth = 200 + ClientWidth = 192 ItemIndex = 0 Items.Strings = ( - '3 Sigma (default)' + '3 Sigma' '2 Sigma' '1 Sigma' 'x Sigmas with x = ' ) - TabOrder = 5 + TabOrder = 3 object XSigmaEdit: TEdit AnchorSideRight.Control = SigmaOpts AnchorSideRight.Side = asrBottom @@ -116,7 +137,7 @@ inherited UChartForm: TUChartForm Left = 128 Height = 23 Top = 80 - Width = 60 + Width = 52 Alignment = taRightJustify Anchors = [akLeft, akRight, akBottom] TabOrder = 0 @@ -127,7 +148,7 @@ inherited UChartForm: TUChartForm inherited SpecsSplitter: TSplitter Left = 435 end - inherited PageControl1: TPageControl + inherited PageControl: TPageControl Left = 443 Width = 478 inherited ReportPage: TTabSheet @@ -139,15 +160,21 @@ inherited UChartForm: TUChartForm Width = 446 end end - inherited ToolBar2: TToolBar + inherited ReportToolBar: TToolBar Width = 466 end end inherited ChartPage: TTabSheet ClientWidth = 470 - inherited ToolBar1: TToolBar + inherited ChartToolBar: TToolBar Width = 466 end end end + inherited SaveDialog: TSaveDialog + Left = 544 + end + inherited PrintDialog: TPrintDialog + Left = 544 + end end diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/uchartunit.pas b/applications/lazstats/source/forms/analysis/statistical_process_control/uchartunit.pas index 3e7595065..12696a245 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/uchartunit.pas +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/uchartunit.pas @@ -84,17 +84,17 @@ begin try lReport.Add('DEFECTS c CONTROL CHART RESULTS'); lReport.Add(''); - lReport.Add('Sample No Defects Defects Per Unit'); - lReport.Add('------ ---------- ----------------'); - for i := 0 to numSamples-1 do - lReport.Add('%6d %10.2f %16.2f', [i, means[i], defPerUnit[i]]); - lReport.Add(''); - lReport.Add('Total Nonconformities: %8.2f', [grandMean]); lReport.Add('No. of Samples: %8d', [numSamples]); + lReport.Add('Total Nonconformities: %8.2f', [grandMean]); lReport.Add('Def. / unit Mean: %8.3f', [meanC]); lReport.Add(' and StdDev: %8.3f', [stdDevC]); lReport.Add('Lower Control Limit: %8.3f', [LCL]); lReport.Add('Upper Control Limit: %8.3f', [UCL]); + lReport.Add(''); + lReport.Add('Sample No Defects Defects Per Unit'); + lReport.Add('------ ---------- ----------------'); + for i := 0 to numSamples-1 do + lReport.Add('%6d %10.2f %16.2f', [i, means[i], defPerUnit[i]]); ReportMemo.Lines.Assign(lReport); finally 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 d9cb09f8b..b240dc531 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/xbarchartunit.lfm +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/xbarchartunit.lfm @@ -1,16 +1,22 @@ inherited XBarChartForm: TXBarChartForm Left = 572 + Height = 443 Top = 215 HelpType = htKeyword HelpKeyword = 'html/XBarChart.htm' Caption = 'X-Bar Control Chart' + ClientHeight = 443 OnActivate = FormActivate inherited SpecsPanel: TPanel + Height = 443 Width = 475 + ClientHeight = 443 ClientWidth = 475 inherited ButtonPanel: TPanel + Top = 401 Width = 475 ClientWidth = 475 + TabOrder = 5 inherited CloseBtn: TButton Left = 420 end @@ -28,40 +34,53 @@ inherited XBarChartForm: TXBarChartForm end end inherited VarList: TListBox - Width = 233 + Height = 368 + Width = 209 end inherited GroupLabel: TLabel - Left = 249 + Left = 257 end inherited GroupEdit: TEdit - Left = 249 - Width = 226 + Left = 257 + Width = 218 end inherited MeasLabel: TLabel - Left = 249 + Left = 257 end inherited MeasEdit: TEdit AnchorSideRight.Control = LevelOptns - Left = 249 - Width = 226 + Left = 257 + Width = 218 end inherited Bevel2: TBevel Left = 226 end - object SigmaOpts: TRadioGroup[8] + inherited MeasInBtn: TSpeedButton + Left = 225 + end + inherited MeasOutBtn: TSpeedButton + Left = 226 + end + inherited GroupInBtn: TSpeedButton + Left = 225 + end + inherited GroupOutBtn: TSpeedButton + Left = 226 + end + object SigmaOpts: TRadioGroup[12] AnchorSideLeft.Control = MeasEdit - AnchorSideTop.Control = MeasEdit + AnchorSideTop.Control = GroupEdit AnchorSideTop.Side = asrBottom AnchorSideRight.Control = LevelOptns AnchorSideRight.Side = asrBottom - Left = 249 + Left = 257 Height = 128 - Top = 108 - Width = 226 + Top = 145 + Width = 218 Anchors = [akTop, akLeft, akRight] AutoFill = True BorderSpacing.Top = 12 - Caption = 'No. of Sigma Units for UCL and LCL' + Caption = 'Sigma Units for UCL and LCL' ChildSizing.LeftRightSpacing = 12 ChildSizing.TopBottomSpacing = 6 ChildSizing.EnlargeHorizontal = crsHomogenousChildResize @@ -71,15 +90,15 @@ inherited XBarChartForm: TXBarChartForm ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.ControlsPerLine = 1 ClientHeight = 108 - ClientWidth = 222 + ClientWidth = 214 ItemIndex = 0 Items.Strings = ( - '3 Sigma (default)' + '3 Sigma' '2 Sigma' '1 Sigma' 'x Sigmas with x = ' ) - TabOrder = 4 + TabOrder = 3 object XSigmaEdit: TEdit AnchorSideRight.Control = SigmaOpts AnchorSideRight.Side = asrBottom @@ -87,31 +106,32 @@ inherited XBarChartForm: TXBarChartForm Left = 128 Height = 23 Top = 80 - Width = 82 + Width = 74 Alignment = taRightJustify Anchors = [akLeft, akRight, akBottom] + BorderSpacing.Right = 8 TabOrder = 0 Text = 'XSigmaEdit' end end - object LevelOptns: TGroupBox[9] + object LevelOptns: TGroupBox[13] AnchorSideLeft.Control = MeasEdit AnchorSideTop.Control = SigmaOpts AnchorSideTop.Side = asrBottom AnchorSideRight.Control = MeasEdit AnchorSideRight.Side = asrBottom - Left = 249 + Left = 257 Height = 103 - Top = 248 - Width = 226 + Top = 285 + Width = 218 Anchors = [akTop, akLeft, akRight] AutoSize = True BorderSpacing.Top = 12 BorderSpacing.Bottom = 8 Caption = 'Show...' ClientHeight = 83 - ClientWidth = 222 - TabOrder = 5 + ClientWidth = 214 + TabOrder = 4 object UpperSpecChk: TCheckBox AnchorSideLeft.Control = LevelOptns AnchorSideTop.Control = UpperSpecEdit @@ -202,26 +222,33 @@ inherited XBarChartForm: TXBarChartForm end inherited SpecsSplitter: TSplitter Left = 478 + Height = 443 end - inherited PageControl1: TPageControl + inherited PageControl: TPageControl Left = 486 + Height = 431 Width = 435 inherited ReportPage: TTabSheet + ClientHeight = 403 ClientWidth = 427 inherited Panel1: TPanel + Height = 363 Width = 415 + ClientHeight = 359 ClientWidth = 411 inherited ReportMemo: TMemo + Height = 351 Width = 403 end end - inherited ToolBar2: TToolBar + inherited ReportToolBar: TToolBar Width = 423 end end inherited ChartPage: TTabSheet + ClientHeight = 403 ClientWidth = 427 - inherited ToolBar1: TToolBar + inherited ChartToolBar: TToolBar Width = 423 end end diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/xbarchartunit.pas b/applications/lazstats/source/forms/analysis/statistical_process_control/xbarchartunit.pas index 685615002..bb6dbee2b 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/xbarchartunit.pas +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/xbarchartunit.pas @@ -45,6 +45,8 @@ procedure TXBarChartForm.FormActivate(Sender: TObject); var w: Integer; begin + NoGroupsAllowed := true; + w := MaxValue([HelpBtn.Width, ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]); HelpBtn.Constraints.MinWidth := w; ResetBtn.Constraints.MinWidth := w; @@ -72,7 +74,10 @@ end; procedure TXBarChartForm.Compute; var i, j: Integer; - upperSpec, lowerSpec, targetSpec, sigma: Double; + sigma: Double; + upperSpec: Double = NaN; + lowerSpec: Double = NaN; + targetSpec: Double = NaN; ColNoSelected: IntDyneVec = nil; groups: StrDyneVec = nil; means: DblDyneVec = nil; @@ -81,101 +86,135 @@ var numGrps: Integer; grp: String; grpIndex: Integer; + totalNumCases: Integer; X, Xsq: Double; - UCL, LCL, grandMean, grandSD, seMean: Double; + UCL, LCL, grandMean, grandSD, stdErrMean, C4Value: Double; lReport: TStrings; begin - SetLength(ColNoSelected, 2); - ColNoSelected[0] := GrpVar; - ColNoSelected[1] := MeasVar; + if GroupEdit.Text <> '' then + begin + SetLength(ColNoSelected, 2); + ColNoSelected[0] := GrpVar; + ColNoSelected[1] := MeasVar; + end else + begin + SetLength(ColNoSelected, 1); + ColNoSelected[0] := MeasVar; + end; if UpperSpecChk.Checked and (UpperSpecEdit.Text <> '') then - upperSpec := StrToFloat(UpperSpecEdit.Text) - else - upperSpec := NaN; + upperSpec := StrToFloat(UpperSpecEdit.Text); if LowerSpecChk.Checked and (LowerSpecEdit.Text <> '') then - lowerSpec := StrToFloat(LowerSpecEdit.Text) - else - lowerSpec := NaN; + lowerSpec := StrToFloat(LowerSpecEdit.Text); if TargetChk.Checked and (TargetSpecEdit.Text <> '') then - targetSpec := StrToFloat(TargetSpecEdit.Text) - else - targetSpec := Nan; + targetSpec := StrToFloat(TargetSpecEdit.Text); case SigmaOpts.ItemIndex of 0: sigma := 3.0; 1: sigma := 2.0; 2: sigma := 1.0; 3: sigma := StrToFloat(XSigmaEdit.Text); + else raise Exception.Create('Sigma case not handled.'); end; - groups := GetGroups; + if GroupEdit.Text = '' then + SetLength(groups, NoCases) + else + groups := GetGroups; numGrps := Length(groups); SetLength(means, numGrps); SetLength(count, numGrps); SetLength(stddev, numGrps); - seMean := 0.0; + stdErrMean := 0.0; grandMean := 0.0; + totalNumCases := 0; // calculate group means, grand mean, group sd's, semeans 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 GroupEdit.Text = '' then + begin + // individuals x-bar chart + grpIndex := totalNumCases; + groups[grpIndex] := IntToStr(i); + end else + begin + // grouped x-bar chart + grp := Trim(OS3MainFrm.DataGrid.Cells[GrpVar, i]); + grpIndex := IndexOfString(groups, grp); + end; X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[MeasVar, i])); Xsq := X*X; inc(count[grpIndex]); means[grpIndex] := means[grpIndex] + X; stddev[grpIndex] := stddev[grpIndex] + Xsq; - seMean := seMean + Xsq; grandMean := grandMean + X; + stdErrMean := stdErrMean + Xsq; + inc(totalNumCases); end; - for i := 0 to numGrps-1 do + stdErrMean := stdErrMean - sqr(grandMean) / totalNumCases; + stdErrMean := sqrt(stderrMean / (totalNumCases - 1)); + grandSD := stdErrMean; + stdErrMean := stdErrMean / sqrt(totalNumCases); + grandMean := grandMean / totalNumCases; + + if (GroupEdit.Text = '') then begin - if count[i] = 0 then + // Individuals chart + SetLength(means, totalNumCases); + SetLength(stddev, totalNumCases); + Setlength(count, totalNumCases); + for i := 0 to totalNumCases-1 do + stddev[i] := stdErrMean; + C4Value := 1.0 / C4[totalNumCases-1]; + UCL := grandMean + sigma * stdErrMean * C4Value; + LCL := grandMean - sigma * stdErrMean * C4Value; + end else + begin + // Grouped chart + for i := 0 to numGrps-1 do begin - means[i] := NaN; - stddev[i] := NaN; - end else - begin - if count[i] = 1 then - stddev[i] := NaN - else + if count[i] = 0 then begin - stddev[i] := stddev[i] - sqr(means[i]) / count[i]; - stddev[i] := stddev[i] / (count[i] - 1); - stddev[i] := sqrt(stddev[i]); + means[i] := NaN; + stddev[i] := NaN; + end else + begin + if count[i] = 1 then + stddev[i] := NaN + else + begin + stddev[i] := stddev[i] - sqr(means[i]) / count[i]; + stddev[i] := stddev[i] / (count[i] - 1); + stddev[i] := sqrt(stddev[i]); + end; + means[i] := means[i] / count[i]; end; - means[i] := means[i] / count[i]; end; + UCL := grandMean + sigma * stdErrMean; + LCL := grandMean - sigma * stdErrMean; end; - seMean := seMean - sqr(grandMean) / NoCases; - seMean := sqrt(seMean / (NoCases - 1)); - grandSD := seMean; - seMean := seMean / sqrt(NoCases); - grandMean := grandMean / NoCases; - UCL := grandMean + sigma * seMean; - LCL := grandMean - sigma * seMean; - // printed results + // Print results lReport := TStringList.Create; try lReport.Add('X BAR CHART RESULTS'); lReport.Add(''); + lReport.Add('Number of samples: %8d', [totalNumCases]); + lReport.Add('Grand Mean: %8.3f', [grandMean]); + lReport.Add('Standard Deviation: %8.3f', [grandSD]); + lReport.Add('Standard Error of Mean: %8.3f', [stdErrMean]); + lReport.Add(''); + lReport.Add('Lower Control Limit: %8.3f', [LCL]); + lReport.Add('Upper Control Limit: %8.3f', [UCL]); + lReport.Add(''); lReport.Add(' Group Size Mean Std.Dev.'); lReport.Add('------- ---- -------- --------'); for i := 0 to numGrps-1 do lReport.Add('%7s %4d %8.2f %8.2f', [groups[i], count[i], means[i], stddev[i]]); - lReport.Add(''); - lReport.Add('Grand Mean: %8.3f', [grandMean]); - lReport.Add('Standard Deviation: %8.3f', [grandSD]); - lReport.Add('Standard Error of Mean: %8.3f', [seMean]); - lReport.Add(''); - lReport.Add('Lower Control Limit: %8.3f', [LCL]); - lReport.Add('Upper Control Limit: %8.3f', [UCL]); ReportMemo.Lines.Assign(lReport); finally @@ -209,8 +248,14 @@ var x: Double; begin Result := inherited; - if not Result then - exit; + if (not Result) then + begin + // This particular chart will handle individual data if GroupEdit is empty. + if GroupEdit.Visible and (GroupEdit.Text = '') then + Result := true + else + exit; + end; Result := false;