You've already forked lazarus-ccr
LazStats: Refactor GroupFreqUnit (to inherit from TBasicStatsChartForm).
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7726 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -63,3 +63,4 @@ correlation, means, standard deviations and confidence interval for each correla
|
|||||||
159=Directions: Firs, click in the variable name that represents the sample lot numbers. Next, click on the variable that represents the measurement. Click on the sigma button to change the default and click on any of the optional check boxes and enter specifications desired. Click the Compute button to obtain the results.
|
159=Directions: Firs, click in the variable name that represents the sample lot numbers. Next, click on the variable that represents the measurement. Click on the sigma button to change the default and click on any of the optional check boxes and enter specifications desired. Click the Compute button to obtain the results.
|
||||||
160=Correspondence analysis is a method for examining the relationship between two sets of categorical variables much as in a Chi-Squared analysis of a two-way contingency table. In fact, a typical chi-squared analysis is completed as part of this procedure. In addition, visualization of the relationships among the columns or rows of the analysis is performed in a manner similar to factor analysis. The data analyzed in the visualization is the table of relative proportions, that is, the original frequency values divided by the sum of all frequencies. The relative proportions of the row sums and the column sums are termed the �masses� of the rows or columns. The method used to analyze the relative proportions involves what is now called the �Generalized Singular Value Decomposition� or more simply the generalized SVD. This method obtains roots and vectors of a rectangular matrix by decomposing that matrix into three portions: a matrix of left singular column vectors (A) that has n rows and q columns (n � q), a square diagonal matrix with q rows and columns of singular values (D), and a transposed matrix (B�) that is m x q in size of right generalized singular vectors (m = q-1). Completing this analysis involves several steps. The first is to obtain the (regular) SVD analysis of a matrix Q defined as Dr-1/2PDc -1/2 where Dr and Dc are diagonal matrices of row and column relative proportions and P is the matrix of relative proportions. The SVD of Q gives Q = U D V� where D is the desired diagonal matrix of eigenvalues and U�U = V�V = I. It should be noted that the first of the q roots is trivial and to be ignored. At this point we obtain A = Dr1/2U and B = Dc 1/2 V. The results of this SVD analysis is available on the output. Now P = ADB�. The row coordinates F and column coordinates G are then computed according to the table: Analysis Choice Button Selected Row Coordinates Column Coordinates Row Profile Row F = Dr-1AD G = Dc-1B Column Profile Column F = Dr-1A G = Dc-1BD Both Profiles Both F = Dr-1AD G = Dc-1BD If Row profiles are computed, the row coordinates are weighted centroids of the column coordinates and the inertias D2 refer only to the row points. If the column profiles are computed, the column coordinates are weighted eentroids of the row coordinates and the inertias D2 refer only to the column points. If both profiles are selected, neither row or column coordinates are weighted centroids of the other but the inertias D2 refer to both sets of points. The q-1 inertias are plotted in a manner similar to a scree plot of roots in a factor analysis. The total inertia is, in fact, the chi-squared statistic divided by the total of all cell frequencies. You may elect to plot the coordinates for any two pairs of coordinates. This will provide a graphical representation of the separation of the row or column categories similar to a plot of variables in a discriminant function analysis or factors in a factor analysis. A way of looking at correspondence analysis is to consider it as a method for decomposing the overall inertia by identifying a small number of dimensions in which the deviations from the expected values can be represented. This is similar to factor analysis where the total variance is decomposed so as to arrive at a lower dimensional representation of variables.
|
160=Correspondence analysis is a method for examining the relationship between two sets of categorical variables much as in a Chi-Squared analysis of a two-way contingency table. In fact, a typical chi-squared analysis is completed as part of this procedure. In addition, visualization of the relationships among the columns or rows of the analysis is performed in a manner similar to factor analysis. The data analyzed in the visualization is the table of relative proportions, that is, the original frequency values divided by the sum of all frequencies. The relative proportions of the row sums and the column sums are termed the �masses� of the rows or columns. The method used to analyze the relative proportions involves what is now called the �Generalized Singular Value Decomposition� or more simply the generalized SVD. This method obtains roots and vectors of a rectangular matrix by decomposing that matrix into three portions: a matrix of left singular column vectors (A) that has n rows and q columns (n � q), a square diagonal matrix with q rows and columns of singular values (D), and a transposed matrix (B�) that is m x q in size of right generalized singular vectors (m = q-1). Completing this analysis involves several steps. The first is to obtain the (regular) SVD analysis of a matrix Q defined as Dr-1/2PDc -1/2 where Dr and Dc are diagonal matrices of row and column relative proportions and P is the matrix of relative proportions. The SVD of Q gives Q = U D V� where D is the desired diagonal matrix of eigenvalues and U�U = V�V = I. It should be noted that the first of the q roots is trivial and to be ignored. At this point we obtain A = Dr1/2U and B = Dc 1/2 V. The results of this SVD analysis is available on the output. Now P = ADB�. The row coordinates F and column coordinates G are then computed according to the table: Analysis Choice Button Selected Row Coordinates Column Coordinates Row Profile Row F = Dr-1AD G = Dc-1B Column Profile Column F = Dr-1A G = Dc-1BD Both Profiles Both F = Dr-1AD G = Dc-1BD If Row profiles are computed, the row coordinates are weighted centroids of the column coordinates and the inertias D2 refer only to the row points. If the column profiles are computed, the column coordinates are weighted eentroids of the row coordinates and the inertias D2 refer only to the column points. If both profiles are selected, neither row or column coordinates are weighted centroids of the other but the inertias D2 refer to both sets of points. The q-1 inertias are plotted in a manner similar to a scree plot of roots in a factor analysis. The total inertia is, in fact, the chi-squared statistic divided by the total of all cell frequencies. You may elect to plot the coordinates for any two pairs of coordinates. This will provide a graphical representation of the separation of the row or column categories similar to a plot of variables in a discriminant function analysis or factors in a factor analysis. A way of looking at correspondence analysis is to consider it as a method for decomposing the overall inertia by identifying a small number of dimensions in which the deviations from the expected values can be represented. This is similar to factor analysis where the total variance is decomposed so as to arrive at a lower dimensional representation of variables.
|
||||||
161=Directions:\n(1) Select the X variable common to all of the Y variables to be selected.\n(2) Select the Y variables.\n(3) Enter a label for the plot.\n(4) Select the options desired.\n(5) Click the Compute button to obtain results.
|
161=Directions:\n(1) Select the X variable common to all of the Y variables to be selected.\n(2) Select the Y variables.\n(3) Enter a label for the plot.\n(4) Select the options desired.\n(5) Click the Compute button to obtain results.
|
||||||
|
162=This procedure plots the frequency of cases in each of the groups in a group variable. The group variable should be defined as an integer variable.\n\nSelect the variable and type of plot and click the Compute button for the results.
|
||||||
|
@ -1,222 +1,189 @@
|
|||||||
object GroupFreqForm: TGroupFreqForm
|
inherited GroupFreqForm: TGroupFreqForm
|
||||||
Left = 513
|
Height = 212
|
||||||
Height = 341
|
|
||||||
Top = 233
|
|
||||||
Width = 444
|
|
||||||
HelpType = htKeyword
|
|
||||||
HelpKeyword = 'html/GroupFrequencyHistograms.htm'
|
|
||||||
AutoSize = True
|
|
||||||
Caption = 'Group Frequency Analysis'
|
Caption = 'Group Frequency Analysis'
|
||||||
ClientHeight = 341
|
ClientHeight = 212
|
||||||
ClientWidth = 444
|
inherited ParamsPanel: TPanel
|
||||||
OnActivate = FormActivate
|
Height = 196
|
||||||
OnCreate = FormCreate
|
ClientHeight = 196
|
||||||
OnShow = ResetBtnClick
|
inherited CloseBtn: TButton
|
||||||
Position = poMainFormCenter
|
Top = 171
|
||||||
LCLVersion = '2.0.10.0'
|
end
|
||||||
object Label1: TLabel
|
inherited ComputeBtn: TButton
|
||||||
AnchorSideLeft.Control = Owner
|
Top = 171
|
||||||
AnchorSideTop.Control = Memo1
|
end
|
||||||
AnchorSideTop.Side = asrBottom
|
inherited ResetBtn: TButton
|
||||||
Left = 8
|
Top = 171
|
||||||
Height = 15
|
end
|
||||||
Top = 84
|
inherited HelpBtn: TButton
|
||||||
Width = 100
|
Tag = 162
|
||||||
BorderSpacing.Left = 8
|
Top = 171
|
||||||
BorderSpacing.Top = 16
|
end
|
||||||
Caption = 'Available Variables:'
|
inherited ButtonBevel: TBevel
|
||||||
ParentColor = False
|
Top = 155
|
||||||
|
end
|
||||||
|
object Label1: TLabel[5]
|
||||||
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideTop.Control = ParamsPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 15
|
||||||
|
Top = 0
|
||||||
|
Width = 100
|
||||||
|
Caption = 'Available Variables:'
|
||||||
|
ParentColor = False
|
||||||
|
end
|
||||||
|
object VarList: TListBox[6]
|
||||||
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideTop.Control = Label1
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
|
AnchorSideRight.Control = GrpInBtn
|
||||||
|
AnchorSideBottom.Control = ButtonBevel
|
||||||
|
Left = 0
|
||||||
|
Height = 138
|
||||||
|
Top = 17
|
||||||
|
Width = 126
|
||||||
|
Anchors = [akTop, akLeft, akRight, akBottom]
|
||||||
|
BorderSpacing.Top = 2
|
||||||
|
BorderSpacing.Right = 6
|
||||||
|
ItemHeight = 0
|
||||||
|
OnDblClick = VarListDblClick
|
||||||
|
OnSelectionChange = VarListSelectionChange
|
||||||
|
TabOrder = 4
|
||||||
|
end
|
||||||
|
object GrpInBtn: TBitBtn[7]
|
||||||
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideLeft.Side = asrCenter
|
||||||
|
AnchorSideTop.Control = VarList
|
||||||
|
Left = 132
|
||||||
|
Height = 26
|
||||||
|
Top = 17
|
||||||
|
Width = 26
|
||||||
|
Images = MainDataModule.ImageList
|
||||||
|
ImageIndex = 1
|
||||||
|
OnClick = GrpInBtnClick
|
||||||
|
Spacing = 0
|
||||||
|
TabOrder = 5
|
||||||
|
end
|
||||||
|
object GrpOutBtn: TBitBtn[8]
|
||||||
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideLeft.Side = asrCenter
|
||||||
|
AnchorSideTop.Control = GrpInBtn
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
|
Left = 132
|
||||||
|
Height = 26
|
||||||
|
Top = 47
|
||||||
|
Width = 26
|
||||||
|
BorderSpacing.Top = 4
|
||||||
|
Images = MainDataModule.ImageList
|
||||||
|
ImageIndex = 0
|
||||||
|
OnClick = GrpOutBtnClick
|
||||||
|
Spacing = 0
|
||||||
|
TabOrder = 6
|
||||||
|
end
|
||||||
|
object Label2: TLabel[9]
|
||||||
|
AnchorSideLeft.Control = GrpVarEdit
|
||||||
|
AnchorSideBottom.Control = GrpVarEdit
|
||||||
|
Left = 164
|
||||||
|
Height = 15
|
||||||
|
Top = 21
|
||||||
|
Width = 77
|
||||||
|
Anchors = [akLeft, akBottom]
|
||||||
|
BorderSpacing.Bottom = 2
|
||||||
|
Caption = 'Group Variable'
|
||||||
|
ParentColor = False
|
||||||
|
end
|
||||||
|
object GrpVarEdit: TEdit[10]
|
||||||
|
AnchorSideLeft.Control = GrpInBtn
|
||||||
|
AnchorSideLeft.Side = asrBottom
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
|
AnchorSideRight.Control = ParamsPanel
|
||||||
|
AnchorSideRight.Side = asrBottom
|
||||||
|
AnchorSideBottom.Control = GrpOutBtn
|
||||||
|
AnchorSideBottom.Side = asrBottom
|
||||||
|
Left = 164
|
||||||
|
Height = 23
|
||||||
|
Top = 38
|
||||||
|
Width = 127
|
||||||
|
Anchors = [akLeft, akRight, akBottom]
|
||||||
|
BorderSpacing.Left = 6
|
||||||
|
BorderSpacing.Top = 2
|
||||||
|
BorderSpacing.Bottom = 12
|
||||||
|
ReadOnly = True
|
||||||
|
TabOrder = 7
|
||||||
|
Text = 'GrpVarEdit'
|
||||||
|
end
|
||||||
|
object PlotOptionsGroup: TGroupBox[11]
|
||||||
|
AnchorSideLeft.Control = GrpInBtn
|
||||||
|
AnchorSideTop.Control = GrpOutBtn
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
|
Left = 132
|
||||||
|
Height = 79
|
||||||
|
Top = 97
|
||||||
|
Width = 147
|
||||||
|
AutoSize = True
|
||||||
|
BorderSpacing.Top = 24
|
||||||
|
Caption = 'Plot Options'
|
||||||
|
ClientHeight = 59
|
||||||
|
ClientWidth = 143
|
||||||
|
TabOrder = 8
|
||||||
|
object VertBarsBtn: TSpeedButton
|
||||||
|
AnchorSideLeft.Control = PlotOptionsGroup
|
||||||
|
AnchorSideTop.Control = PlotOptionsGroup
|
||||||
|
Left = 12
|
||||||
|
Height = 22
|
||||||
|
Top = 4
|
||||||
|
Width = 23
|
||||||
|
BorderSpacing.Left = 12
|
||||||
|
BorderSpacing.Top = 4
|
||||||
|
BorderSpacing.Bottom = 6
|
||||||
|
Down = True
|
||||||
|
GroupIndex = 1
|
||||||
|
Images = MainDataModule.ImageList
|
||||||
|
ImageIndex = 8
|
||||||
|
end
|
||||||
|
object HorBarsBtn: TSpeedButton
|
||||||
|
AnchorSideLeft.Control = VertBarsBtn
|
||||||
|
AnchorSideLeft.Side = asrBottom
|
||||||
|
AnchorSideTop.Control = PlotOptionsGroup
|
||||||
|
Left = 39
|
||||||
|
Height = 22
|
||||||
|
Top = 4
|
||||||
|
Width = 23
|
||||||
|
BorderSpacing.Left = 4
|
||||||
|
BorderSpacing.Top = 4
|
||||||
|
GroupIndex = 1
|
||||||
|
Images = MainDataModule.ImageList
|
||||||
|
ImageIndex = 9
|
||||||
|
end
|
||||||
|
object ThreeDChk: TCheckBox
|
||||||
|
AnchorSideLeft.Control = HorBarsBtn
|
||||||
|
AnchorSideLeft.Side = asrBottom
|
||||||
|
AnchorSideTop.Control = VertBarsBtn
|
||||||
|
AnchorSideTop.Side = asrCenter
|
||||||
|
Left = 94
|
||||||
|
Height = 19
|
||||||
|
Top = 6
|
||||||
|
Width = 34
|
||||||
|
BorderSpacing.Left = 32
|
||||||
|
BorderSpacing.Right = 8
|
||||||
|
Caption = '3D'
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object ShowValuesChk: TCheckBox
|
||||||
|
AnchorSideLeft.Control = VertBarsBtn
|
||||||
|
AnchorSideTop.Control = VertBarsBtn
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
|
Left = 12
|
||||||
|
Height = 19
|
||||||
|
Top = 32
|
||||||
|
Width = 123
|
||||||
|
BorderSpacing.Right = 8
|
||||||
|
BorderSpacing.Bottom = 8
|
||||||
|
Caption = 'Show values at bars'
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
object Label2: TLabel
|
inherited ParamsSplitter: TSplitter
|
||||||
AnchorSideLeft.Control = GrpInBtn
|
Height = 212
|
||||||
AnchorSideLeft.Side = asrBottom
|
|
||||||
AnchorSideBottom.Control = GrpVarEdit
|
|
||||||
Left = 237
|
|
||||||
Height = 15
|
|
||||||
Top = 109
|
|
||||||
Width = 77
|
|
||||||
Anchors = [akLeft, akBottom]
|
|
||||||
BorderSpacing.Left = 12
|
|
||||||
BorderSpacing.Bottom = 2
|
|
||||||
Caption = 'Group Variable'
|
|
||||||
ParentColor = False
|
|
||||||
end
|
|
||||||
object VarList: TListBox
|
|
||||||
AnchorSideLeft.Control = Owner
|
|
||||||
AnchorSideTop.Control = Label1
|
|
||||||
AnchorSideTop.Side = asrBottom
|
|
||||||
AnchorSideRight.Control = GrpInBtn
|
|
||||||
AnchorSideBottom.Control = Bevel1
|
|
||||||
Left = 8
|
|
||||||
Height = 191
|
|
||||||
Top = 101
|
|
||||||
Width = 181
|
|
||||||
Anchors = [akTop, akLeft, akRight, akBottom]
|
|
||||||
BorderSpacing.Left = 8
|
|
||||||
BorderSpacing.Top = 2
|
|
||||||
BorderSpacing.Right = 8
|
|
||||||
ItemHeight = 0
|
|
||||||
OnSelectionChange = VarListSelectionChange
|
|
||||||
TabOrder = 0
|
|
||||||
end
|
|
||||||
object GrpInBtn: TBitBtn
|
|
||||||
AnchorSideLeft.Control = PlotOptionsBox
|
|
||||||
AnchorSideTop.Control = VarList
|
|
||||||
Left = 197
|
|
||||||
Height = 28
|
|
||||||
Top = 101
|
|
||||||
Width = 28
|
|
||||||
Images = MainDataModule.ImageList
|
|
||||||
ImageIndex = 1
|
|
||||||
OnClick = GrpInBtnClick
|
|
||||||
Spacing = 0
|
|
||||||
TabOrder = 1
|
|
||||||
end
|
|
||||||
object GrpOutBtn: TBitBtn
|
|
||||||
AnchorSideLeft.Control = GrpInBtn
|
|
||||||
AnchorSideTop.Control = GrpInBtn
|
|
||||||
AnchorSideTop.Side = asrBottom
|
|
||||||
Left = 197
|
|
||||||
Height = 28
|
|
||||||
Top = 133
|
|
||||||
Width = 28
|
|
||||||
BorderSpacing.Top = 4
|
|
||||||
Images = MainDataModule.ImageList
|
|
||||||
ImageIndex = 0
|
|
||||||
OnClick = GrpOutBtnClick
|
|
||||||
Spacing = 0
|
|
||||||
TabOrder = 2
|
|
||||||
end
|
|
||||||
object GrpVarEdit: TEdit
|
|
||||||
AnchorSideLeft.Control = Label2
|
|
||||||
AnchorSideTop.Side = asrBottom
|
|
||||||
AnchorSideRight.Control = Owner
|
|
||||||
AnchorSideRight.Side = asrBottom
|
|
||||||
AnchorSideBottom.Control = GrpOutBtn
|
|
||||||
AnchorSideBottom.Side = asrBottom
|
|
||||||
Left = 237
|
|
||||||
Height = 23
|
|
||||||
Top = 126
|
|
||||||
Width = 199
|
|
||||||
Anchors = [akLeft, akRight, akBottom]
|
|
||||||
BorderSpacing.Top = 2
|
|
||||||
BorderSpacing.Right = 8
|
|
||||||
BorderSpacing.Bottom = 12
|
|
||||||
ReadOnly = True
|
|
||||||
TabOrder = 3
|
|
||||||
Text = 'GrpVarEdit'
|
|
||||||
end
|
|
||||||
object ResetBtn: TButton
|
|
||||||
AnchorSideTop.Control = CloseBtn
|
|
||||||
AnchorSideRight.Control = ComputeBtn
|
|
||||||
Left = 235
|
|
||||||
Height = 25
|
|
||||||
Top = 308
|
|
||||||
Width = 54
|
|
||||||
Anchors = [akTop, akRight]
|
|
||||||
AutoSize = True
|
|
||||||
BorderSpacing.Right = 8
|
|
||||||
BorderSpacing.Bottom = 8
|
|
||||||
Caption = 'Reset'
|
|
||||||
OnClick = ResetBtnClick
|
|
||||||
TabOrder = 5
|
|
||||||
end
|
|
||||||
object ComputeBtn: TButton
|
|
||||||
AnchorSideTop.Control = CloseBtn
|
|
||||||
AnchorSideRight.Control = CloseBtn
|
|
||||||
Left = 297
|
|
||||||
Height = 25
|
|
||||||
Top = 308
|
|
||||||
Width = 76
|
|
||||||
Anchors = [akTop, akRight]
|
|
||||||
AutoSize = True
|
|
||||||
BorderSpacing.Right = 8
|
|
||||||
BorderSpacing.Bottom = 8
|
|
||||||
Caption = 'Compute'
|
|
||||||
OnClick = ComputeBtnClick
|
|
||||||
TabOrder = 6
|
|
||||||
end
|
|
||||||
object CloseBtn: TButton
|
|
||||||
AnchorSideRight.Control = Owner
|
|
||||||
AnchorSideRight.Side = asrBottom
|
|
||||||
AnchorSideBottom.Control = Owner
|
|
||||||
AnchorSideBottom.Side = asrBottom
|
|
||||||
Left = 381
|
|
||||||
Height = 25
|
|
||||||
Top = 308
|
|
||||||
Width = 55
|
|
||||||
Anchors = [akRight, akBottom]
|
|
||||||
AutoSize = True
|
|
||||||
BorderSpacing.Top = 8
|
|
||||||
BorderSpacing.Right = 8
|
|
||||||
BorderSpacing.Bottom = 8
|
|
||||||
Caption = 'Close'
|
|
||||||
ModalResult = 11
|
|
||||||
OnClick = CloseBtnClick
|
|
||||||
TabOrder = 7
|
|
||||||
end
|
|
||||||
object PlotOptionsBox: TRadioGroup
|
|
||||||
AnchorSideLeft.Control = GrpInBtn
|
|
||||||
AnchorSideTop.Control = GrpOutBtn
|
|
||||||
AnchorSideTop.Side = asrBottom
|
|
||||||
AnchorSideRight.Control = Owner
|
|
||||||
AnchorSideRight.Side = asrBottom
|
|
||||||
Left = 197
|
|
||||||
Height = 114
|
|
||||||
Top = 177
|
|
||||||
Width = 239
|
|
||||||
Anchors = [akTop, akRight]
|
|
||||||
AutoFill = True
|
|
||||||
AutoSize = True
|
|
||||||
BorderSpacing.Top = 16
|
|
||||||
BorderSpacing.Right = 8
|
|
||||||
Caption = 'Plot Options:'
|
|
||||||
ChildSizing.LeftRightSpacing = 12
|
|
||||||
ChildSizing.TopBottomSpacing = 6
|
|
||||||
ChildSizing.VerticalSpacing = 2
|
|
||||||
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
|
|
||||||
ChildSizing.EnlargeVertical = crsHomogenousChildResize
|
|
||||||
ChildSizing.ShrinkHorizontal = crsScaleChilds
|
|
||||||
ChildSizing.ShrinkVertical = crsScaleChilds
|
|
||||||
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
|
||||||
ChildSizing.ControlsPerLine = 1
|
|
||||||
ClientHeight = 94
|
|
||||||
ClientWidth = 235
|
|
||||||
Items.Strings = (
|
|
||||||
'Plot means using 2D Horizontal Bars'
|
|
||||||
'Plot means using 3D Horizontal Bars'
|
|
||||||
'Plot means using 2D Vertical Bars'
|
|
||||||
'Plot means using 3D Vertical Bars'
|
|
||||||
)
|
|
||||||
TabOrder = 4
|
|
||||||
end
|
|
||||||
object Bevel1: TBevel
|
|
||||||
AnchorSideLeft.Control = Owner
|
|
||||||
AnchorSideRight.Control = Owner
|
|
||||||
AnchorSideRight.Side = asrBottom
|
|
||||||
AnchorSideBottom.Control = CloseBtn
|
|
||||||
Left = 0
|
|
||||||
Height = 8
|
|
||||||
Top = 292
|
|
||||||
Width = 444
|
|
||||||
Anchors = [akLeft, akRight, akBottom]
|
|
||||||
Shape = bsBottomLine
|
|
||||||
end
|
|
||||||
object Memo1: TLabel
|
|
||||||
AnchorSideLeft.Control = Owner
|
|
||||||
AnchorSideTop.Control = Owner
|
|
||||||
AnchorSideRight.Control = Owner
|
|
||||||
AnchorSideRight.Side = asrBottom
|
|
||||||
Left = 8
|
|
||||||
Height = 60
|
|
||||||
Top = 8
|
|
||||||
Width = 428
|
|
||||||
Anchors = [akTop, akLeft, akRight]
|
|
||||||
BorderSpacing.Left = 8
|
|
||||||
BorderSpacing.Top = 8
|
|
||||||
BorderSpacing.Right = 8
|
|
||||||
Caption = 'This procedure plots the frequency of cases in each of the groups in a group variable. The group variable should be defined as an integer variable.'#13#10#13#10'Select the variable and type of plot and click the Compute button for the results.'
|
|
||||||
ParentColor = False
|
|
||||||
WordWrap = True
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -5,41 +5,44 @@ unit GroupFreqUnit;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
|
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Buttons,
|
||||||
StdCtrls, Buttons, ExtCtrls,
|
ExtCtrls, StdCtrls, LCLVersion,
|
||||||
MainUnit, GraphLib, Globals, DataProcs;
|
TASources,
|
||||||
|
Globals, MainUnit, MainDM, BasicStatsChartFormUnit;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
{ TGroupFreqForm }
|
{ TGroupFreqForm }
|
||||||
|
|
||||||
TGroupFreqForm = class(TForm)
|
TGroupFreqForm = class(TBasicStatsChartForm)
|
||||||
Bevel1: TBevel;
|
ShowValuesChk: TCheckBox;
|
||||||
GrpInBtn: TBitBtn;
|
GrpInBtn: TBitBtn;
|
||||||
GrpOutBtn: TBitBtn;
|
GrpOutBtn: TBitBtn;
|
||||||
ComputeBtn: TButton;
|
|
||||||
GrpVarEdit: TEdit;
|
GrpVarEdit: TEdit;
|
||||||
|
HorBarsBtn: TSpeedButton;
|
||||||
Label1: TLabel;
|
Label1: TLabel;
|
||||||
Label2: TLabel;
|
Label2: TLabel;
|
||||||
Memo1: TLabel;
|
PlotOptionsGroup: TGroupBox;
|
||||||
PlotOptionsBox: TRadioGroup;
|
ThreeDChk: TCheckBox;
|
||||||
ResetBtn: TButton;
|
|
||||||
CloseBtn: TButton;
|
|
||||||
VarList: TListBox;
|
VarList: TListBox;
|
||||||
procedure CloseBtnClick(Sender: TObject);
|
VertBarsBtn: TSpeedButton;
|
||||||
procedure ComputeBtnClick(Sender: TObject);
|
|
||||||
procedure FormActivate(Sender: TObject);
|
|
||||||
procedure FormCreate(Sender: TObject);
|
|
||||||
procedure GrpInBtnClick(Sender: TObject);
|
procedure GrpInBtnClick(Sender: TObject);
|
||||||
procedure GrpOutBtnClick(Sender: TObject);
|
procedure GrpOutBtnClick(Sender: TObject);
|
||||||
procedure ResetBtnClick(Sender: TObject);
|
procedure VarListDblClick(Sender: TObject);
|
||||||
procedure VarListSelectionChange(Sender: TObject; User: boolean);
|
procedure VarListSelectionChange(Sender: TObject; User: boolean);
|
||||||
private
|
private
|
||||||
{ private declarations }
|
FLabelsSource: TListChartSource;
|
||||||
FAutoSized: Boolean;
|
|
||||||
procedure UpdateBtnStates;
|
procedure UpdateBtnStates;
|
||||||
|
|
||||||
|
protected
|
||||||
|
procedure AdjustConstraints; override;
|
||||||
|
procedure Compute; override;
|
||||||
|
procedure Plot(XLabels: StrDyneVec; FreqValues: DblDyneVec; XTitle: String);
|
||||||
|
|
||||||
public
|
public
|
||||||
{ public declarations }
|
constructor Create(AOwner: TComponent); override;
|
||||||
|
procedure Reset; override;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
@ -47,22 +50,90 @@ var
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
{$R *.lfm}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Math;
|
Math,
|
||||||
|
TAChartUtils, TACustomSeries, TASeries,
|
||||||
|
Utils, DataProcs, ChartFrameUnit;
|
||||||
|
|
||||||
|
|
||||||
{ TGroupFreqForm }
|
{ TGroupFreqForm }
|
||||||
|
|
||||||
procedure TGroupFreqForm.ResetBtnClick(Sender: TObject);
|
constructor TGroupFreqForm.Create(AOwner: TComponent);
|
||||||
var
|
|
||||||
i: integer;
|
|
||||||
begin
|
begin
|
||||||
VarList.Clear;
|
inherited;
|
||||||
for i := 1 to NoVariables do
|
FLabelsSource := TListChartSource.Create(self);
|
||||||
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
|
|
||||||
GrpVarEdit.Text := '';
|
|
||||||
UpdateBtnStates;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGroupFreqForm.AdjustConstraints;
|
||||||
|
begin
|
||||||
|
ParamsPanel.Constraints.MinWidth := MaxValue( [
|
||||||
|
4*CloseBtn.Width + 3*CloseBtn.BorderSpacing.Left,
|
||||||
|
(PlotOptionsGroup.Width - GrpInBtn.Width div 2 + GrpVarEdit.BorderSpacing.Left)*2,
|
||||||
|
(Max(Label1.Width, Label2.Width) + GrpvarEdit.BorderSpacing.Left) * 2
|
||||||
|
]);
|
||||||
|
ParamsPanel.Constraints.MinHeight := PlotOptionsGroup.Top + PlotOptionsGroup.Height +
|
||||||
|
ButtonBevel.Height + CloseBtn.BorderSpacing.Top + CloseBtn.Height;
|
||||||
|
|
||||||
|
Constraints.MinWidth := ParamsPanel.Constraints.MinWidth + 300;
|
||||||
|
Constraints.MinHeight := ParamsPanel.Constraints.MinHeight + ParamsPanel.BorderSpacing.Top * 2;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGroupFreqForm.Compute;
|
||||||
|
VAR
|
||||||
|
nogroups, mingrp, maxgrp, grpcol, minfreq, maxfreq: integer;
|
||||||
|
cellStr: string;
|
||||||
|
i, numValues, valueIdx: integer;
|
||||||
|
freq: DblDyneVec = nil; // Could be IntDyneVec, but easier plotting with Dbl
|
||||||
|
values: StrDyneVec = nil;
|
||||||
|
begin
|
||||||
|
// get the variable to analyze
|
||||||
|
grpcol := 0;
|
||||||
|
for i := 1 to NoVariables do
|
||||||
|
if GrpVarEdit.Text = OS3MainFrm.DataGrid.Cells[i,0] then
|
||||||
|
begin
|
||||||
|
grpcol := i;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
if grpcol = 0 then
|
||||||
|
begin
|
||||||
|
MessageDlg('No variable selected.', mtError, [mbOK], 0);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
SetLength(values, NoCases); // over-dimension values array; will be trimmed.
|
||||||
|
numvalues := 0;
|
||||||
|
for i := 1 to NoCases do
|
||||||
|
begin
|
||||||
|
cellStr := Trim(OS3MainFrm.DataGrid.Cells[grpcol,i]);
|
||||||
|
if IndexOfString(values, cellStr) = -1 then begin
|
||||||
|
values[numValues] := cellStr;
|
||||||
|
inc(numvalues);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
SetLength(values, numValues); // Trim values array to correct length
|
||||||
|
|
||||||
|
// setup frequency array and count cases in each group
|
||||||
|
SetLength(freq, numvalues);
|
||||||
|
for i := 1 to NoCases do
|
||||||
|
begin
|
||||||
|
if not ValidValue(i, grpcol) then continue;
|
||||||
|
cellStr := Trim(OS3MainFrm.DataGrid.Cells[grpcol, i]);
|
||||||
|
valueIdx := IndexOfString(values, cellStr);
|
||||||
|
if valueIdx > -1 then
|
||||||
|
freq[valueIdx] := freq[valueIdx] + 1
|
||||||
|
else
|
||||||
|
raise Exception.Create('Value index not found.'); // this should not happen
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Plot frequency data
|
||||||
|
Plot(values, freq, GrpVarEdit.Text);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TGroupFreqForm.GrpInBtnClick(Sender: TObject);
|
procedure TGroupFreqForm.GrpInBtnClick(Sender: TObject);
|
||||||
var
|
var
|
||||||
index: integer;
|
index: integer;
|
||||||
@ -76,141 +147,6 @@ begin
|
|||||||
UpdateBtnStates;
|
UpdateBtnStates;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TGroupFreqForm.ComputeBtnClick(Sender: TObject);
|
|
||||||
VAR
|
|
||||||
nogroups, mingrp, maxgrp, grpcol, value, minfreq, maxfreq: integer;
|
|
||||||
labelstr: string;
|
|
||||||
i: integer;
|
|
||||||
strvalue: string;
|
|
||||||
freq: IntDyneVec;
|
|
||||||
plottype: integer;
|
|
||||||
begin
|
|
||||||
// get the variable to analyze
|
|
||||||
grpcol := 0;
|
|
||||||
for i := 1 to NoVariables do
|
|
||||||
begin
|
|
||||||
strvalue := OS3MainFrm.DataGrid.Cells[i,0];
|
|
||||||
if GrpVarEdit.Text = strvalue then
|
|
||||||
begin
|
|
||||||
grpcol := i;
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
if grpcol = 0 then
|
|
||||||
begin
|
|
||||||
MessageDlg('No variable selected.', mtError, [mbOK], 0);
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
labelstr := GrpVarEdit.Text;
|
|
||||||
mingrp := 1000;
|
|
||||||
maxgrp := -1000;
|
|
||||||
for i := 1 to NoCases do
|
|
||||||
begin
|
|
||||||
if not ValidValue(i,grpcol) then continue;
|
|
||||||
value := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[grpcol,i])));
|
|
||||||
if value < mingrp then mingrp := value;
|
|
||||||
if value > maxgrp then maxgrp := value;
|
|
||||||
end;
|
|
||||||
nogroups := maxgrp - mingrp + 1;
|
|
||||||
if nogroups < 2 then
|
|
||||||
begin
|
|
||||||
MessageDlg('One or fewer groups found.', mtError, [mbOK], 0);
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// setup frequency array and count cases in each group
|
|
||||||
SetLength(freq,NoGroups+1);
|
|
||||||
for i := 0 to NoGroups do
|
|
||||||
freq[i] := 0;
|
|
||||||
for i := 1 to NoCases do
|
|
||||||
begin
|
|
||||||
if not ValidValue(i,grpcol) then continue;
|
|
||||||
value := round(StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[grpcol,i])));
|
|
||||||
value := value - mingrp;
|
|
||||||
freq[value] := freq[value] + 1;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// get min and max frequencies and check for existence of a range
|
|
||||||
minfreq := 10000;
|
|
||||||
maxfreq := -10000;
|
|
||||||
for i := 0 to NoGroups-1 do
|
|
||||||
begin
|
|
||||||
if freq[i] < minfreq then minfreq := freq[i];
|
|
||||||
if freq[i] > maxfreq then maxfreq := freq[i];
|
|
||||||
end;
|
|
||||||
if minfreq = maxfreq then
|
|
||||||
begin
|
|
||||||
MessageDlg('All groups have equal frequencies. Cannot plot.', mtInformation, [mbOK], 0);
|
|
||||||
freq := nil;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
case PlotOptionsBox.ItemIndex of
|
|
||||||
0: plottype := 9;
|
|
||||||
1: plottype := 10;
|
|
||||||
2: plottype := 1;
|
|
||||||
3: plottype := 2;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// plot the frequencies
|
|
||||||
SetLength(GraphFrm.Xpoints,1,nogroups+1);
|
|
||||||
SetLength(GraphFrm.Ypoints,1,nogroups+1);
|
|
||||||
GraphFrm.nosets := 1;
|
|
||||||
GraphFrm.nbars := nogroups;
|
|
||||||
GraphFrm.Heading := 'Frequency Distribution';
|
|
||||||
GraphFrm.XTitle := 'Values of ' + labelstr;
|
|
||||||
GraphFrm.YTitle := 'Frequency';
|
|
||||||
GraphFrm.barwideprop := 0.5;
|
|
||||||
GraphFrm.AutoScaled := false;
|
|
||||||
GraphFrm.miny := 0.0;
|
|
||||||
GraphFrm.maxy := maxfreq;
|
|
||||||
GraphFrm.GraphType := plottype;
|
|
||||||
GraphFrm.BackColor := clCream; // clYellow;
|
|
||||||
GraphFrm.WallColor := clDkGray; //Black;
|
|
||||||
GraphFrm.FloorColor := clLtGray;
|
|
||||||
GraphFrm.ShowBackWall := true;
|
|
||||||
for i := 0 to nogroups do
|
|
||||||
begin
|
|
||||||
GraphFrm.Ypoints[0,i] := freq[i];
|
|
||||||
GraphFrm.Xpoints[0,i] := mingrp + i;
|
|
||||||
end;
|
|
||||||
GraphFrm.ShowModal;
|
|
||||||
GraphFrm.Xpoints := nil;
|
|
||||||
GraphFrm.Ypoints := nil;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGroupFreqForm.CloseBtnClick(Sender: TObject);
|
|
||||||
begin
|
|
||||||
Close;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGroupFreqForm.FormActivate(Sender: TObject);
|
|
||||||
var
|
|
||||||
w: Integer;
|
|
||||||
begin
|
|
||||||
if FAutoSized then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
w := MaxValue([ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]);
|
|
||||||
ResetBtn.Constraints.MinWidth := w;
|
|
||||||
ComputeBtn.Constraints.MinWidth := w;
|
|
||||||
CloseBtn.Constraints.MinWidth := w;
|
|
||||||
|
|
||||||
VarList.Constraints.MinHeight := PlotOptionsBox.Top + PlotOptionsBox.Height - VarList.Top;
|
|
||||||
Varlist.Constraints.MinWidth := Label1.Width * 3 div 2;
|
|
||||||
|
|
||||||
Constraints.MinWidth := Width;
|
|
||||||
Constraints.MinHeight := Height;
|
|
||||||
|
|
||||||
FAutoSized := true;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGroupFreqForm.FormCreate(Sender: TObject);
|
|
||||||
begin
|
|
||||||
Assert(OS3MainFrm <> nil);
|
|
||||||
if GraphFrm = nil then Application.CreateForm(TGraphFrm, GraphFrm);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGroupFreqForm.GrpOutBtnClick(Sender: TObject);
|
procedure TGroupFreqForm.GrpOutBtnClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
@ -222,20 +158,128 @@ begin
|
|||||||
UpdateBtnStates;
|
UpdateBtnStates;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGroupFreqForm.Plot(XLabels: StrDyneVec; FreqValues: DblDyneVec; XTitle: String);
|
||||||
|
const
|
||||||
|
MARGIN: array[boolean] of Integer = (4, 0);
|
||||||
|
var
|
||||||
|
ser: TBarSeries;
|
||||||
|
YTitle: String;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
// Erase the chart, if it has already been used.
|
||||||
|
FChartFrame.Clear;
|
||||||
|
FLabelsSource.Clear;
|
||||||
|
|
||||||
|
// Copy XLabels to LabelsSource
|
||||||
|
for i := 0 to High(XLabels) do
|
||||||
|
FLabelsSource.Add(i+1, i+1, XLabels[i]);
|
||||||
|
|
||||||
|
// Define captions -- will be applied later
|
||||||
|
XTitle := 'Values of ' + XTitle;
|
||||||
|
YTitle := 'Frequency';
|
||||||
|
|
||||||
|
// Plot the frequencies
|
||||||
|
ser := TBarSeries(FChartFrame.PlotXY(ptBars, nil, FreqValues, XLabels, nil, '', DATA_COLORS[0]));
|
||||||
|
if ThreeDChk.Checked then
|
||||||
|
begin
|
||||||
|
ser.Depth := 20;
|
||||||
|
{$IF LCL_FullVersion >= 2010000}
|
||||||
|
ser.DepthBrightnessDelta := -30;
|
||||||
|
{$IFEND}
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Show/Hide series labels
|
||||||
|
if ShowValuesChk.Checked then
|
||||||
|
begin
|
||||||
|
ser.Marks.Style := smsValue;
|
||||||
|
ser.Marks.Distance := 0;
|
||||||
|
ser.MarkPositionCentered := true;
|
||||||
|
end else
|
||||||
|
ser.Marks.Style := smsNone;
|
||||||
|
ser.Marks.LinkPen.Color := clGray;
|
||||||
|
|
||||||
|
// Hide legend
|
||||||
|
FChartFrame.Chart.Legend.Visible := false;
|
||||||
|
|
||||||
|
// Show XLabels along the x axis
|
||||||
|
if HorBarsBtn.Down then
|
||||||
|
begin
|
||||||
|
// Rotate bars to be horizontal
|
||||||
|
ser.AxisIndexX := 0;
|
||||||
|
ser.AxisIndexY := 1;
|
||||||
|
FChartFrame.SetXTitle(YTitle);
|
||||||
|
FChartFrame.SetYTitle(XTitle);
|
||||||
|
FChartFrame.Chart.Margins.Bottom := 4;
|
||||||
|
FChartFrame.Chart.BottomAxis.Marks.Source := nil;
|
||||||
|
FChartFrame.Chart.BottomAxis.Marks.Style := smsValue;
|
||||||
|
FChartFrame.Chart.BottomAxis.Marks.Alignment := taCenter;
|
||||||
|
FChartFrame.Chart.Margins.Left := MARGIN[HorBarsBtn.Down];
|
||||||
|
FChartFrame.Chart.LeftAxis.Marks.Source := FLabelsSource;
|
||||||
|
FChartFrame.Chart.LeftAxis.Marks.Style := smsLabel;
|
||||||
|
FChartFrame.Chart.LeftAxis.Marks.Alignment := taCenter;
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
ser.AxisIndexX := 1;
|
||||||
|
ser.AxisIndexY := 0;
|
||||||
|
FChartFrame.SetXTitle(XTitle);
|
||||||
|
FChartFrame.SetYTitle(YTitle);
|
||||||
|
FChartFrame.Chart.Margins.Bottom := MARGIN[HorBarsBtn.Down];
|
||||||
|
FChartFrame.Chart.BottomAxis.Marks.Source := FLabelsSource;
|
||||||
|
FChartFrame.Chart.BottomAxis.Marks.Style := smsLabel;
|
||||||
|
FChartFrame.Chart.BottomAxis.Marks.Alignment := taCenter;
|
||||||
|
FChartFrame.Chart.Margins.Left := 4;
|
||||||
|
FChartFrame.Chart.LeftAxis.Marks.Source := nil;
|
||||||
|
FChartFrame.Chart.LeftAxis.Marks.Style := smsValue;
|
||||||
|
FChartFrame.Chart.LeftAxis.Marks.Alignment := taCenter;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Set Chart title
|
||||||
|
FChartFrame.SetTitle('Frequency Distribution');
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGroupFreqForm.Reset;
|
||||||
|
var
|
||||||
|
i: integer;
|
||||||
|
begin
|
||||||
|
VarList.Clear;
|
||||||
|
for i := 1 to NoVariables do
|
||||||
|
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
|
||||||
|
GrpVarEdit.Text := '';
|
||||||
|
UpdateBtnStates;
|
||||||
|
|
||||||
|
FChartFrame.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TGroupFreqForm.UpdateBtnStates;
|
procedure TGroupFreqForm.UpdateBtnStates;
|
||||||
begin
|
begin
|
||||||
GrpInBtn.Enabled := VarList.ItemIndex > -1;
|
GrpInBtn.Enabled := VarList.ItemIndex > -1;
|
||||||
GrpOutBtn.Enabled := (GrpVarEdit.Text <> '');
|
GrpOutBtn.Enabled := (GrpVarEdit.Text <> '');
|
||||||
|
FChartFrame.UpdateBtnStates;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGroupFreqForm.VarListDblClick(Sender: TObject);
|
||||||
|
var
|
||||||
|
index: Integer;
|
||||||
|
begin
|
||||||
|
index := VarList.ItemIndex;
|
||||||
|
if (index > -1) and (GrpVarEdit.Text = '') then
|
||||||
|
begin
|
||||||
|
GrpVarEdit.Text := VarList.Items[index];
|
||||||
|
Varlist.Items.Delete(index);
|
||||||
|
UpdateBtnStates;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TGroupFreqForm.VarListSelectionChange(Sender: TObject; User: boolean);
|
procedure TGroupFreqForm.VarListSelectionChange(Sender: TObject; User: boolean);
|
||||||
begin
|
begin
|
||||||
UpdateBtnStates;
|
UpdateBtnStates;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
initialization
|
|
||||||
{$I groupfrequnit.lrs}
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user