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:
wp_xxyyzz
2020-10-01 14:06:47 +00:00
parent 8df06eb3c3
commit 349f9b039b
3 changed files with 396 additions and 384 deletions

View File

@ -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.
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.
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.

View File

@ -1,222 +1,189 @@
object GroupFreqForm: TGroupFreqForm
Left = 513
Height = 341
Top = 233
Width = 444
HelpType = htKeyword
HelpKeyword = 'html/GroupFrequencyHistograms.htm'
AutoSize = True
inherited GroupFreqForm: TGroupFreqForm
Height = 212
Caption = 'Group Frequency Analysis'
ClientHeight = 341
ClientWidth = 444
OnActivate = FormActivate
OnCreate = FormCreate
OnShow = ResetBtnClick
Position = poMainFormCenter
LCLVersion = '2.0.10.0'
object Label1: TLabel
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Memo1
AnchorSideTop.Side = asrBottom
Left = 8
ClientHeight = 212
inherited ParamsPanel: TPanel
Height = 196
ClientHeight = 196
inherited CloseBtn: TButton
Top = 171
end
inherited ComputeBtn: TButton
Top = 171
end
inherited ResetBtn: TButton
Top = 171
end
inherited HelpBtn: TButton
Tag = 162
Top = 171
end
inherited ButtonBevel: TBevel
Top = 155
end
object Label1: TLabel[5]
AnchorSideLeft.Control = ParamsPanel
AnchorSideTop.Control = ParamsPanel
Left = 0
Height = 15
Top = 84
Top = 0
Width = 100
BorderSpacing.Left = 8
BorderSpacing.Top = 16
Caption = 'Available Variables:'
ParentColor = False
end
object Label2: TLabel
AnchorSideLeft.Control = GrpInBtn
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
object VarList: TListBox[6]
AnchorSideLeft.Control = ParamsPanel
AnchorSideTop.Control = Label1
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = GrpInBtn
AnchorSideBottom.Control = Bevel1
Left = 8
Height = 191
Top = 101
Width = 181
AnchorSideBottom.Control = ButtonBevel
Left = 0
Height = 138
Top = 17
Width = 126
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 8
BorderSpacing.Top = 2
BorderSpacing.Right = 8
BorderSpacing.Right = 6
ItemHeight = 0
OnDblClick = VarListDblClick
OnSelectionChange = VarListSelectionChange
TabOrder = 0
TabOrder = 4
end
object GrpInBtn: TBitBtn
AnchorSideLeft.Control = PlotOptionsBox
object GrpInBtn: TBitBtn[7]
AnchorSideLeft.Control = ParamsPanel
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = VarList
Left = 197
Height = 28
Top = 101
Width = 28
Left = 132
Height = 26
Top = 17
Width = 26
Images = MainDataModule.ImageList
ImageIndex = 1
OnClick = GrpInBtnClick
Spacing = 0
TabOrder = 1
TabOrder = 5
end
object GrpOutBtn: TBitBtn
AnchorSideLeft.Control = GrpInBtn
object GrpOutBtn: TBitBtn[8]
AnchorSideLeft.Control = ParamsPanel
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = GrpInBtn
AnchorSideTop.Side = asrBottom
Left = 197
Height = 28
Top = 133
Width = 28
Left = 132
Height = 26
Top = 47
Width = 26
BorderSpacing.Top = 4
Images = MainDataModule.ImageList
ImageIndex = 0
OnClick = GrpOutBtnClick
Spacing = 0
TabOrder = 2
TabOrder = 6
end
object GrpVarEdit: TEdit
AnchorSideLeft.Control = Label2
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 = Owner
AnchorSideRight.Control = ParamsPanel
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = GrpOutBtn
AnchorSideBottom.Side = asrBottom
Left = 237
Left = 164
Height = 23
Top = 126
Width = 199
Top = 38
Width = 127
Anchors = [akLeft, akRight, akBottom]
BorderSpacing.Left = 6
BorderSpacing.Top = 2
BorderSpacing.Right = 8
BorderSpacing.Bottom = 12
ReadOnly = True
TabOrder = 3
TabOrder = 7
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
object PlotOptionsGroup: TGroupBox[11]
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
Left = 132
Height = 79
Top = 97
Width = 147
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
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 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
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 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
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 = '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
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
inherited ParamsSplitter: TSplitter
Height = 212
end
end

View File

@ -5,41 +5,44 @@ unit GroupFreqUnit;
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
StdCtrls, Buttons, ExtCtrls,
MainUnit, GraphLib, Globals, DataProcs;
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Buttons,
ExtCtrls, StdCtrls, LCLVersion,
TASources,
Globals, MainUnit, MainDM, BasicStatsChartFormUnit;
type
{ TGroupFreqForm }
TGroupFreqForm = class(TForm)
Bevel1: TBevel;
TGroupFreqForm = class(TBasicStatsChartForm)
ShowValuesChk: TCheckBox;
GrpInBtn: TBitBtn;
GrpOutBtn: TBitBtn;
ComputeBtn: TButton;
GrpVarEdit: TEdit;
HorBarsBtn: TSpeedButton;
Label1: TLabel;
Label2: TLabel;
Memo1: TLabel;
PlotOptionsBox: TRadioGroup;
ResetBtn: TButton;
CloseBtn: TButton;
PlotOptionsGroup: TGroupBox;
ThreeDChk: TCheckBox;
VarList: TListBox;
procedure CloseBtnClick(Sender: TObject);
procedure ComputeBtnClick(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormCreate(Sender: TObject);
VertBarsBtn: TSpeedButton;
procedure GrpInBtnClick(Sender: TObject);
procedure GrpOutBtnClick(Sender: TObject);
procedure ResetBtnClick(Sender: TObject);
procedure VarListDblClick(Sender: TObject);
procedure VarListSelectionChange(Sender: TObject; User: boolean);
private
{ private declarations }
FAutoSized: Boolean;
FLabelsSource: TListChartSource;
procedure UpdateBtnStates;
protected
procedure AdjustConstraints; override;
procedure Compute; override;
procedure Plot(XLabels: StrDyneVec; FreqValues: DblDyneVec; XTitle: String);
public
{ public declarations }
constructor Create(AOwner: TComponent); override;
procedure Reset; override;
end;
var
@ -47,22 +50,90 @@ var
implementation
{$R *.lfm}
uses
Math;
Math,
TAChartUtils, TACustomSeries, TASeries,
Utils, DataProcs, ChartFrameUnit;
{ TGroupFreqForm }
procedure TGroupFreqForm.ResetBtnClick(Sender: TObject);
var
i: integer;
constructor TGroupFreqForm.Create(AOwner: TComponent);
begin
VarList.Clear;
for i := 1 to NoVariables do
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
GrpVarEdit.Text := '';
UpdateBtnStates;
inherited;
FLabelsSource := TListChartSource.Create(self);
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);
var
index: integer;
@ -76,141 +147,6 @@ begin
UpdateBtnStates;
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);
begin
@ -222,20 +158,128 @@ begin
UpdateBtnStates;
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;
begin
GrpInBtn.Enabled := VarList.ItemIndex > -1;
GrpOutBtn.Enabled := (GrpVarEdit.Text <> '');
FChartFrame.UpdateBtnStates;
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);
begin
UpdateBtnStates;
end;
initialization
{$I groupfrequnit.lrs}
end.