diff --git a/applications/lazstats/source/LazStats.lpi b/applications/lazstats/source/LazStats.lpi index 17e000a56..e7f5d2ee8 100644 --- a/applications/lazstats/source/LazStats.lpi +++ b/applications/lazstats/source/LazStats.lpi @@ -49,7 +49,7 @@ - + @@ -752,12 +752,11 @@ - + - @@ -1421,6 +1420,14 @@ + + + + + + + + diff --git a/applications/lazstats/source/LazStats.lpr b/applications/lazstats/source/LazStats.lpr index 43edd4608..eec8e4a9d 100644 --- a/applications/lazstats/source/LazStats.lpr +++ b/applications/lazstats/source/LazStats.lpr @@ -9,7 +9,8 @@ uses Interfaces, // this includes the LCL widgetset Forms, tachartlazaruspkg, tachartprint, lhelpcontrolpkg, Globals, LicenseUnit, OptionsUnit, MainDM, MainUnit, MathUnit, BasicSPCUnit, -SChartUnit, rchartunit, XBarChartUnit, cchartunit; //, utils, chartunit; +SChartUnit, rchartunit, XBarChartUnit, cchartunit, +pchartunit; //, utils, chartunit; {$R LazStats.res} @@ -32,6 +33,7 @@ begin Application.CreateForm(TRChartForm, RChartForm); Application.CreateForm(TXBarChartForm, XBarChartForm); Application.CreateForm(TCChartForm, CChartForm); + Application.CreateForm(TPChartForm, PChartForm); Application.Run; 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 be045da87..26b506224 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/cchartunit.pas +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/cchartunit.pas @@ -47,7 +47,7 @@ var numData: Integer; lReport: TStrings; begin - SetLength(ColNoSelected,1); + SetLength(ColNoSelected, 1); ColNoSelected[0] := MeasVar; case SigmaOptns.ItemIndex of @@ -105,8 +105,6 @@ begin UCL, LCL, meanc, NaN, NaN, NaN ); - - //PlotMeans(means, NoCases, UCL, LCL, meanc); end; procedure TCChartForm.FormActivate(Sender: TObject); 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 5706262a1..f92bc1e81 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/pchartunit.lfm +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/pchartunit.lfm @@ -1,289 +1,174 @@ -object pChartFrm: TpChartFrm - Left = 504 - Height = 371 - Top = 382 - Width = 511 +inherited PChartForm: TPChartForm + Left = 556 + Top = 220 HelpType = htKeyword HelpKeyword = 'html/PControlChart.htm' - AutoSize = True - Caption = 'p Control Chart' - ClientHeight = 371 - ClientWidth = 511 + Caption = 'P Control Chart' OnActivate = FormActivate - OnCreate = FormCreate - OnShow = FormShow - 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 = MeasEdit - AnchorSideTop.Control = Owner - Left = 264 - Height = 15 - Top = 8 - Width = 117 - BorderSpacing.Top = 8 - Caption = 'Measurement Variable' - ParentColor = False - end - object Label3: TLabel - AnchorSideLeft.Control = Label4 - AnchorSideTop.Control = NEdit - AnchorSideTop.Side = asrCenter - AnchorSideRight.Control = NEdit - Left = 264 - Height = 15 - Top = 76 - Width = 167 - Anchors = [akTop, akLeft, akRight] - BorderSpacing.Right = 8 - Caption = 'No. of Parts Sampled:' - ParentColor = False - end - object Label4: TLabel - AnchorSideTop.Control = PEdit - AnchorSideTop.Side = asrCenter - AnchorSideRight.Control = PEdit - Left = 264 - Height = 15 - Top = 107 - Width = 167 - Anchors = [akTop, akRight] - BorderSpacing.Right = 8 - Caption = 'Expected Proportion of Defects:' - ParentColor = False - end - object VarList: TListBox - AnchorSideLeft.Control = Owner - AnchorSideTop.Control = Label1 - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = SigmaOpts - AnchorSideBottom.Control = Bevel2 - Left = 8 - Height = 297 - Top = 25 - Width = 248 - Anchors = [akTop, akLeft, akRight, akBottom] - BorderSpacing.Left = 8 - BorderSpacing.Top = 2 - BorderSpacing.Right = 8 - ItemHeight = 0 - OnClick = VarListClick - TabOrder = 0 - end - object MeasEdit: TEdit - AnchorSideLeft.Control = Label4 - AnchorSideTop.Control = Label2 - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - Left = 264 - Height = 23 - Top = 25 - Width = 239 - Anchors = [akTop, akLeft, akRight] - BorderSpacing.Top = 2 - BorderSpacing.Right = 8 - ReadOnly = True - TabOrder = 1 - Text = 'MeasEdit' - end - object NEdit: TEdit - AnchorSideTop.Control = MeasEdit - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - Left = 439 - Height = 23 - Top = 72 - Width = 64 - Alignment = taRightJustify - Anchors = [akTop, akRight] - BorderSpacing.Top = 24 - BorderSpacing.Right = 8 - TabOrder = 2 - Text = 'NEdit' - end - object PEdit: TEdit - AnchorSideTop.Control = NEdit - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - Left = 439 - Height = 23 - Top = 103 - Width = 64 - Alignment = taRightJustify - Anchors = [akTop, akRight] - BorderSpacing.Top = 8 - BorderSpacing.Right = 8 - TabOrder = 3 - Text = 'Edit1' - end - object SigmaOpts: TRadioGroup - AnchorSideLeft.Control = Label4 - AnchorSideTop.Control = PEdit - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - Left = 264 - Height = 118 - Top = 150 - Width = 239 - Anchors = [akTop, akLeft, akRight] - AutoFill = True - AutoSize = True - BorderSpacing.Top = 24 - BorderSpacing.Right = 8 - Caption = 'No. Of Sigma Units for UCL and LCL' - ChildSizing.LeftRightSpacing = 12 - ChildSizing.TopBottomSpacing = 6 - ChildSizing.VerticalSpacing = 2 - ChildSizing.EnlargeHorizontal = crsHomogenousChildResize - ChildSizing.EnlargeVertical = crsHomogenousChildResize - ChildSizing.ShrinkHorizontal = crsScaleChilds - ChildSizing.ShrinkVertical = crsScaleChilds - ChildSizing.Layout = cclTopToBottomThenLeftToRight - ChildSizing.ControlsPerLine = 4 - ClientHeight = 98 - ClientWidth = 235 - ItemIndex = 0 - Items.Strings = ( - '3 Sigma (Default)' - '2 Sigma' - '1 Sigma' - 'X Sigma where X = ' - ) - TabOrder = 4 - object Label5: TLabel - Left = 143 - Height = 19 - Top = 6 - Width = 80 - Caption = ' ' + inherited SpecsPanel: TPanel + Width = 456 + ClientWidth = 456 + inherited ButtonPanel: TPanel + Width = 456 + ClientWidth = 456 + inherited CloseBtn: TButton + Left = 401 + end + inherited ComputeBtn: TButton + Left = 317 + end + inherited ResetBtn: TButton + Left = 255 + end + inherited HelpBtn: TButton + Left = 204 + end + inherited Bevel1: TBevel + Width = 448 + end + end + inherited VarList: TListBox + Width = 224 + end + inherited GroupLabel: TLabel + Left = 240 + Visible = False + end + inherited GroupEdit: TEdit + Left = 240 + Width = 216 + Visible = False + end + inherited MeasLabel: TLabel + Left = 240 + end + inherited MeasEdit: TEdit + Left = 240 + Width = 216 + end + inherited Bevel2: TBevel + Left = 217 + end + object Label3: TLabel[8] + AnchorSideLeft.Control = Label4 + AnchorSideTop.Control = NEdit + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = NEdit + Left = 270 + Height = 15 + Top = 124 + Width = 114 + Anchors = [akTop, akRight] + BorderSpacing.Right = 8 + Caption = 'No. of Parts Sampled:' ParentColor = False end - object Label6: TLabel - Left = 143 - Height = 19 - Top = 27 - Width = 80 - Caption = ' ' - ParentColor = False - end - object Label7: TLabel - Left = 143 - Height = 19 - Top = 48 - Width = 80 - Caption = ' ' - ParentColor = False - end - object XSigmaEdit: TEdit - Left = 143 - Height = 23 - Top = 69 - Width = 80 - Alignment = taRightJustify - BorderSpacing.Left = 8 - TabOrder = 2 - Text = 'XSigmaEdit' - end - end - object Bevel2: TBevel - AnchorSideTop.Control = Panel1 - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = Panel1 - Left = 0 - Height = 8 - Top = 322 - Width = 511 - Anchors = [akLeft, akRight, akBottom] - Shape = bsBottomLine - end - object Panel1: TPanel - Left = 8 - Height = 25 - Top = 338 - Width = 495 - Align = alBottom - AutoSize = True - BorderSpacing.Around = 8 - BevelOuter = bvNone - ClientHeight = 25 - ClientWidth = 495 - TabOrder = 5 - object ResetBtn: TButton - AnchorSideLeft.Control = Panel1 - AnchorSideTop.Control = Panel1 - AnchorSideRight.Control = ComputeBtn - Left = 294 - Height = 25 - Top = 0 - Width = 54 - Anchors = [akTop, akRight] - AutoSize = True - BorderSpacing.Right = 8 - Caption = 'Reset' - OnClick = ResetBtnClick - TabOrder = 1 - end - object ComputeBtn: TButton - AnchorSideLeft.Control = Panel1 - AnchorSideTop.Control = Panel1 - AnchorSideRight.Control = CloseBtn - Left = 356 - Height = 25 - Top = 0 - Width = 76 - Anchors = [akTop, akRight] - AutoSize = True - BorderSpacing.Right = 8 - Caption = 'Compute' - OnClick = ComputeBtnClick - TabOrder = 2 - end - object HelpBtn: TButton - Tag = 141 - AnchorSideLeft.Control = Panel1 - AnchorSideTop.Control = ResetBtn - AnchorSideRight.Control = ResetBtn - Left = 235 - Height = 25 - Top = 0 - Width = 51 - Anchors = [akTop, akRight] - AutoSize = True - BorderSpacing.Right = 8 - Caption = 'Help' - OnClick = HelpBtnClick - TabOrder = 0 - end - object CloseBtn: TButton - AnchorSideLeft.Control = Panel1 - AnchorSideTop.Control = Panel1 - AnchorSideRight.Control = Panel1 + object NEdit: TEdit[9] + AnchorSideTop.Control = MeasEdit + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = MeasEdit AnchorSideRight.Side = asrBottom - Left = 440 - Height = 25 - Top = 0 - Width = 55 + Left = 392 + Height = 23 + Top = 120 + Width = 64 + Alignment = taRightJustify Anchors = [akTop, akRight] - AutoSize = True - Caption = 'Close' - ModalResult = 11 - TabOrder = 3 + BorderSpacing.Top = 24 + TabOrder = 4 + Text = 'NEdit' + end + object Label4: TLabel[10] + AnchorSideTop.Control = PEdit + AnchorSideTop.Side = asrCenter + Left = 272 + Height = 30 + Top = 147 + Width = 108 + Alignment = taRightJustify + Anchors = [akTop, akRight] + BorderSpacing.Right = 8 + Caption = 'Expected Proportion'#13#10'of Defects:' + ParentColor = False + end + object PEdit: TEdit[11] + AnchorSideTop.Control = NEdit + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = MeasEdit + AnchorSideRight.Side = asrBottom + Left = 392 + Height = 23 + Top = 151 + Width = 64 + Alignment = taRightJustify + Anchors = [akTop, akRight] + BorderSpacing.Top = 8 + TabOrder = 5 + Text = 'PEdit' + end + object SigmaOpts: TRadioGroup[12] + AnchorSideLeft.Control = MeasEdit + AnchorSideTop.Control = PEdit + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = SpecsPanel + AnchorSideRight.Side = asrBottom + Left = 240 + Height = 128 + Top = 198 + Width = 216 + Anchors = [akTop, akLeft, akRight] + AutoFill = True + BorderSpacing.Top = 24 + BorderSpacing.Bottom = 8 + Caption = 'No. of Sigma Units for UCL and LCL' + ChildSizing.LeftRightSpacing = 12 + ChildSizing.TopBottomSpacing = 6 + ChildSizing.EnlargeHorizontal = crsHomogenousChildResize + ChildSizing.EnlargeVertical = crsHomogenousChildResize + ChildSizing.ShrinkHorizontal = crsScaleChilds + ChildSizing.ShrinkVertical = crsScaleChilds + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 1 + ClientHeight = 108 + ClientWidth = 212 + ItemIndex = 0 + Items.Strings = ( + '3 Sigma (default)' + '2 Sigma' + '1 Sigma' + 'x Sigmas with x = ' + ) + TabOrder = 6 + object XSigmaEdit: TEdit + AnchorSideRight.Control = SigmaOpts + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Side = asrBottom + Left = 128 + Height = 23 + Top = 80 + Width = 72 + Alignment = taRightJustify + Anchors = [akLeft, akRight, akBottom] + TabOrder = 0 + Text = 'XSigmaEdit' + end + end + end + inherited SpecsSplitter: TSplitter + Left = 459 + end + inherited PageControl1: TPageControl + Left = 467 + Width = 454 + inherited ReportPage: TTabSheet + ClientWidth = 446 + inherited Panel1: TPanel + Width = 434 + ClientWidth = 430 + inherited ReportMemo: TMemo + Width = 422 + end + end end end end diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/pchartunit.pas b/applications/lazstats/source/forms/analysis/statistical_process_control/pchartunit.pas index f2e714ff5..b2b5fd49e 100644 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/pchartunit.pas +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/pchartunit.pas @@ -1,8 +1,3 @@ -// File for testing: "defects.laz" -// Defects --> Measurement Variable -// No of parts sampled ---> 1000 -// Expected proportion of defects --> 0.01 - unit PChartUnit; {$mode objfpc}{$H+} @@ -10,167 +5,88 @@ unit PChartUnit; interface uses - Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, - StdCtrls, ExtCtrls, - MainUnit, Globals, Math, OutputUnit, Buttons, BlankFrmUnit, ContextHelpUnit; + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, ExtCtrls, + StdCtrls, BasicSPCUnit; type - { TpChartFrm } + { TPChartForm } - TpChartFrm = class(TForm) - Bevel2: TBevel; - ComputeBtn: TButton; - HelpBtn: TButton; - Label5: TLabel; - Label6: TLabel; - Label7: TLabel; - Panel1: TPanel; - ResetBtn: TButton; - CloseBtn: TButton; - XSigmaEdit: TEdit; - NEdit: TEdit; - PEdit: TEdit; + TPChartForm = class(TBasicSPCForm) Label3: TLabel; Label4: TLabel; - MeasEdit: TEdit; - Label1: TLabel; - Label2: TLabel; + NEdit: TEdit; + PEdit: TEdit; SigmaOpts: TRadioGroup; - VarList: TListBox; - procedure ComputeBtnClick(Sender: TObject); + XSigmaEdit: 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; - procedure PlotMeans(var means: DblDyneVec; NoGrps: integer; - UCL, LCL, GrandMean, Target: double); - function Validate(out AMsg: String; out AControl: TWinControl): Boolean; - public - { public declarations } - end; + protected + procedure Compute; override; + procedure Reset; override; + function Validate(out AMsg: String; out AControl: TWinControl): Boolean; override; + end; var - pChartFrm: TpChartFrm; + PChartForm: TPChartForm; + implementation -{ TpChartFrm } +{$R *.lfm} -procedure TpChartFrm.ResetBtnClick(Sender: TObject); +uses + Math, Globals, Utils, MainUnit, DataProcs; + +procedure TPChartForm.Compute; var - i: integer; -begin - VarList.Clear; - MeasEdit.Text := ''; - NEdit.Text := ''; - PEdit.Text := ''; - for i := 1 to NoVariables do - VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); -end; - -procedure TpChartFrm.VarListClick(Sender: TObject); -var - index : integer; -begin - index := VarList.ItemIndex; - if index > -1 then begin - MeasEdit.Text := VarList.Items[index]; - VarList.Items.Delete(index); - end; -end; - -procedure TpChartFrm.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.MinHeight := SigmaOpts.Top + SigmaOpts.Height - VarList.Top; - VarList.Constraints.MinWidth := SigmaOpts.Width * 3 div 4; - - Constraints.MinWidth := Width; - Constraints.MinHeight := Height; - - FAutoSized := true; -end; - -procedure TpChartFrm.FormCreate(Sender: TObject); -begin - Assert(OS3MainFrm <> nil); - if BlankFrm = nil then - Application.CreateForm(TBlankfrm, BlankFrm); -end; - -procedure TpChartFrm.FormShow(Sender: TObject); -begin - ResetBtnClick(self); -end; - -procedure TpChartFrm.HelpBtnClick(Sender: TObject); -begin - if ContextHelpForm = nil then - Application.CreateForm(TContextHelpForm, ContextHelpForm); - ContextHelpForm.HelpMessage((Sender as TButton).tag); -end; - -procedure TpChartFrm.ComputeBtnClick(Sender: TObject); -var - P, N, variance, stddev, UCL, LCL, X, Sigma, AVG: double; - i, measvar: integer; - cellstring: string; - obsp: DblDyneVec; - msg: String; - C: TWinControl; + ColNoSelected: IntDyneVec = nil; + obsP: DblDyneVec = nil; + X, AVG, P, sigma, variance, stddev, UCL, LCL, maxX: Double; + i, N, count: Integer; lReport: TStrings; begin - if not Validate(msg, C) then + SetLength(ColNoSelected, 1); + ColNoSelected[0] := MeasVar; + + case SigmaOpts.ItemIndex of + 0: sigma := 3.0; + 1: sigma := 2.0; + 2: sigma := 1.0; + 3: sigma := StrToFloat(XSigmaEdit.Text); + end; + + N := StrToInt(NEdit.Text); + P := StrToFloat(PEdit.Text); + variance := P * (1.0 - P) / N; + stddev := sqrt(variance); + + AVG := 0.0; + count := 0; + maxX := 0; + SetLength(obsP, NoCases); + for i := 1 to NoCases do begin - C.SetFocus; - MessageDlg(msg, mtError, [mbOK], 0); + if not GoodRecord(i, Length(ColNoSelected), ColNoSelected) then continue; + X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[MeasVar, i])); + if X > maxX then maxX := X; + end; + + if maxX > N then + begin + ErrorMsg(Format('Maximum number of defects (%.0f) cannot be larger than the sample size (%d)', [maxX, N])); exit; end; - AVG := 0.0; - measvar := 1; - Sigma := 3; - N := StrToFloat(NEdit.Text); - P := StrToFloat(PEdit.Text); - case SigmaOpts.ItemIndex of - 0: Sigma := 3.0; - 1: Sigma := 2.0; - 2: Sigma := 1.0; - 3: Sigma := StrToFloat(XSigmaEdit.Text); - end; - - for i := 1 to NoVariables do - begin - cellstring := OS3MainFrm.DataGrid.Cells[i,0]; - if cellstring = MeasEdit.Text then measvar := i; - end; - variance := P * (1.0 - P) / N; - stddev := Sqrt(variance); - SetLength(obsp, NoCases + 1); for i := 1 to NoCases do begin - X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[measvar,i])); + X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[MeasVar, i])); X := X / N; - obsp[i] := X; + obsP[i - 1] := X; AVG := AVG + X; + inc(count); end; - AVG := AVG / NoCases; + SetLength(obsP, count); + AVG := AVG / count; //NoCases; UCL := P + Sigma * stddev; LCL := P - Sigma * stddev; @@ -182,219 +98,121 @@ begin lReport.Add('Sample No. Proportion'); lReport.Add('---------- ----------'); for i := 1 to NoCases do - lReport.Add(' %5d %6.3f', [i, obsp[i]]); + lReport.Add('%10d %10.3f', [i, obsp[i]]); lReport.Add(''); - lReport.Add('Target proportion: %6.4f', [P]); - lReport.Add('Sample size for each observation: %6.0f', [N]); - lReport.Add('Average proportion observed %6.4f', [AVG]); + lReport.Add('Number of data values: %8d', [count]); + lReport.Add('Target proportion: %8.4f', [P]); + lReport.Add('Sample size for each observation: %8d', [N]); + lReport.Add('Average proportion observed %8.4f', [AVG]); - DisplayReport(lReport); + ReportMemo.Lines.Assign(lReport); finally lReport.Free; end; - // Now create plot - PlotMeans(obsp,NoCases,UCL,LCL, Avg, P); - - obsp := nil; + // Show graph + PlotMeans( + Format('P Control Chart for "%s"', [GetFileName]), + 'Sample', MeasEdit.Text, 'Proportion', 'Mean', + nil, obsP, + UCL, LCL, AVG, + NaN, NaN, NaN + ); end; -procedure TpChartFrm.PlotMeans(var Means: DblDyneVec; NoGrps: integer; - UCL, LCL, GrandMean, Target: double); +procedure TPChartForm.FormActivate(Sender: TObject); var - i, xpos, ypos, hleft, hright, vtop, vbottom, imagewide : integer; - vhi, hwide, offset, strhi, oldxpos : integer; - imagehi, maxval, minval, valincr, Yvalue : double; - Title : string; + w: Integer; begin - maxval := -10000.0; - minval := 10000.0; - for i := 1 to NoGrps do - begin - if means[i] > maxval then maxval := means[i]; - if means[i] < minval then minval := means[i]; - end; - if UCL > maxval then maxval := UCL; - if LCL < minval then minval := LCL; - BlankFrm.Image1.Canvas.Clear; - BlankFrm.Show; - Title := 'p CONTROL 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; + 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; - BlankFrm.Image1.Canvas.Brush.Color := clLtGray; - BlankFrm.Image1.Canvas.FillRect(0, 0, BlankFrm.Image1.Width, BlankFrm.Image1.Height); + DisableAutoSizing; + try + SigmaOpts.AnchorSideRight.Control := nil; + VarList.Constraints.MinWidth := VarListLabel.Width; + SpecsPanel.Constraints.MinWidth := Max( + CloseBtn.Left + CloseBtn.Width - HelpBtn.Left + HelpBtn.BorderSpacing.Around, + SigmaOpts.Width * 2 + VarList.BorderSpacing.Right + VarList.BorderSpacing.Left + ); + Constraints.MinHeight := SigmaOpts.Top + SigmaOpts.Height + SigmaOpts.BorderSpacing.Bottom + ButtonPanel.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 := clBlue; - BlankFrm.Image1.Canvas.LineTo(xpos,ypos); - Title := 'MEAN'; - 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 target - ypos := round(vhi * ( (maxval - Target) / (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 := 'TARGET'; - 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); - oldxpos := 0; - 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; - if xpos > oldxpos then - begin - BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title); - oldxpos := xpos + (offset * 2); - end; - 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('%.3f',[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[1]) / (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]) / (maxval - minval))); - ypos := ypos + vtop; - xpos := round((hwide / NoGrps)* i + hleft); - BlankFrm.Image1.Canvas.LineTo(xpos,ypos); - end; - - // Draw upper and lower confidence intervals - ypos := round(vhi * ( (maxval - UCL) / (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 := 'UCL'; - strhi := BlankFrm.Image1.Canvas.TextHeight(Title); - ypos := ypos - strhi div 2; - BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title); - - ypos := round(vhi * ( (maxval - LCL) / (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 := 'LCL'; - strhi := BlankFrm.Image1.Canvas.TextHeight(Title); - ypos := ypos - strhi div 2; - BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title); + SigmaOpts.AnchorSideRight.Control := MeasEdit; + SigmaOpts.AnchorSideRight.Side := asrBottom; + finally + EnableAutoSizing; + end; end; -function TPChartFrm.Validate(out AMsg: String; out AControl: TWinControl): Boolean; +procedure TPChartForm.Reset; +begin + inherited; + XSigmaEdit.Clear; + NEdit.Clear; + PEdit.Clear; +end; + + +function TPChartForm.Validate(out AMsg: String; out AControl: TWinControl): Boolean; var - n: Integer; x: Double; + n: Integer; begin + Result := inherited; + if not Result then + exit; + Result := false; - if MeasEdit.Text = '' then + if (NEdit.Text = '') then begin - AMsg := 'Measurement variable not specified.'; - AControl := MeasEdit; - exit; - end; - - if NEdit.Text = '' then - begin - AMsg := 'Number of sampled parts is not specified.'; + AMsg := 'No of Parts Sampled not specified.'; AControl := NEdit; exit; end; + if not TryStrToInt(NEdit.Text, n) then begin - AMsg := 'Number of sampled parts is not valid.'; + AMsg := 'No valid number given for No of Parts Sampled.'; AControl := NEdit; exit; end; - if PEdit.Text = '' then + if (PEdit.Text = '') then begin - AMsg := 'Expected proportion of defects is not specified.'; + AMsg := 'Expected proportion of defects not specifed.'; AControl := PEdit; exit; end; + if not TryStrToFloat(PEdit.Text, x) then begin - AMsg := 'Expected proporton of defects is not a valid number.'; + AMsg := 'No valid number given for expected proportion of defects.'; AControl := PEdit; exit; end; + if SigmaOpts.ItemIndex = -1 then + begin + AMsg := 'Number of sigma units for UCL and LCL not specified.'; + AControl := SigmaOpts; + exit; + end; + if SigmaOpts.ItemIndex = 3 then begin - if XSigmaEdit.Text = '' then + if (XSigmaEdit.Text = '') then begin - AMsg := 'X Sigma is not specified.'; + AMsg := 'User-defined sigma units missing.'; AControl := XSigmaEdit; exit; end; if not TryStrToFloat(XSigmaEdit.Text, x) then begin - AMsg := 'X Sigma is not a valid number.'; + AMsg := 'No valid number given for sser-defined sigma units.'; AControl := XSigmaEdit; exit; end; @@ -403,8 +221,6 @@ begin Result := true; end; -initialization - {$I pchartunit.lrs} - end. + diff --git a/applications/lazstats/source/forms/mainunit.pas b/applications/lazstats/source/forms/mainunit.pas index 202d17bc5..7260f8da3 100644 --- a/applications/lazstats/source/forms/mainunit.pas +++ b/applications/lazstats/source/forms/mainunit.pas @@ -926,9 +926,9 @@ end; // Menu "Analysis" > "Statistical Process Control" > "p Control Chart" procedure TOS3MainFrm.mnuAnalysisSPC_PChartClick(Sender: TObject); begin - if pChartFrm = nil then - Application.CreateForm(TpChartFrm, pChartFrm); - pChartFrm.ShowModal; + if PChartForm = nil then + Application.CreateForm(TPChartForm, PChartForm); + PChartForm.ShowModal; end; // Menu "Analysis" > "Descriptive" > "Plot X vs Y"