From d7567a511a38fc319162da634dfd0f570ea32c5f Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Mon, 7 Sep 2020 16:25:52 +0000 Subject: [PATCH] LazStats: Add SPC template form. Replace old SigmaChartUnit by SChartUnit based on template. Some cosmetics in MainForm menu items. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7653 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- applications/lazstats/source/LazStats.lpi | 350 ++++++++------- applications/lazstats/source/LazStats.lpr | 4 +- .../basicspcunit.lfm | 298 ++++++++++++ .../basicspcunit.pas | 347 ++++++++++++++ .../schartunit.lfm | 16 + .../schartunit.pas | 176 ++++++++ .../sigmachartunit.lfm | 196 -------- .../sigmachartunit.pas | 424 ------------------ .../lazstats/source/forms/mainunit.lfm | 36 +- .../lazstats/source/forms/mainunit.pas | 220 +++++---- 10 files changed, 1164 insertions(+), 903 deletions(-) create mode 100644 applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.lfm create mode 100644 applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.pas create mode 100644 applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.lfm create mode 100644 applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.pas delete mode 100644 applications/lazstats/source/forms/analysis/statistical_process_control/sigmachartunit.lfm delete mode 100644 applications/lazstats/source/forms/analysis/statistical_process_control/sigmachartunit.pas diff --git a/applications/lazstats/source/LazStats.lpi b/applications/lazstats/source/LazStats.lpi index fa5111c08..22b96498e 100644 --- a/applications/lazstats/source/LazStats.lpi +++ b/applications/lazstats/source/LazStats.lpi @@ -49,7 +49,7 @@ - + @@ -760,659 +760,667 @@ - - - - - - - - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + diff --git a/applications/lazstats/source/LazStats.lpr b/applications/lazstats/source/LazStats.lpr index a284fbee6..472701ac8 100644 --- a/applications/lazstats/source/LazStats.lpr +++ b/applications/lazstats/source/LazStats.lpr @@ -8,7 +8,8 @@ uses {$ENDIF}{$ENDIF} Interfaces, // this includes the LCL widgetset Forms, tachartlazaruspkg, tachartprint, lhelpcontrolpkg, Globals, LicenseUnit, - OptionsUnit, MainDM, MainUnit, MathUnit; //, utils, chartunit; + OptionsUnit, MainDM, MainUnit, MathUnit, BasicSPCUnit, +SChartUnit; //, utils, chartunit; {$R LazStats.res} @@ -26,7 +27,6 @@ begin else Application.Terminate; end; - Application.CreateForm(TMainDataModule, MainDataModule); Application.CreateForm(TOS3MainFrm, OS3MainFrm); Application.Run; diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.lfm b/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.lfm new file mode 100644 index 000000000..b3ce64d54 --- /dev/null +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.lfm @@ -0,0 +1,298 @@ +object BasicSPCForm: TBasicSPCForm + Left = 535 + Height = 438 + Top = 241 + Width = 927 + Caption = 'SPC Form' + ClientHeight = 438 + ClientWidth = 927 + OnActivate = FormActivate + OnCreate = FormCreate + OnShow = FormShow + LCLVersion = '2.1.0.0' + object SpecsPanel: TPanel + Left = 0 + Height = 438 + Top = 0 + Width = 357 + Align = alLeft + BevelOuter = bvNone + ClientHeight = 438 + ClientWidth = 357 + TabOrder = 0 + object ButtonPanel: TPanel + Left = 0 + Height = 42 + Top = 396 + Width = 357 + Align = alBottom + AutoSize = True + BevelOuter = bvNone + ClientHeight = 42 + ClientWidth = 357 + TabOrder = 0 + object CloseBtn: TButton + AnchorSideTop.Control = ButtonPanel + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = ButtonPanel + AnchorSideRight.Side = asrBottom + Left = 302 + Height = 25 + Top = 9 + Width = 55 + Anchors = [akTop, akRight] + AutoSize = True + BorderSpacing.Top = 8 + BorderSpacing.Bottom = 8 + Caption = 'Close' + ModalResult = 11 + OnClick = CloseBtnClick + TabOrder = 0 + end + object ComputeBtn: TButton + AnchorSideTop.Control = ButtonPanel + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = CloseBtn + Left = 218 + Height = 25 + Top = 9 + Width = 76 + Anchors = [akTop, akRight] + AutoSize = True + BorderSpacing.Around = 8 + Caption = 'Compute' + OnClick = ComputeBtnClick + TabOrder = 1 + end + object ResetBtn: TButton + AnchorSideTop.Control = ButtonPanel + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = ComputeBtn + Left = 156 + Height = 25 + Top = 9 + Width = 54 + Anchors = [akTop, akRight] + AutoSize = True + BorderSpacing.Around = 8 + Caption = 'Reset' + OnClick = ResetBtnClick + TabOrder = 2 + end + object HelpBtn: TButton + AnchorSideTop.Control = ButtonPanel + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = ResetBtn + Left = 105 + Height = 25 + Top = 9 + Width = 43 + Anchors = [akTop, akRight] + BorderSpacing.Around = 8 + Caption = 'Help' + OnClick = HelpBtnClick + TabOrder = 3 + end + object Bevel1: TBevel + AnchorSideLeft.Control = ButtonPanel + AnchorSideTop.Control = ButtonPanel + AnchorSideRight.Control = ButtonPanel + AnchorSideRight.Side = asrBottom + Left = 8 + Height = 4 + Top = 0 + Width = 349 + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Left = 8 + Shape = bsTopLine + end + end + object VarListLabel: TLabel + AnchorSideLeft.Control = SpecsPanel + AnchorSideTop.Control = SpecsPanel + Left = 8 + Height = 15 + Top = 8 + Width = 97 + BorderSpacing.Left = 8 + BorderSpacing.Top = 8 + Caption = 'Selection Variables' + ParentColor = False + end + object VarList: TListBox + AnchorSideLeft.Control = SpecsPanel + AnchorSideTop.Control = VarListLabel + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = Bevel2 + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = ButtonPanel + Left = 8 + Height = 363 + Top = 25 + Width = 174 + Anchors = [akTop, akLeft, akRight, akBottom] + BorderSpacing.Left = 8 + BorderSpacing.Top = 2 + BorderSpacing.Right = 8 + BorderSpacing.Bottom = 8 + ItemHeight = 0 + OnClick = VarListClick + TabOrder = 1 + end + object GroupLabel: TLabel + AnchorSideLeft.Control = VarList + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = VarListLabel + Left = 190 + Height = 15 + Top = 8 + Width = 105 + BorderSpacing.Bottom = 2 + Caption = 'Group (Lot) Variable' + ParentColor = False + end + object GroupEdit: TEdit + AnchorSideLeft.Control = VarList + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = GroupLabel + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = SpecsPanel + AnchorSideRight.Side = asrBottom + Left = 190 + Height = 23 + Top = 25 + Width = 167 + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Top = 2 + BorderSpacing.Bottom = 8 + ReadOnly = True + TabOrder = 2 + Text = 'GroupEdit' + end + object MeasLabel: TLabel + AnchorSideLeft.Control = VarList + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = GroupEdit + AnchorSideTop.Side = asrBottom + Left = 190 + Height = 15 + Top = 56 + Width = 117 + BorderSpacing.Bottom = 2 + Caption = 'Measurement Variable' + ParentColor = False + end + object MeasEdit: TEdit + AnchorSideLeft.Control = VarList + AnchorSideLeft.Side = asrBottom + AnchorSideTop.Control = MeasLabel + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = SpecsPanel + AnchorSideRight.Side = asrBottom + Left = 190 + Height = 23 + Top = 73 + Width = 167 + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Top = 2 + BorderSpacing.Bottom = 8 + ReadOnly = True + TabOrder = 3 + Text = 'MeasEdit' + end + object Bevel2: TBevel + AnchorSideLeft.Control = SpecsPanel + AnchorSideLeft.Side = asrCenter + Left = 167 + Height = 9 + Top = 0 + Width = 23 + Shape = bsSpacer + end + end + object SpecsSplitter: TSplitter + Left = 357 + Height = 438 + Top = 0 + Width = 5 + ResizeStyle = rsPattern + end + object PageControl1: TPageControl + Left = 368 + Height = 426 + Top = 6 + Width = 553 + ActivePage = ReportPage + Align = alClient + BorderSpacing.Around = 6 + TabIndex = 0 + TabOrder = 2 + object ReportPage: TTabSheet + Caption = 'Report' + ClientHeight = 398 + ClientWidth = 545 + object Panel1: TPanel + Left = 6 + Height = 386 + Top = 6 + Width = 533 + Align = alClient + BorderSpacing.Around = 6 + BevelOuter = bvNone + BorderStyle = bsSingle + ClientHeight = 382 + ClientWidth = 529 + TabOrder = 0 + object ReportMemo: TMemo + Left = 0 + Height = 382 + Top = 0 + Width = 529 + Align = alClient + BorderStyle = bsNone + Font.Height = -11 + Font.Name = 'Courier New' + ParentFont = False + TabOrder = 0 + end + end + end + object ChartPage: TTabSheet + Caption = 'Chart' + ClientHeight = 398 + ClientWidth = 545 + object ToolBar1: TToolBar + Left = 517 + Height = 386 + Top = 6 + Width = 24 + Align = alRight + AutoSize = True + BorderSpacing.Top = 6 + BorderSpacing.Right = 4 + BorderSpacing.Bottom = 6 + Caption = 'ToolBar1' + EdgeBorders = [] + Images = MainDataModule.ImageList + TabOrder = 0 + Transparent = True + object tbSave: TToolButton + Left = 1 + Hint = 'Save chart to file' + Top = 0 + Caption = 'tbSave' + ImageIndex = 4 + OnClick = tbSaveClick + end + object tbPrint: TToolButton + Left = 1 + Hint = 'Print chart' + Top = 22 + Caption = 'tbPrint' + ImageIndex = 5 + OnClick = tbPrintClick + end + end + end + end +end diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.pas b/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.pas new file mode 100644 index 000000000..606265878 --- /dev/null +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/basicspcunit.pas @@ -0,0 +1,347 @@ +unit BasicSPCUnit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, + StdCtrls, ComCtrls, + Globals, MainUnit, ContextHelpUnit, ChartFrameUnit; + +type + + { TBasicSPCForm } + + TBasicSPCForm = class(TForm) + Bevel1: TBevel; + Bevel2: TBevel; + GroupEdit: TEdit; + HelpBtn: TButton; + GroupLabel: TLabel; + MeasLabel: TLabel; + MeasEdit: TEdit; + ReportMemo: TMemo; + PageControl1: TPageControl; + Panel1: TPanel; + ResetBtn: TButton; + ComputeBtn: TButton; + CloseBtn: TButton; + SpecsPanel: TPanel; + ButtonPanel: TPanel; + SpecsSplitter: TSplitter; + ReportPage: TTabSheet; + ChartPage: TTabSheet; + tbPrint: TToolButton; + tbSave: TToolButton; + ToolBar1: TToolBar; + VarList: TListBox; + VarListLabel: TLabel; + procedure CloseBtnClick(Sender: TObject); + procedure ComputeBtnClick(Sender: TObject); + procedure FormActivate(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure HelpBtnClick(Sender: TObject); + procedure ResetBtnClick(Sender: TObject); + procedure tbPrintClick(Sender: TObject); + procedure tbSaveClick(Sender: TObject); + procedure VarListClick(Sender: TObject); + private + + protected + GrpVar: Integer; + MeasVar: Integer; + function GetGroups: StrDyneVec; + function GetFileName: String; + procedure PlotMeans(ATitle, AXTitle, AYTitle, ADataTitle, AGrandMeanTitle: String; + const Groups: StrDyneVec; const Means, StdDevs: DblDyneVec; + UCL, LCL, GrandMean, TargetSpec, LowerSpec, UpperSpec: double); + procedure Reset; virtual; + procedure Compute; virtual; + function Validate(out AMsg: String; out AControl: TWinControl): Boolean; virtual; + + public + FChartFrame: TChartFrame; + + end; + +var + BasicSPCForm: TBasicSPCForm; + +implementation + +{$R *.lfm} + +uses + Math, + TAChartUtils, TALegend, TAChartAxisUtils, TASources, TACustomSeries, TASeries, + Utils, DataProcs; + + +{ TBasicSPCForm } + +procedure TBasicSPCForm.CloseBtnClick(Sender: TObject); +begin + Close; +end; + + +procedure TBasicSPCForm.Compute; +begin +end; + + +procedure TBasicSPCForm.ComputeBtnClick(Sender: TObject); +var + msg: String; + C: TWinControl; + i: Integer; + cellString: String; +begin + if not Validate(msg, C) then begin + C.SetFocus; + MessageDlg(msg, mtError, [mbOK], 0); + exit; + end; + + GrpVar := -1; + MeasVar := -1; + for i := 1 to NoVariables do + begin + cellstring := OS3MainFrm.DataGrid.Cells[i, 0]; + 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 + begin + GroupEdit.SetFocus; + ErrorMsg('Group variable not found.'); + exit; + end; + if MeasEdit.Visible and (MeasVar = -1) then + begin + MeasEdit.SetFocus; + ErrorMsg('Measurement variable not found.'); + exit; + end; + + Compute; +end; + +procedure TBasicSPCForm.FormActivate(Sender: TObject); +var + w: Integer; +begin + 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; + + SpecsPanel.Constraints.MinWidth := Max( + VarListLabel.Left + VarListLabel.Width + MeasLabel.Width, + CloseBtn.Left + CloseBtn.Width - HelpBtn.Left + HelpBtn.BorderSpacing.Around + ); + Constraints.MinHeight := MeasEdit.Top + MeasEdit.Height + MeasEdit.BorderSpacing.Bottom + ButtonPanel.Height; +end; + + +procedure TBasicSPCForm.FormCreate(Sender: TObject); +begin + Assert(OS3MainFrm <> nil); + FChartFrame := TChartFrame.Create(self); + FChartFrame.Parent := ChartPage; + FChartFrame.Align := alClient; + FChartFrame.BorderSpacing.Around := Scale96ToFont(8); + FChartFrame.Chart.Legend.SymbolWidth := Scale96ToFont(30); + FChartFrame.Chart.Legend.Alignment := laBottomCenter; + FChartFrame.Chart.Legend.ColumnCount := 3; + FChartFrame.Chart.Title.TextFormat := tfHtml; + with FChartFrame.Chart.AxisList.Add do + begin + Alignment := calRight; + Marks.Source := TListChartSource.Create(self); + Marks.Style := smsLabel; + end; +end; + + +procedure TBasicSPCForm.FormShow(Sender: TObject); +begin + Reset; +end; + + +function TBasicSPCForm.GetGroups: StrDyneVec; +var + numGrps: Integer = 0; + ColNoSelected: IntDyneVec = nil; + grp: String; + i: Integer; +begin + SetLength(ColNoSelected, 2); + ColNoSelected[0] := GrpVar; + ColNoSelected[1] := MeasVar; + SetLength(Result, NoCases); + for i := 1 to NoCases do + begin + if not GoodRecord(i, Length(ColNoSelected), ColNoSelected) then + continue; + grp := Trim(OS3MainFrm.DataGrid.Cells[GrpVar, i]); + if IndexOfString(Result, grp) = -1 then + begin + Result[numGrps] := grp; + inc(numGrps); + end; + end; + SetLength(Result, numGrps); +end; + + +function TBasicSPCForm.GetFileName: String; +begin + Result := ExtractFileName(OS3MainFrm.FileNameEdit.Text); +end; + + +procedure TBasicSPCForm.HelpBtnClick(Sender: TObject); +begin + if ContextHelpForm = nil then + Application.CreateForm(TContextHelpForm, ContextHelpForm); + ContextHelpForm.HelpMessage((Sender as TButton).Tag); +end; + + +procedure TBasicSPCForm.PlotMeans(ATitle, AXTitle, AYTitle, ADataTitle, AGrandMeanTitle: String; + const Groups: StrDyneVec; const Means, StdDevs: DblDyneVec; + UCL, LCL, GrandMean, TargetSpec, LowerSpec, UpperSpec: double); +const + TARGET_COLOR = clBlue; + CL_COLOR = clRed; + SPEC_COLOR = clGreen; + CL_STYLE = psDot; + SPEC_STYLE = psSolid; +var + fn: String; + ser: TChartSeries; + rightLabels: TListChartSource; + constLine: TConstantLine; + s: String; +begin + fn := ExtractFileName(OS3MainFrm.FileNameEdit.Text); + rightLabels := FChartFrame.Chart.AxisList[2].Marks.Source as TListChartSource; + + FChartFrame.Clear; + FChartFrame.SetTitle(ATitle); + FChartFrame.SetXTitle(AXTitle); + FChartFrame.SetYTitle(AYTitle); + + ser := FChartFrame.PlotXY(ptSymbols, nil, Means, Groups, StdDevs, ADataTitle, clBlack); + FChartFrame.Chart.BottomAxis.Marks.Source := ser.Source; + FChartFrame.Chart.BottomAxis.Marks.style := smsLabel; + + FChartFrame.HorLine(GrandMean, clRed, psSolid, AGrandMeanTitle); + rightLabels.Add(GrandMean, GrandMean, AGrandMeanTitle); + + FChartFrame.HorLine(UCL, CL_COLOR, CL_STYLE, 'UCL/LCL'); + rightLabels.Add(UCL, UCL, 'UCL'); + + FChartFrame.HorLine(LCL, CL_COLOR, CL_STYLE, ''); + rightLabels.Add(UCL, LCL, 'LCL'); + + if not IsNan(UpperSpec) then + begin + if IsNaN(LowerSpec) then + s := 'Upper Spec' + else + s := 'Upper/Lower Spec'; + FChartFrame.HorLine(UpperSpec, SPEC_COLOR, SPEC_STYLE, s); + rightLabels.Add(UpperSpec, UpperSpec, 'Upper Spec'); + end; + + if not IsNaN(TargetSpec) then begin + FChartFrame.HorLine(TargetSpec, TARGET_COLOR, psSolid, 'Target'); + rightLabels.Add(TargetSpec, TargetSpec, 'Target'); + end; + + if not IsNaN(LowerSpec) then + begin + if IsNaN(UpperSpec) then + s := 'Lower Spec' + else + s := 'Upper/Lower Spec'; + constLine := FChartFrame.HorLine(LowerSpec, SPEC_COLOR, SPEC_STYLE, s); + constLine.Legend.Visible := not IsNaN(UpperSpec); //UpSpecChk.Checked; + rightLabels.Add(LowerSpec, LowerSpec, 'Lower Spec'); + end; +end; + +procedure TBasicSPCForm.Reset; +var + i : integer; +begin + VarList.Clear; + GroupEdit.Text := ''; + MeasEdit.Text := ''; + for i := 1 to NoVariables do + VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); + FChartFrame.Clear; +end; + + +procedure TBasicSPCForm.ResetBtnClick(Sender: TObject); +begin + Reset; +end; + + +procedure TBasicSPCForm.tbPrintClick(Sender: TObject); +begin + FChartFrame.Print; +end; + + +procedure TBasicSPCForm.tbSaveClick(Sender: TObject); +begin + FChartFrame.Save; +end; + + +function TBasicSPCForm.Validate(out AMsg: String; out AControl: TWinControl): Boolean; +var + x: Double; +begin + Result := false; + if GroupEdit.Visible and (GroupEdit.Text = '') then begin + AMsg := 'Group variable not specified.'; + AControl := GroupEdit; + exit; + end; + if MeasEdit.Visible and (MeasEdit.Text = '') then + begin + AMsg := 'Measurement variable not specified.'; + AControl := MeasEdit; + exit; + end; + Result := true; +end; + + +procedure TBasicSPCForm.VarListClick(Sender: TObject); +var + index: integer; +begin + index := VarList.ItemIndex; + if index > -1 then + begin + if GroupEdit.Visible and (GroupEdit.Text = '') then + GroupEdit.Text := VarList.Items[index] + else + MeasEdit.Text := VarList.Items[index]; + VarList.Items.Delete(index); + end; +end; + +end. + diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.lfm b/applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.lfm new file mode 100644 index 000000000..d81612215 --- /dev/null +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.lfm @@ -0,0 +1,16 @@ +inherited SChartForm: TSChartForm + Caption = 'Sigma Chart' + inherited PageControl1: TPageControl + inherited ReportPage: TTabSheet + inherited Panel1: TPanel + inherited ReportMemo: TMemo + Left = 4 + Height = 374 + Top = 4 + Width = 521 + BorderSpacing.Around = 4 + end + end + end + end +end diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.pas b/applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.pas new file mode 100644 index 000000000..30f57155a --- /dev/null +++ b/applications/lazstats/source/forms/analysis/statistical_process_control/schartunit.pas @@ -0,0 +1,176 @@ +unit SChartUnit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, + BasicSPCUnit; + +type + + { TSChartForm } + + TSChartForm = class(TBasicSPCForm) + private + + protected + procedure Compute; override; + + public + + end; + +var + SChartForm: TSChartForm; + +implementation + +{$R *.lfm} + +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; + ColNoSelected: IntDyneVec = nil; + groups: StrDyneVec = nil; + means: DblDyneVec = nil; + stddev: DblDyneVec = nil; + count: IntDyneVec = nil; + numGrps: Integer = 0; + grp: String; + grpIndex: Integer; + X, Xsq: Double; + seMean, grandMean, grandSigma, grandSD: Double; + B, C4, gamma, D3Value, D4Value: Double; + xmin, xmax: Double; + sizeError: Boolean; + i, j: Integer; + lReport: TStrings; +begin + SetLength(ColNoSelected, 2); + ColNoSelected[0] := GrpVar; + ColNoSelected[1] := MeasVar; + + grpsize := 0; + oldgrpsize := 0; + groups := GetGroups; + numGrps := Length(groups); + + SetLength(means, numGrps); + SetLength(count, numGrps); + SetLength(stddev, numGrps); + seMean := 0.0; + grandMean := 0.0; + grandSigma := 0.0; + sizeError := false; + + // calculate group ranges, grand mean, group sd's, semeans + for j := 0 to numGrps-1 do // groups + begin + xmin := Infinity; + xmax := -Infinity; + for i := 1 to NoCases do + begin + if not GoodRecord(i, Length(ColNoSelected), ColNoSelected) then continue; + grp := Trim(OS3MainFrm.DataGrid.Cells[GrpVar,i]); + grpIndex := IndexOfString(groups, grp); + if grpIndex = j then + begin + X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[MeasVar, i])); + Xsq := X*X; + if X > xmax then xmax := X; + if X < xmin then xmin := X; + inc(count[grpIndex]); + means[grpIndex] := means[grpIndex] + X; + stddev[grpIndex] := stddev[grpIndex] + Xsq; + seMean := seMean + Xsq; + grandMean := grandMean + X; + end; + end; // next case + stddev[j] := stddev[j] - sqr(means[j]) / count[j]; + stddev[j] := stddev[j] / (count[j] - 1); + stddev[j] := sqrt(stddev[j]); + means[j] := means[j] / count[j]; + grandSigma := grandSigma + stddev[j]; + grpSize := count[j]; + if j = 0 then oldGrpSize := grpSize; + if oldGrpSize <> grpSize then + sizeError := true; + end; + + if (grpSize < 2) or (grpSize > 25) or sizeError then + begin + ErrorMsg('Group size error.'); + exit; + end; + + seMean := seMean - sqr(grandMean)/NoCases; + seMean := seMean / (NoCases - 1); + seMean := sqrt(seMean); + grandSD := seMean; + seMean := seMean / sqrt(NoCases); + grandMean := grandMean / NoCases; + grandSigma := grandSigma / numGrps; + D3Value := D3[grpSize-1]; + D4Value := D4[grpSize-1]; + C4 := sqrt(2.0 / (grpSize - 1)); + gamma := exp(GammaLn(grpSize / 2.0)); + C4 := C4 * gamma; + gamma := exp(GammaLn((grpSize-1) / 2.0)); + C4 := C4 / gamma; + B := grandSigma * sqrt(1.0 - (C4 * C4)) / C4; + UCL := grandSigma + 3.0 * B; + LCL := grandSigma - 3.0 * B; + if (LCL < 0.0) then LCL := 0.0; + + // print results + lReport := TStringList.Create; + try + lReport.Add('Sigma Chart Results'); + 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 + lReport.Free; + end; + + // show graph + PlotMeans( + Format('Sigma Chart for "%s"', [GetFileName]), + GroupEdit.Text, Format('StdDev(%s)', [MeasEdit.Text]), + 'Group Sigma', 'Mean', + groups, stdDev, nil, + UCL, LCL, grandSigma, + NaN, NaN, NaN + ); +end; + +end. + diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/sigmachartunit.lfm b/applications/lazstats/source/forms/analysis/statistical_process_control/sigmachartunit.lfm deleted file mode 100644 index 8d296c8f2..000000000 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/sigmachartunit.lfm +++ /dev/null @@ -1,196 +0,0 @@ -object SigmaChartFrm: TSigmaChartFrm - Left = 533 - Height = 298 - Top = 243 - Width = 397 - HelpType = htKeyword - HelpKeyword = 'html/SControlChart.htm' - AutoSize = True - Caption = 'Sigma Charting' - ClientHeight = 298 - ClientWidth = 397 - OnActivate = FormActivate - OnCreate = FormCreate - OnShow = FormShow - Position = poMainFormCenter - LCLVersion = '2.1.0.0' - object Label1: TLabel - AnchorSideLeft.Control = Owner - AnchorSideTop.Control = Owner - Left = 8 - Height = 15 - Top = 8 - Width = 97 - BorderSpacing.Left = 8 - BorderSpacing.Top = 8 - Caption = 'Selection Variables' - ParentColor = False - end - object Label2: TLabel - AnchorSideLeft.Control = GroupEdit - AnchorSideTop.Control = Owner - Left = 234 - Height = 15 - Top = 8 - Width = 77 - BorderSpacing.Top = 8 - Caption = 'Group Variable' - ParentColor = False - end - object Label3: TLabel - AnchorSideLeft.Control = MeasEdit - Left = 234 - Height = 15 - Top = 80 - Width = 117 - Caption = 'Measurement Variable' - ParentColor = False - end - object VarList: TListBox - AnchorSideLeft.Control = Owner - AnchorSideTop.Control = Label1 - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = GroupEdit - AnchorSideBottom.Control = Bevel2 - Left = 8 - Height = 226 - Top = 23 - Width = 218 - Anchors = [akTop, akLeft, akRight, akBottom] - BorderSpacing.Left = 8 - BorderSpacing.Right = 8 - Constraints.MinHeight = 220 - ItemHeight = 0 - OnClick = VarListClick - TabOrder = 0 - end - object GroupEdit: TEdit - AnchorSideLeft.Control = Bevel1 - AnchorSideLeft.Side = asrBottom - AnchorSideTop.Control = Label2 - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - Left = 234 - Height = 23 - Top = 25 - Width = 155 - Anchors = [akTop, akLeft, akRight] - BorderSpacing.Top = 2 - BorderSpacing.Right = 8 - ReadOnly = True - TabOrder = 1 - Text = 'GroupEdit' - end - object MeasEdit: TEdit - AnchorSideLeft.Control = Bevel1 - AnchorSideLeft.Side = asrBottom - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - Left = 234 - Height = 23 - Top = 96 - Width = 155 - Anchors = [akTop, akLeft, akRight] - BorderSpacing.Right = 8 - ReadOnly = True - TabOrder = 2 - Text = 'MeasEdit' - end - object Panel1: TPanel - Left = 8 - Height = 25 - Top = 265 - Width = 381 - Align = alBottom - AutoSize = True - BorderSpacing.Around = 8 - BevelOuter = bvNone - ClientHeight = 25 - ClientWidth = 381 - TabOrder = 3 - object ResetBtn: TButton - AnchorSideLeft.Control = Panel1 - AnchorSideTop.Control = Panel1 - AnchorSideRight.Control = ComputeBtn - Left = 180 - 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 = 242 - 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 = 121 - 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 - AnchorSideRight.Side = asrBottom - Left = 326 - Height = 25 - Top = 0 - Width = 55 - Anchors = [akTop, akRight] - AutoSize = True - Caption = 'Close' - ModalResult = 11 - TabOrder = 3 - end - end - object Bevel2: TBevel - AnchorSideTop.Control = Panel1 - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - AnchorSideBottom.Control = Panel1 - Left = 0 - Height = 8 - Top = 249 - Width = 397 - Anchors = [akLeft, akRight, akBottom] - Shape = bsBottomLine - end - object Bevel1: TBevel - AnchorSideLeft.Control = Owner - AnchorSideLeft.Side = asrCenter - AnchorSideTop.Control = Owner - Left = 162 - Height = 16 - Top = 0 - Width = 72 - Shape = bsSpacer - end -end diff --git a/applications/lazstats/source/forms/analysis/statistical_process_control/sigmachartunit.pas b/applications/lazstats/source/forms/analysis/statistical_process_control/sigmachartunit.pas deleted file mode 100644 index 4048c264c..000000000 --- a/applications/lazstats/source/forms/analysis/statistical_process_control/sigmachartunit.pas +++ /dev/null @@ -1,424 +0,0 @@ -unit SigmaChartUnit; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, - StdCtrls, Buttons, ExtCtrls, - MainUnit, Globals, OutputUnit, FunctionsLib, BlankFrmUnit, ContextHelpUnit; - -type - - { TSigmaChartFrm } - - TSigmaChartFrm = class(TForm) - Bevel1: TBevel; - Bevel2: TBevel; - ComputeBtn: TButton; - HelpBtn: TButton; - Panel1: TPanel; - ResetBtn: TButton; - MeasEdit: TEdit; - GroupEdit: TEdit; - Label1: TLabel; - Label2: TLabel; - Label3: TLabel; - CloseBtn: TButton; - VarList: TListBox; - procedure ComputeBtnClick(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 declarations } - FAutoSized: boolean; - procedure PlotMeans(var means: DblDyneVec; - NoGrps: integer; - UCL, LCL, GrandMean: double; - TargetSpec, LowerSpec, UpperSpec: double); - public - { public declarations } - end; - -var - SigmaChartFrm: TSigmaChartFrm; - -implementation - -uses - Math, - MathUnit; - -{ TSigmaChartFrm } - -procedure TSigmaChartFrm.ResetBtnClick(Sender: TObject); -var - i : integer; -begin - VarList.Clear; - GroupEdit.Text := ''; - MeasEdit.Text := ''; - for i := 1 to NoVariables do - VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]); -end; - -procedure TSigmaChartFrm.VarListClick(Sender: TObject); -var - index: integer; -begin - index := VarList.ItemIndex; - if Index > -1 then - begin - if GroupEdit.Text = '' then - GroupEdit.Text := VarList.Items[index] - else - MeasEdit.Text := VarList.Items[index]; - VarList.Items.Delete(index); - end; -end; - -procedure TSigmaChartFrm.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; - - Constraints.MinWidth := Width; - Constraints.MinHeight := Height; - - FAutoSized := true; -end; - -procedure TSigmaChartFrm.FormCreate(Sender: TObject); -begin - Assert(OS3MainFrm <> nil); - if BlankFrm = nil then - Application.CreateForm(TBlankFrm, BlankFrm); -end; - -procedure TSigmaChartFrm.FormShow(Sender: TObject); -begin - ResetBtnClick(self); -end; - -procedure TSigmaChartFrm.HelpBtnClick(Sender: TObject); -begin - if ContextHelpForm = nil then - Application.CreateForm(TContextHelpForm, ContextHelpForm); - ContextHelpForm.HelpMessage((Sender as TButton).tag); -end; - -procedure TSigmaChartFrm.ComputeBtnClick(Sender: TObject); -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, GrpVar, MeasVar, mingrp, maxgrp, G, range, grpsize: integer; - oldgrpsize: integer; - X, UCL, LCL, UpperSpec, LowerSpec, TargetSpec: double; - xmin, xmax, GrandMean, GrandSD, semean: double; - GrandSigma, C4, gamma, B: double; - D3Value, D4Value: Double; - means, stddev: DblDyneVec; - count: IntDyneVec; - cellstring: string; - sizeerror: boolean; - lReport: TStrings; - - procedure CleanUp; - begin - stddev := nil; - count := nil; - means := nil; - end; - -begin - if (GroupEdit.Text = '') then - begin - MessageDlg('Group variable is not specified.', mtError, [mbOk], 0); - exit; - end; - - if (MeasEdit.Text = '') then - begin - MessageDlg('Measurement variable is not specified.', mtError, [mbOK], 0); - exit; - end; - - GrpVar := 1; - MeasVar := 2; - UpperSpec := 0.0; - LowerSpec := 0.0; - TargetSpec := 0.0; - 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; - - mingrp := 10000; - maxgrp := -10000; - for i := 1 to NoCases do - begin - 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); - - for i := 0 to range-1 do - begin - count[i] := 0; - means[i] := 0.0; - stddev[i] := 0.0; - end; - semean := 0.0; - GrandMean := 0.0; - GrandSigma := 0.0; - sizeerror := false; - - // calculate group ranges, grand mean, group sd's, semeans - for j := 1 to range do // groups - begin - xmin := 10000.0; - xmax := -10000.0; - for i := 1 to NoCases do - begin - G := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[GrpVar,i]))); - G := G - mingrp + 1; - if G = j then - begin - X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[MeasVar,i])); - if X > xmax then xmax := X; - if X < xmin then xmin := X; - means[G-1] := means[G-1] + X; - count[G-1] := count[G-1] + 1; - stddev[G-1] := stddev[G-1] + (X * X); - semean := semean + (X * X); - GrandMean := GrandMean + X; - end; - end; // next case - stddev[j-1] := stddev[j-1] - (means[j-1] * means[j-1] / count[j-1]); - stddev[j-1] := stddev[j-1] / (count[j-1] - 1); - stddev[j-1] := sqrt(stddev[j-1]); - means[j-1] := means[j-1] / count[j-1]; - GrandSigma := GrandSigma + stddev[j-1]; - grpsize := count[j-1]; - if j = 1 then oldgrpsize := grpsize; - if oldgrpsize <> grpsize then sizeerror := true; - end; - - if (grpsize < 2) or (grpsize > 25) or sizeError then - begin - MessageDlg('Group sizes error.', mtError, [mbOK], 0); - CleanUp; - exit; - end; - - semean := semean - sqr(GrandMean)/NoCases; - semean := semean / (NoCases - 1); - semean := sqrt(semean); - GrandSD := semean; - semean := semean / sqrt(NoCases); - GrandMean := GrandMean / NoCases; - GrandSigma := GrandSigma / range; - D3Value := D3[grpsize-1]; - D4Value := D4[grpsize-1]; - C4 := sqrt(2.0 / (grpsize - 1)); - gamma := exp(GammaLn(grpsize / 2.0)); - C4 := C4 * gamma; - gamma := exp(GammaLn((grpsize-1) / 2.0)); - C4 := C4 / gamma; - B := GrandSigma * sqrt(1.0 - (C4 * C4)) / C4; - UCL := GrandSigma + 3.0 * B; - LCL := GrandSigma - 3.0 * B; - if (LCL < 0.0) then LCL := 0.0; - - // printed results - lReport := TStringList.Create; - try - lReport.Add('Sigma Chart Results'); - lReport.Add(''); - lReport.Add('Group Size Mean Std.Dev.'); - lReport.Add('_____ ____ _________ ________'); - for i := 0 to range-1 do - lReport.Add(' %3d %3d %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]); - - DisplayReport(lReport); - finally - lReport.Free; - end; - - // show graph - PlotMeans(stddev, range, UCL, LCL, GrandSigma, TargetSpec, LowerSpec, UpperSpec); - - // clean up - CleanUp; -end; - -procedure TSigmaChartFrm.PlotMeans(var means: DblDyneVec; NoGrps: integer; - UCL, LCL, GrandMean: double; TargetSpec, LowerSpec, UpperSpec: double); -var - i, xpos, ypos, hleft, hright, vtop, vbottom, imagewide : integer; - vhi, hwide, offset, strhi : integer; - imagehi, maxval, minval, valincr, Yvalue : double; - Title : string; -begin - maxval := -10000.0; - minval := 10000.0; - for i := 0 to NoGrps-1 do - begin - if means[i] > maxval then maxval := means[i]; - if means[i] < minval then minval := means[i]; - end; - if UCL > maxval then maxval := UCL; - if LCL < minval then minval := LCL; - BlankFrm.Image1.Canvas.Clear; - BlankFrm.Show; - Title := 'SIGMA CHART FOR : ' + OS3MainFrm.FileNameEdit.Text; - BlankFrm.Caption := Title; - imagewide := BlankFrm.Width; - imagehi := BlankFrm.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 := '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 horizontal axis - BlankFrm.Image1.Canvas.MoveTo(hleft,vbottom + 20); - BlankFrm.Image1.Canvas.LineTo(hright,vbottom + 20); - for i := 1 to NoGrps do - begin - ypos := vbottom + 10; - xpos := round((hwide / NoGrps)* i + hleft); - BlankFrm.Image1.Canvas.MoveTo(xpos,ypos); - ypos := ypos + 10; - BlankFrm.Image1.Canvas.LineTo(xpos,ypos); - Title := format('%d',[i]); - offset := BlankFrm.Image1.Canvas.TextWidth(Title) div 2; - strhi := BlankFrm.Image1.Canvas.TextHeight(Title); - xpos := xpos - offset; - ypos := ypos + strhi; - BlankFrm.Image1.Canvas.Pen.Color := clBlack; - BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title); - xpos := 10; - BlankFrm.Image1.Canvas.TextOut(xpos,ypos,'GROUPS:'); - end; - - // Draw vertical axis - valincr := (maxval - minval) / 10.0; - for i := 1 to 11 do - begin - Title := format('%8.2f',[maxval - ((i-1)*valincr)]); - strhi := BlankFrm.Image1.Canvas.TextHeight(Title); - xpos := 10; - Yvalue := maxval - (valincr * (i-1)); - ypos := round(vhi * ( (maxval - Yvalue) / (maxval - minval))); - ypos := ypos + vtop - strhi div 2; - BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title); - end; - - // draw lines for means of the groups - ypos := round(vhi * ( (maxval - means[0]) / (maxval - minval))); - ypos := ypos + vtop; - xpos := round((hwide / NoGrps) + hleft); - BlankFrm.Image1.Canvas.MoveTo(xpos,ypos); - BlankFrm.Image1.Canvas.Pen.Color := clBlack; - for i := 2 to NoGrps do - begin - ypos := round(vhi * ( (maxval - means[i-1]) / (maxval - minval))); - ypos := ypos + vtop; - xpos := round((hwide / NoGrps)* i + hleft); - BlankFrm.Image1.Canvas.LineTo(xpos,ypos); - end; - - // Draw 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); -end; - -initialization - {$I sigmachartunit.lrs} - -end. - diff --git a/applications/lazstats/source/forms/mainunit.lfm b/applications/lazstats/source/forms/mainunit.lfm index 7555209a2..9373fc82e 100644 --- a/applications/lazstats/source/forms/mainunit.lfm +++ b/applications/lazstats/source/forms/mainunit.lfm @@ -442,7 +442,7 @@ object OS3MainFrm: TOS3MainFrm OnClick = mnuEditPasteRowClick end end - object MenuItem5: TMenuItem + object mnuAnalysis: TMenuItem Caption = 'Analyses' object MenuItem32: TMenuItem Caption = 'Descriptive' @@ -861,35 +861,35 @@ object OS3MainFrm: TOS3MainFrm OnClick = lifetableClick end end - object MenuItem41: TMenuItem + object mnuAnalysisSPC: TMenuItem Caption = 'Statistical Process Control' - object MenuItem116: TMenuItem + object mnuAnalysisSPC_XBar: TMenuItem Caption = 'XBAR Chart' - OnClick = MenuItem116Click + OnClick = mnuAnalysisSPC_XBarClick end - object MenuItem117: TMenuItem + object mnuAnalysisSPC_Range: TMenuItem Caption = 'Range Chart' - OnClick = MenuItem117Click + OnClick = mnuAnalysisSPC_RangeClick end - object MenuItem118: TMenuItem + object mnuAnalysisSPC_SChart: TMenuItem Caption = 'S Control Chart' - OnClick = MenuItem118Click + OnClick = mnuAnalysisSPC_SChartClick end - object MenuItem6: TMenuItem + object mnuAnalysisSPC_CUMSUM: TMenuItem Caption = 'CUMSUM Chart' - OnClick = MenuItem6Click + OnClick = mnuAnalysisSPC_CUMSUMClick end - object MenuItem119: TMenuItem + object mnuAnalysisSPC_CChart: TMenuItem Caption = 'Defect (nonconformity) c Chart' - OnClick = MenuItem119Click + OnClick = mnuAnalysisSPC_CChartClick end - object pcontrochart: TMenuItem + object mnuAnalysisSPC_PChart: TMenuItem Caption = 'p Control Chart' - OnClick = pcontrochartClick + OnClick = mnuAnalysisSPC_PChartClick end - object MenuItem120: TMenuItem + object mnuAnalysisSPC_UChart: TMenuItem Caption = 'Defects per Unit u Chart' - OnClick = MenuItem120Click + OnClick = mnuAnalysisSPC_UChartClick end end object MenuItem9: TMenuItem @@ -1064,6 +1064,10 @@ object OS3MainFrm: TOS3MainFrm OnClick = mnuHelpUsingGridClick end end + object MenuItem2: TMenuItem + Caption = 'MenuItem2' + OnClick = MenuItem2Click + end end object OpenDialog1: TOpenDialog Left = 312 diff --git a/applications/lazstats/source/forms/mainunit.pas b/applications/lazstats/source/forms/mainunit.pas index 430940419..e524ca71a 100644 --- a/applications/lazstats/source/forms/mainunit.pas +++ b/applications/lazstats/source/forms/mainunit.pas @@ -59,14 +59,95 @@ type MenuItem113: TMenuItem; MenuItem114: TMenuItem; MenuItem115: TMenuItem; - MenuItem116: TMenuItem; - MenuItem117: TMenuItem; - MenuItem118: TMenuItem; - MenuItem119: TMenuItem; - MenuItem12: TMenuItem; - MenuItem120: TMenuItem; - mnuHelpAbout: TMenuItem; + + mnuAnalysis: TMenuItem; + mnuAnalysisSPC: TMenuItem; + mnuAnalysisSPC_CChart: TMenuItem; + mnuAnalysisSPC_CUMSUM: TMenuItem; + mnuAnalysisSPC_PChart: TMenuItem; + mnuAnalysisSPC_Range: TMenuItem; + mnuAnalysisSPC_SChart: TMenuItem; + mnuAnalysisSPC_UChart: TMenuItem; + mnuAnalysisSPC_XBar: TMenuItem; + + mnuEdit: TMenuItem; + mnuEditCopyCells: TMenuItem; + mnuEditCopyCol: TMenuItem; + mnuEditCopyRow: TMenuItem; + mnuEditCutCells: TMenuItem; + mnuEditCutCol: TMenuItem; + mnuEditCutRow: TMenuItem; + mnuEditDIVIDER1: TMenuItem; + mnuEditDIVIDER2: TMenuItem; + mnuEditNewCol: TMenuItem; + mnuEditNewRow: TMenuItem; + mnuEditPasteCells: TMenuItem; + mnuEditPasteCol: TMenuItem; + mnuEditPasteRow: TMenuItem; + mnuFileClose: TMenuItem; + mnuFileExport: TMenuItem; + mnuFileExportCSV: TMenuItem; + mnuFileExportSSV: TMenuItem; + mnuFileExportTab: TMenuItem; + mnuFileExit: TMenuItem; + mnuFileImport: TMenuItem; + mnuFileImportCSV: TMenuItem; + mnuFileImportSSV: TMenuItem; + mnuFileImportTAB: TMenuItem; + mnuFileNew: TMenuItem; + mnuFileOpen: TMenuItem; + mnuFileSave: TMenuItem; + + mnuHelpAbout: TMenuItem; + mnuHelpLicense: TMenuItem; + mnuHelpShowTOC: TMenuItem; + mnuHelpUsingGrid: TMenuItem; + + mnuIOptions: TMenuItem; + + mnuSimulations: TMenuItem; + mnuSimBivarScatterPlot: TMenuItem; + mnuSimChiSqProb: TMenuItem; + mnuSimDistPlots: TMenuItem; + mnuSimFProb: TMenuItem; + mnuSimGenerateRandomValues: TMenuItem; + mnuSimGenerateSeqValues: TMenuItem; + mnuSimHyperGeomProb: TMenuItem; + mnuSimInverseZ: TMenuItem; + mnuSimMultiVarDists: TMenuItem; + mnuSimPowerCurves: TMenuItem; + mnuSimProbabilities: TMenuItem; + mnuSimProbBetween: TMenuItem; + mnuSimProbDIVIDER: TMenuItem; + mnuSimProbGreaterZ: TMenuItem; + mnuSimProbLessZ: TMenuItem; + mnuSimStudentTProb: TMenuItem; + mnuSimTypeErrorCurves: TMenuItem; + + mnuTools: TMenuItem; + mnuToolsCalculator: TMenuItem; + mnuToolsFormatGrid: TMenuItem; + mnuToolsJPEGViewer: TMenuItem; + mnuToolsLoadSubFile: TMenuItem; + mnuToolsOutputForm: TMenuItem; + mnuToolsPrintGrid: TMenuItem; + mnuToolsSelectCases: TMenuItem; + mnuToolsSmooth: TMenuItem; + mnuToolsSortCases: TMenuItem; + mnuToolsStrToInt: TMenuItem; + mnuToolsSwapDecType: TMenuItem; + mnuToolsSwapRowsCols: TMenuItem; + + mnuVariables: TMenuItem; + mnuVariablesDefine: TMenuItem; + mnuVariablesEquationEditor: TMenuItem; + mnuVariablesPrintDefs: TMenuItem; + mnuVariablesRecode: TMenuItem; + mnuVariablesTransform: TMenuItem; + + MenuItem12: TMenuItem; + MenuItem2: TMenuItem; MenuItem14: TMenuItem; MenuItem15: TMenuItem; MenuItem17: TMenuItem; @@ -79,11 +160,6 @@ type MenuItem25: TMenuItem; MenuItem26: TMenuItem; MenuItem27: TMenuItem; - mnuEditCopyCells: TMenuItem; - mnuEditPasteCells: TMenuItem; - mnuEditCutCells: TMenuItem; - mnuHelpUsingGrid: TMenuItem; - mnuToolsOutputForm: TMenuItem; MenuItem29: TMenuItem; MenuItem31: TMenuItem; MenuItem33: TMenuItem; @@ -91,18 +167,11 @@ type CompareDists: TMenuItem; MatManMnu: TMenuItem; GrdBkMnu: TMenuItem; - mnuSimInverseZ: TMenuItem; - mnuSimChiSqProb: TMenuItem; - mnuSimFProb: TMenuItem; - mnuSimHyperGeomProb: TMenuItem; BinA: TMenuItem; BartlettTest: TMenuItem; GrpFreq: TMenuItem; Correspondence: TMenuItem; KSTest: TMenuItem; - mnuVariablesEquationEditor: TMenuItem; - mnuToolsCalculator: TMenuItem; - mnuToolsJPEGViewer: TMenuItem; MedianPolish: TMenuItem; DataSmooth: TMenuItem; ItemBankMenuItem: TMenuItem; @@ -111,17 +180,12 @@ type LSMRitem: TMenuItem; MenuItem42: TMenuItem; MenuItem43: TMenuItem; - mnuSimProbDIVIDER: TMenuItem; MenuItem45: TMenuItem; MenuItem46: TMenuItem; - mnuHelpLicense: TMenuItem; MenuItem47: TMenuItem; - mnuEditDIVIDER2: TMenuItem; - mnuEditDIVIDER1: TMenuItem; MenuItem50: TMenuItem; MenuItem51: TMenuItem; MenuItem52: TMenuItem; - mnuHelpShowTOC: TMenuItem; SimpChiSqr: TMenuItem; SRHItem: TMenuItem; OneCaseAnova: TMenuItem; @@ -129,34 +193,16 @@ type Sens: TMenuItem; XvsMultY: TMenuItem; RunsTest: TMenuItem; - mnuToolsSmooth: TMenuItem; NestedABC: TMenuItem; - mnuSimStudentTProb: TMenuItem; - mnuSimProbBetween: TMenuItem; - mnuSimProbLessZ: TMenuItem; - mnuSimProbGreaterZ: TMenuItem; - mnuSimProbabilities: TMenuItem; - mnuToolsStrToInt: TMenuItem; - mnuToolsSwapDecType: TMenuItem; PicView: TMenuItem; mnuShowOptions: TMenuItem; WghtedKappa: TMenuItem; WLSReg: TMenuItem; TwoSLSReg: TMenuItem; RiditAnalysis: TMenuItem; - MenuItem6: TMenuItem; MenuItem9: TMenuItem; - pcontrochart: TMenuItem; OpenDialog1: TOpenDialog; SaveDialog1: TSaveDialog; - mnuEditNewCol: TMenuItem; - mnuEditCopyCol: TMenuItem; - mnuEditCutCol: TMenuItem; - mnuEditPasteCol: TMenuItem; - mnuEditNewRow: TMenuItem; - mnuEditCopyRow: TMenuItem; - mnuEditCutRow: TMenuItem; - mnuEditPasteRow: TMenuItem; MenuItem71: TMenuItem; MenuItem72: TMenuItem; MenuItem73: TMenuItem; @@ -196,28 +242,6 @@ type Label1: TLabel; MainMenu1: TMainMenu; MenuItem1: TMenuItem; - mnuFileOpen: TMenuItem; - mnuFileNew: TMenuItem; - mnuFileImport: TMenuItem; - mnuFileExport: TMenuItem; - mnuFileExit: TMenuItem; - mnuFileImportTAB: TMenuItem; - mnuFileImportCSV: TMenuItem; - mnuFileImportSSV: TMenuItem; - mnuVariables: TMenuItem; - mnuFileExportTab: TMenuItem; - mnuFileExportCSV: TMenuItem; - mnuFileExportSSV: TMenuItem; - mnuVariablesDefine: TMenuItem; - mnuVariablesPrintDefs: TMenuItem; - mnuVariablesTransform: TMenuItem; - mnuVariablesRecode: TMenuItem; - mnuToolsFormatGrid: TMenuItem; - mnuToolsSortCases: TMenuItem; - mnuToolsPrintGrid: TMenuItem; - mnuTools: TMenuItem; - mnuToolsSelectCases: TMenuItem; - mnuToolsLoadSubFile: TMenuItem; MenuItem32: TMenuItem; OneSampTests: TMenuItem; MenuItem34: TMenuItem; @@ -226,9 +250,7 @@ type MenuItem37: TMenuItem; MenuItem38: TMenuItem; MenuItem39: TMenuItem; - mnuEdit: TMenuItem; MenuItem40: TMenuItem; - MenuItem41: TMenuItem; Distributions: TMenuItem; FreqAnal: TMenuItem; CrossTabs: TMenuItem; @@ -237,7 +259,6 @@ type NormalityTests: TMenuItem; ThreeDRotate: TMenuItem; PlotXvsY: TMenuItem; - MenuItem5: TMenuItem; BubblePlot: TMenuItem; StemLeaf: TMenuItem; MultXvsY: TMenuItem; @@ -248,21 +269,10 @@ type WithinAnova: TMenuItem; AxSAnova: TMenuItem; ABSAnova: TMenuItem; - mnuIOptions: TMenuItem; Ancova: TMenuItem; GLM: TMenuItem; LatinSquares: TMenuItem; - mnuSimBivarScatterPlot: TMenuItem; - mnuSimMultiVarDists: TMenuItem; - mnuSimTypeErrorCurves: TMenuItem; - mnuSimPowerCurves: TMenuItem; - mnuSimDistPlots: TMenuItem; - mnuSimGenerateSeqValues: TMenuItem; - mnuSimulations: TMenuItem; - mnuSimGenerateRandomValues: TMenuItem; MenuItem8: TMenuItem; - mnuToolsSwapRowsCols: TMenuItem; - mnuFileSave: TMenuItem; Panel1: TPanel; Panel2: TPanel; DataGrid: TStringGrid; @@ -272,6 +282,16 @@ type procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormShow(Sender: TObject); + procedure MenuItem2Click(Sender: TObject); + + // Menu 'Analysis" / "Statistical Process Control" + procedure mnuAnalysisSPC_CChartClick(Sender: TObject); + procedure mnuAnalysisSPC_CUMSUMClick(Sender: TObject); + procedure mnuAnalysisSPC_PChartClick(Sender: TObject); + procedure mnuAnalysisSPC_RangeClick(Sender: TObject); + procedure mnuAnalysisSPC_SChartClick(Sender: TObject); + procedure mnuAnalysisSPC_UChartClick(Sender: TObject); + procedure mnuAnalysisSPC_XBarClick(Sender: TObject); // Menu "Edit" procedure mnuEditCopyCellsClick(Sender: TObject); @@ -397,18 +417,12 @@ type procedure MenuItem113Click(Sender: TObject); procedure MenuItem114Click(Sender: TObject); procedure MenuItem115Click(Sender: TObject); - procedure MenuItem116Click(Sender: TObject); - procedure MenuItem117Click(Sender: TObject); - procedure MenuItem118Click(Sender: TObject); - procedure MenuItem119Click(Sender: TObject); procedure MenuItem11Click(Sender: TObject); - procedure MenuItem120Click(Sender: TObject); procedure MenuItem14Click(Sender: TObject); procedure MenuItem27Click(Sender: TObject); procedure MenuItem29Click(Sender: TObject); procedure MenuItem31Click(Sender: TObject); procedure MenuItem33Click(Sender: TObject); - procedure MenuItem6Click(Sender: TObject); procedure MenuItem71Click(Sender: TObject); procedure MenuItem72Click(Sender: TObject); procedure MenuItem73Click(Sender: TObject); @@ -443,7 +457,6 @@ type procedure NormalityTestsClick(Sender: TObject); procedure OneCaseAnovaClick(Sender: TObject); procedure OneSampTestsClick(Sender: TObject); - procedure pcontrochartClick(Sender: TObject); // procedure PicViewClick(Sender: TObject); procedure PlotXvsYClick(Sender: TObject); procedure PropDiffClick(Sender: TObject); @@ -494,8 +507,13 @@ uses CompRelUnit, KR21Unit, SpBrUnit, RelChangeUnit, DIFUnit, PolyDIFUnit, ChiSqrUnit, SpearmanUnit, MannWhitUUnit, ExactUnit, ConcordanceUnit, KWAnovaUnit, WilcoxonUnit, CochranQUnit, SignTestUnit, FriedmanUnit, - BinomialUnit, KendallTauUnit, KaplanMeierUnit, XBarUnit, RChartUnit, - SigmaChartUnit, CUMSUMUNIT, CCHARTUNIT, PChartUnit, UChartUnit, CorSimUnit, + BinomialUnit, KendallTauUnit, KaplanMeierUnit, + + // Statistical process control + XBarUnit, RChartUnit, SChartUnit, CUMSUMUNIT, CCHARTUNIT, + PChartUnit, UChartUnit, //SigmaChartUnit, + + CorSimUnit, ErrorCurvesUnit, PCurvesUnit, DistribUnit, GenSeqUnit, GenRndValsUnit, MultGenUnit, LoanItUnit, SumYrsDepUnit, SLDUnit, DblDeclineUnit, RIDITUnit, TwoSLSUnit, WLSUnit, SortCasesUnit, @@ -587,6 +605,15 @@ begin end; end; +procedure TOS3MainFrm.MenuItem2Click(Sender: TObject); +begin + { + if SChartForm = nil then + Application.CreateForm(TSChartForm, SChartForm); + SChartForm.ShowModal; + } +end; + // Menu "Analysis" > "Financial" > "Double Declining Value" procedure TOS3MainFrm.MenuItem27Click(Sender: TObject); begin @@ -620,7 +647,7 @@ begin end; // Menu "Analysis" > "Statistical Process Control" > "CUMSUM Chart" -procedure TOS3MainFrm.MenuItem6Click(Sender: TObject); +procedure TOS3MainFrm.mnuAnalysisSPC_CUMSUMClick(Sender: TObject); begin if CUMSUMFrm = nil then Application.CreateForm(TCUMSUMFrm, CUMSUMFrm); @@ -897,7 +924,7 @@ end; // Menu "Analysis" > "Statistical Process Control" > "p Control Chart" -procedure TOS3MainFrm.pcontrochartClick(Sender: TObject); +procedure TOS3MainFrm.mnuAnalysisSPC_PChartClick(Sender: TObject); begin if pChartFrm = nil then Application.CreateForm(TpChartFrm, pChartFrm); @@ -2107,7 +2134,7 @@ begin end; // Menu "Analysis" > "Statistical Process Control" > "XBAR Chart" -procedure TOS3MainFrm.MenuItem116Click(Sender: TObject); +procedure TOS3MainFrm.mnuAnalysisSPC_XBarClick(Sender: TObject); begin if XBarFrm = nil then Application.CreateForm(TXBarFrm, XBarFrm); @@ -2115,7 +2142,7 @@ begin end; // Menu "Analysis" > "Statistical Process Control" > "Range Chart" -procedure TOS3MainFrm.MenuItem117Click(Sender: TObject); +procedure TOS3MainFrm.mnuAnalysisSPC_RangeClick(Sender: TObject); begin if RChartFrm = nil then Application.CreateForm(TRChartFrm, RChartFrm); @@ -2123,15 +2150,20 @@ begin end; // Menu "Analysis" > "Statistical Process Control" > "S Control Chart" -procedure TOS3MainFrm.MenuItem118Click(Sender: TObject); +procedure TOS3MainFrm.mnuAnalysisSPC_SChartClick(Sender: TObject); begin + if SChartForm = nil then + Application.CreateForm(TSChartForm, SChartForm); + SChartForm.ShowModal; + { if SigmaChartFrm = nil then Application.CreateForm(TSigmaChartFrm, SigmaChartFrm); SigmaChartFrm.ShowModal; + } end; // Menu "Analysis" > "Statistical Process Control" > "Defect (nonconformity) c Chart" -procedure TOS3MainFrm.MenuItem119Click(Sender: TObject); +procedure TOS3MainFrm.mnuAnalysisSPC_CChartClick(Sender: TObject); begin if CChartFrm = nil then Application.CreateForm(TCChartFrm, CChartFrm); @@ -2147,7 +2179,7 @@ begin end; // Menu "Analysis" > "Statistical Process Control" > "Defects per Unit u Chart" -procedure TOS3MainFrm.MenuItem120Click(Sender: TObject); +procedure TOS3MainFrm.mnuAnalysisSPC_UChartClick(Sender: TObject); begin if UChartFrm = nil then Application.CreateForm(TUChartFrm, UChartFrm);