2020-03-30 18:01:44 +00:00
|
|
|
// Use file "cansas.laz" for testing
|
|
|
|
|
|
|
|
unit PlotXYUnit;
|
|
|
|
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2020-08-22 22:23:20 +00:00
|
|
|
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
|
2020-09-20 21:49:11 +00:00
|
|
|
StdCtrls, ExtCtrls, Buttons, ComCtrls,
|
|
|
|
MainUnit, Globals, FunctionsLib, DataProcs, ReportFrameUnit, ChartFrameUnit;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
|
|
|
type
|
|
|
|
|
|
|
|
{ TPlotXYFrm }
|
|
|
|
|
|
|
|
TPlotXYFrm = class(TForm)
|
|
|
|
Bevel1: TBevel;
|
|
|
|
ConfEdit: TEdit;
|
|
|
|
Label4: TLabel;
|
2020-09-20 21:49:11 +00:00
|
|
|
PageControl1: TPageControl;
|
|
|
|
ParamsPanel: TPanel;
|
2020-03-30 18:01:44 +00:00
|
|
|
ResetBtn: TButton;
|
|
|
|
ComputeBtn: TButton;
|
|
|
|
CloseBtn: TButton;
|
|
|
|
LineChk: TCheckBox;
|
|
|
|
MeansChk: TCheckBox;
|
|
|
|
ConfChk: TCheckBox;
|
2020-09-20 21:49:11 +00:00
|
|
|
OptionsGroup: TGroupBox;
|
|
|
|
ParamsSplitter: TSplitter;
|
|
|
|
ReportPage: TTabSheet;
|
|
|
|
ChartPage: TTabSheet;
|
2020-03-30 18:01:44 +00:00
|
|
|
YEdit: TEdit;
|
|
|
|
Label3: TLabel;
|
|
|
|
XEdit: TEdit;
|
|
|
|
Label2: TLabel;
|
|
|
|
XinBtn: TBitBtn;
|
|
|
|
XOutBtn: TBitBtn;
|
|
|
|
YInBtn: TBitBtn;
|
|
|
|
YOutBtn: TBitBtn;
|
|
|
|
Label1: TLabel;
|
|
|
|
VarList: TListBox;
|
2020-09-20 20:37:17 +00:00
|
|
|
procedure CloseBtnClick(Sender: TObject);
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure ComputeBtnClick(Sender: TObject);
|
|
|
|
procedure FormActivate(Sender: TObject);
|
|
|
|
procedure FormCreate(Sender: TObject);
|
|
|
|
procedure ResetBtnClick(Sender: TObject);
|
2020-09-21 21:39:40 +00:00
|
|
|
procedure VarListDblClick(Sender: TObject);
|
2020-09-20 21:56:53 +00:00
|
|
|
procedure VarListSelectionChange(Sender: TObject; {%H-}User: boolean);
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure XinBtnClick(Sender: TObject);
|
|
|
|
procedure XOutBtnClick(Sender: TObject);
|
|
|
|
procedure YInBtnClick(Sender: TObject);
|
|
|
|
procedure YOutBtnClick(Sender: TObject);
|
|
|
|
private
|
|
|
|
{ private declarations }
|
|
|
|
FAutoSized: Boolean;
|
2020-09-20 21:49:11 +00:00
|
|
|
FReportFrame: TReportFrame;
|
|
|
|
FChartFrame: TChartFrame;
|
2020-09-20 21:56:53 +00:00
|
|
|
procedure PlotXY(XPoints, YPoints, UpConf, LowConf: DblDyneVec;
|
|
|
|
XMean, YMean, R, Slope, Intercept: Double);
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure UpdateBtnStates;
|
|
|
|
function Validate(out AMsg: String; out AControl: TWinControl;
|
|
|
|
Xcol,Ycol: Integer): Boolean;
|
|
|
|
public
|
|
|
|
{ public declarations }
|
2020-09-20 14:15:41 +00:00
|
|
|
procedure Reset;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
var
|
|
|
|
PlotXYFrm: TPlotXYFrm;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
2020-08-22 22:23:20 +00:00
|
|
|
{$R *.lfm}
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
uses
|
2020-09-20 21:49:11 +00:00
|
|
|
TAChartUtils, TAChartAxisUtils, TALegend, TASources, TACustomSeries, TASeries,
|
2020-08-22 17:31:05 +00:00
|
|
|
Math, Utils;
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
|
|
|
|
{ TPlotXYFrm }
|
|
|
|
|
2020-09-20 14:15:41 +00:00
|
|
|
procedure TPlotXYfrm.Reset;
|
2020-03-30 18:01:44 +00:00
|
|
|
var
|
|
|
|
i: integer;
|
|
|
|
begin
|
|
|
|
XEdit.Text := '';
|
|
|
|
YEdit.Text := '';
|
|
|
|
ConfEdit.Text := FormatFloat('0.0', DEFAULT_CONFIDENCE_LEVEL_PERCENT);
|
|
|
|
LineChk.Checked := false;
|
|
|
|
MeansChk.Checked := false;
|
|
|
|
ConfChk.Checked := false;
|
|
|
|
VarList.Items.Clear;
|
|
|
|
for i := 1 to NoVariables do
|
|
|
|
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
|
2020-09-20 21:49:11 +00:00
|
|
|
FChartFrame.Clear;
|
|
|
|
FReportFrame.Clear;
|
2020-03-30 18:01:44 +00:00
|
|
|
UpdateBtnStates;
|
|
|
|
end;
|
|
|
|
|
2020-09-20 14:15:41 +00:00
|
|
|
|
|
|
|
procedure TPlotXYFrm.ResetBtnClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
Reset;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2020-09-21 21:39:40 +00:00
|
|
|
procedure TPlotXYFrm.VarListDblClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
index: integer;
|
|
|
|
begin
|
|
|
|
index := VarList.ItemIndex;
|
|
|
|
if index > -1 then
|
|
|
|
begin
|
|
|
|
if XEdit.Text = '' then
|
|
|
|
XEdit.Text := VarList.Items[index]
|
|
|
|
else
|
|
|
|
YEdit.Text := VarList.Items[index];
|
|
|
|
VarList.Items.Delete(index);
|
|
|
|
UpdateBtnStates;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure TPlotXYFrm.XinBtnClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
index: integer;
|
|
|
|
begin
|
|
|
|
index := VarList.ItemIndex;
|
2020-04-13 21:59:05 +00:00
|
|
|
if (index > -1) and (XEdit.Text = '') then
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
|
|
|
XEdit.Text := VarList.Items[index];
|
|
|
|
VarList.Items.Delete(index);
|
2020-04-13 21:59:05 +00:00
|
|
|
UpdateBtnStates;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TPlotXYFrm.XOutBtnClick(Sender: TObject);
|
|
|
|
begin
|
2020-04-13 21:59:05 +00:00
|
|
|
if XEdit.Text <> '' then
|
|
|
|
begin
|
|
|
|
VarList.Items.Add(XEdit.Text);
|
|
|
|
XEdit.Text := '';
|
|
|
|
UpdateBtnStates;
|
|
|
|
end;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TPlotXYFrm.YInBtnClick(Sender: TObject);
|
|
|
|
var
|
|
|
|
index: integer;
|
|
|
|
begin
|
|
|
|
index := VarList.ItemIndex;
|
2020-04-13 21:59:05 +00:00
|
|
|
if (index > -1) and (YEdit.Text = '') then
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
|
|
|
YEdit.Text := VarList.Items[index];
|
|
|
|
VarList.Items.Delete(index);
|
2020-04-13 21:59:05 +00:00
|
|
|
UpdateBtnStates;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TPlotXYFrm.YOutBtnClick(Sender: TObject);
|
|
|
|
begin
|
2020-04-13 21:59:05 +00:00
|
|
|
if YEdit.Text <> '' then
|
|
|
|
begin
|
|
|
|
VarList.Items.Add(YEdit.Text);
|
|
|
|
YEdit.Text := '';
|
|
|
|
UpdateBtnStates;
|
|
|
|
end;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TPlotXYFrm.ComputeBtnClick(Sender: TObject);
|
|
|
|
var
|
2020-08-22 17:31:05 +00:00
|
|
|
Xmin, Xmax, Ymin, Ymax, SSx, SSY, t, DF: double;
|
|
|
|
Xmean, Ymean, Xvariance, Yvariance, Xstddev, Ystddev, ConfBand: double;
|
2020-09-20 21:56:53 +00:00
|
|
|
X, Y, R, SEPred, Slope, Intercept, predicted, sedata: double;
|
|
|
|
i: integer;
|
2020-08-22 17:31:05 +00:00
|
|
|
Xcol, Ycol, N, NoSelected: integer;
|
|
|
|
Xpoints: DblDyneVec = nil;
|
|
|
|
Ypoints: DblDyneVec = nil;
|
|
|
|
UpConf: DblDyneVec = nil;
|
|
|
|
lowConf: DblDyneVec = nil;
|
|
|
|
cellstring: string;
|
|
|
|
ColNoSelected: IntDyneVec= nil;
|
|
|
|
C: TWinControl;
|
|
|
|
msg: String;
|
|
|
|
lReport: TStrings;
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-08-22 17:31:05 +00:00
|
|
|
SetLength(Xpoints, NoCases);
|
|
|
|
SetLength(Ypoints, NoCases);
|
|
|
|
SetLength(UpConf, NoCases);
|
|
|
|
SetLength(lowConf, NoCases);
|
|
|
|
SetLength(ColNoSelected, NoVariables);
|
|
|
|
|
|
|
|
Xcol := 0;
|
|
|
|
Ycol := 0;
|
|
|
|
|
|
|
|
for i := 1 to NoVariables do
|
|
|
|
begin
|
|
|
|
cellstring := OS3MainFrm.DataGrid.Cells[i,0];
|
|
|
|
if cellstring = XEdit.Text then Xcol := i;
|
|
|
|
if cellstring = YEdit.Text then Ycol := i;
|
|
|
|
end;
|
|
|
|
|
|
|
|
// Validation
|
|
|
|
if not Validate(msg, C, Xcol, Ycol) then
|
|
|
|
begin
|
|
|
|
C.SetFocus;
|
|
|
|
ErrorMsg(msg);
|
|
|
|
ModalResult := mrNone;
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
|
|
|
|
NoSelected := 2;
|
|
|
|
ColNoSelected[0] := Xcol;
|
|
|
|
ColNoSelected[1] := Ycol;
|
|
|
|
Xmax := -Infinity;
|
|
|
|
Xmin := Infinity;
|
|
|
|
Ymax := -Infinity;
|
|
|
|
Ymin := Infinity;
|
|
|
|
Xmean := 0.0;
|
|
|
|
Ymean := 0.0;
|
|
|
|
XVariance := 0.0;
|
|
|
|
YVariance := 0.0;
|
2020-09-20 21:56:53 +00:00
|
|
|
SSX := 0.0;
|
|
|
|
SSY := 0.0;
|
2020-08-22 17:31:05 +00:00
|
|
|
R := 0.0;
|
|
|
|
|
|
|
|
N := 0;
|
|
|
|
for i := 1 to NoCases do
|
|
|
|
begin
|
|
|
|
if not GoodRecord(i, NoSelected, ColNoSelected) then continue;
|
|
|
|
inc(N);
|
|
|
|
X := StrToFloat(OS3MainFrm.DataGrid.Cells[Xcol,i]);
|
|
|
|
Y := StrToFloat(OS3MainFrm.DataGrid.Cells[Ycol,i]);
|
|
|
|
XPoints[N-1] := X;
|
|
|
|
YPoints[N-1] := Y;
|
|
|
|
XMax := Max(X, XMax);
|
|
|
|
XMin := Min(X, XMin);
|
|
|
|
YMax := Max(Y, YMax);
|
|
|
|
YMin := Min(Y, YMin);
|
|
|
|
XMean := XMean + X;
|
|
|
|
YMean := YMean + Y;
|
|
|
|
SSX := SSX + sqr(X);
|
|
|
|
SSY := SSY + sqr(Y);
|
|
|
|
R := R + X * Y;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if N < 1 then
|
|
|
|
begin
|
|
|
|
ErrorMsg('No data values.');
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
|
2020-09-21 16:22:05 +00:00
|
|
|
// Trim array lengths
|
|
|
|
SetLength(Xpoints, NoCases);
|
|
|
|
SetLength(Ypoints, NoCases);
|
|
|
|
SetLength(UpConf, NoCases);
|
|
|
|
SetLength(lowConf, NoCases);
|
|
|
|
|
2020-08-22 17:31:05 +00:00
|
|
|
// sort on X
|
|
|
|
SortOnX(XPoints, YPoints);
|
|
|
|
|
|
|
|
// calculate statistics
|
|
|
|
XVariance := SSX - sqr(XMean) / N;
|
|
|
|
XVariance := XVariance / (N - 1);
|
|
|
|
XStdDev := sqrt(XVariance);
|
|
|
|
|
|
|
|
YVariance := SSY - sqr(YMean) / N;
|
|
|
|
YVariance := YVariance / (N - 1);
|
|
|
|
YStdDev := sqrt(YVariance);
|
|
|
|
|
|
|
|
R := R - Xmean * Ymean / N;
|
|
|
|
R := R / (N - 1);
|
|
|
|
R := R / (XStdDev * YStdDev);
|
|
|
|
SEPred := sqrt(1.0 - sqr(R)) * YStdDev;
|
|
|
|
SEPred := SEPred * sqrt((N - 1) / (N - 2));
|
|
|
|
XMean := XMean / N;
|
|
|
|
YMean := YMean / N;
|
|
|
|
Slope := R * YStdDev / XStdDev;
|
|
|
|
Intercept := YMean - Slope * XMean;
|
|
|
|
|
|
|
|
// Now, print the descriptive statistics to the output form if requested
|
2020-09-20 21:49:11 +00:00
|
|
|
lReport := TStringList.Create;
|
|
|
|
try
|
|
|
|
lReport.Add('X vs. Y PLOT');
|
|
|
|
lReport.Add('');
|
|
|
|
lReport.Add('Data file: %s', [OS3MainFrm.FileNameEdit.Text]);
|
|
|
|
lReport.Add('');
|
|
|
|
lReport.Add('Variables:');
|
|
|
|
lReport.Add(' X: %s', [XEdit.Text]);
|
|
|
|
lReport.Add(' Y: %s', [YEdit.Text]);
|
|
|
|
lReport.Add('');
|
|
|
|
lReport.Add('Variable Mean Variance Std.Dev.');
|
|
|
|
lReport.Add('---------- -------- -------- --------');
|
|
|
|
lReport.Add('%-10s %8.2f %8.2f %8.2f', [XEdit.Text, XMean, XVariance, XStdDev]);
|
|
|
|
lReport.Add('%-10s %8.2f %8.2f %8.2f', [YEdit.Text, YMean, YVariance, YStdDev]);
|
|
|
|
lReport.Add('');
|
|
|
|
lReport.Add('Regression:');
|
|
|
|
lReport.Add(' Correlation: %8.3f', [R]);
|
|
|
|
lReport.Add(' Slope: %8.3f', [Slope]);
|
|
|
|
lReport.Add(' Intercept: %8.3f', [Intercept]);
|
|
|
|
lReport.Add(' Standard Error of Estimate: %8.3f', [SEPred]);
|
|
|
|
lReport.Add(' Number of good cases: %8d', [N]);
|
|
|
|
|
|
|
|
FReportFrame.DisplayReport(lReport);
|
|
|
|
finally
|
|
|
|
lReport.Free;
|
2020-08-22 17:31:05 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
// Get upper and lower confidence points for each X value
|
|
|
|
if ConfChk.Checked then
|
|
|
|
begin
|
|
|
|
ConfBand := StrToFloat(ConfEdit.Text) / 100.0;
|
|
|
|
DF := N - 2;
|
|
|
|
t := InverseT(ConfBand, DF);
|
|
|
|
for i := 0 to N-1 do
|
|
|
|
begin
|
|
|
|
X := XPoints[i];
|
|
|
|
predicted := slope * X + intercept;
|
|
|
|
sedata := SEPred * sqrt(1.0 + (1.0 / N) + (sqr(X - XMean) / SSx));
|
|
|
|
UpConf[i] := predicted + (t * sedata);
|
|
|
|
lowConf[i] := predicted - (t * sedata);
|
|
|
|
YMax := Max(YMax, UpConf[i]);
|
|
|
|
YMin := Min(YMin, LowConf[i]);
|
|
|
|
end;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
ConfBand := 0.0;
|
|
|
|
|
|
|
|
// Plot the values (and optional line and confidence band if elected)
|
2020-09-20 21:49:11 +00:00
|
|
|
PlotXY(Xpoints, Ypoints, UpConf, LowConf, XMean, YMean, R, Slope, Intercept);
|
2020-08-22 17:31:05 +00:00
|
|
|
|
|
|
|
// cleanup
|
|
|
|
ColNoSelected := nil;
|
|
|
|
lowConf := nil;
|
|
|
|
UpConf := nil;
|
|
|
|
Ypoints := nil;
|
|
|
|
Xpoints := nil;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-08-22 17:31:05 +00:00
|
|
|
|
2020-09-20 20:37:17 +00:00
|
|
|
procedure TPlotXYFrm.CloseBtnClick(Sender: TObject);
|
|
|
|
begin
|
|
|
|
Close;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure TPlotXYFrm.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;
|
|
|
|
|
2020-09-20 21:49:11 +00:00
|
|
|
ParamsPanel.Constraints.MinHeight := OptionsGroup.Top + OptionsGroup.Height +
|
|
|
|
OptionsGroup.BorderSpacing.Bottom + Bevel1.Height +
|
|
|
|
CloseBtn.Height + CloseBtn.BorderSpacing.Top;
|
|
|
|
ParamsPanel.Constraints.MinWidth := OptionsGroup.Width * 2 - XInBtn.Width div 2 - XInBtn.BorderSpacing.Left;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-09-20 21:49:11 +00:00
|
|
|
Constraints.MinHeight := ParamsPanel.Constraints.MinHeight + ParamsPanel.BorderSpacing.Around*2;
|
|
|
|
Constraints.MinWidth := ParamsPanel.Constraints.MinWidth + 200;
|
|
|
|
if Height < Constraints.MinHeight then Height := 1;
|
|
|
|
if Width < Constraints.MinWidth then Width := 1;
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-09-20 20:37:17 +00:00
|
|
|
Position := poDesigned;
|
2020-03-30 18:01:44 +00:00
|
|
|
FAutoSized := True;
|
|
|
|
end;
|
|
|
|
|
2020-08-22 17:31:05 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure TPlotXYFrm.FormCreate(Sender: TObject);
|
|
|
|
begin
|
|
|
|
Assert(OS3MainFrm <> nil);
|
2020-09-20 21:49:11 +00:00
|
|
|
|
2020-09-23 11:19:08 +00:00
|
|
|
InitForm(self);
|
2020-09-22 13:20:08 +00:00
|
|
|
|
2020-09-20 21:49:11 +00:00
|
|
|
FReportFrame := TReportFrame.Create(self);
|
|
|
|
FReportFrame.Parent := ReportPage;
|
|
|
|
FReportFrame.Align := alClient;
|
|
|
|
|
|
|
|
FChartFrame := TChartFrame.Create(self);
|
|
|
|
FChartFrame.Parent := ChartPage;
|
|
|
|
FChartFrame.Align := alClient;
|
|
|
|
FChartFrame.Chart.Legend.Alignment := laBottomCenter;
|
|
|
|
FChartFrame.Chart.Legend.ColumnCount := 3;
|
|
|
|
FChartFrame.Chart.Legend.TextFormat := tfHTML;
|
|
|
|
FChartFrame.Chart.BottomAxis.Intervals.MaxLength := 80;
|
|
|
|
FChartFrame.Chart.BottomAxis.Intervals.MinLength := 30;
|
|
|
|
with FChartFrame.Chart.AxisList.Add do
|
|
|
|
begin
|
|
|
|
Alignment := calRight;
|
|
|
|
Marks.Source := TListChartSource.Create(self);
|
|
|
|
Marks.Style := smsLabel;
|
|
|
|
Grid.Visible := false;
|
|
|
|
end;
|
|
|
|
with FChartFrame.Chart.AxisList.Add do
|
|
|
|
begin
|
|
|
|
Alignment := calTop;
|
|
|
|
Marks.Source := TListChartSource.Create(self);
|
|
|
|
Marks.Style := smsLabel;
|
|
|
|
Grid.Visible := false;
|
|
|
|
end;
|
|
|
|
|
2020-09-20 14:15:41 +00:00
|
|
|
Reset;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
2020-09-20 21:56:53 +00:00
|
|
|
procedure TPlotXYFrm.PlotXY(XPoints, YPoints, UpConf, LowConf: DblDyneVec;
|
|
|
|
XMean, YMean, R, Slope, Intercept: Double);
|
2020-08-22 17:31:05 +00:00
|
|
|
var
|
2020-09-20 21:49:11 +00:00
|
|
|
tmpX, tmpY: array[0..1] of Double;
|
2020-08-22 17:31:05 +00:00
|
|
|
xmin, xmax, ymin, ymax: Double;
|
2020-09-20 21:49:11 +00:00
|
|
|
rightLabels: TListChartSource;
|
|
|
|
topLabels: TListChartSource;
|
|
|
|
ser: TChartSeries;
|
2020-03-30 18:01:44 +00:00
|
|
|
begin
|
2020-09-20 21:49:11 +00:00
|
|
|
rightLabels := FChartFrame.Chart.AxisList[2].Marks.Source as TListChartSource;
|
|
|
|
rightLabels.Clear;
|
|
|
|
topLabels := FChartFrame.Chart.AxisList[3].Marks.Source as TListChartSource;
|
|
|
|
topLabels.Clear;
|
|
|
|
FChartFrame.Clear;
|
2020-08-22 17:31:05 +00:00
|
|
|
|
|
|
|
// Titles
|
2020-09-20 21:49:11 +00:00
|
|
|
FChartFrame.SetTitle('X vs. Y plot using file ' + OS3MainFrm.FileNameEdit.Text);
|
|
|
|
FChartFrame.SetFooter(Format('R(X,Y) = %.3f, Slope = %.3f, Intercept = %.3f', [
|
2020-08-22 17:31:05 +00:00
|
|
|
R, Slope, Intercept
|
|
|
|
]));
|
2020-09-20 21:49:11 +00:00
|
|
|
FChartFrame.SetXTitle(XEdit.Text);
|
|
|
|
FChartFrame.SetYTitle(YEdit.Text);
|
2020-08-22 17:31:05 +00:00
|
|
|
|
|
|
|
// Draw upper confidence band
|
|
|
|
if ConfChk.Checked then
|
2020-09-20 21:49:11 +00:00
|
|
|
begin
|
|
|
|
ser := FChartFrame.PlotXY(ptLines, XPoints, UpConf, nil, nil, 'Upper confidence band', clRed);
|
|
|
|
rightLabels.Add(ser.yValue[ser.Count-1], ser.YValue[ser.Count-1], 'UCL');
|
|
|
|
end;
|
2020-08-22 17:31:05 +00:00
|
|
|
|
|
|
|
// Plot data points
|
2020-09-20 21:49:11 +00:00
|
|
|
FChartFrame.PlotXY(ptSymbols, XPoints, YPoints, nil, nil, 'Data values', clNavy);
|
2020-08-22 17:31:05 +00:00
|
|
|
|
|
|
|
// Draw lower confidence band
|
|
|
|
if ConfChk.Checked then
|
2020-09-20 21:49:11 +00:00
|
|
|
begin
|
|
|
|
ser := FChartFrame.PlotXY(ptLines, XPoints, LowConf, nil, nil, 'Lower confidence band', clRed);
|
|
|
|
rightLabels.Add(ser.yValue[ser.Count-1], ser.YValue[ser.Count-1], 'LCL');
|
|
|
|
end;
|
2020-08-22 17:31:05 +00:00
|
|
|
|
2020-09-20 21:49:11 +00:00
|
|
|
FChartFrame.Chart.Prepare;
|
|
|
|
FChartFrame.GetXRange(xmin, xmax, false);
|
|
|
|
FChartFrame.GetYRange(ymin, ymax, false);
|
2020-08-22 17:31:05 +00:00
|
|
|
|
|
|
|
// Draw means
|
|
|
|
if MeansChk.Checked then
|
|
|
|
begin
|
2020-09-20 21:49:11 +00:00
|
|
|
FChartFrame.VertLine(XMean, clGreen, psDashDot, 'Mean ' + XEdit.Text);
|
2020-09-20 21:56:53 +00:00
|
|
|
topLabels.Add(XMean, XMean, 'Mean ' + XEdit.Text);
|
2020-09-20 21:49:11 +00:00
|
|
|
FChartFrame.HorLine(YMean, clGreen, psDash, 'Mean ' + YEdit.Text);
|
2020-09-20 21:56:53 +00:00
|
|
|
rightLabels.Add(YMean, YMean, 'Mean ' + YEdit.Text);
|
2020-08-22 17:31:05 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
// Draw regression line
|
|
|
|
if LineChk.Checked then
|
|
|
|
begin
|
|
|
|
tmpX[0] := xmin; tmpY[0] := tmpX[0] * slope + intercept;
|
|
|
|
tmpX[1] := xmax; tmpY[1] := tmpX[1] * slope + intercept;
|
2020-09-20 21:49:11 +00:00
|
|
|
ser := FChartFrame.PlotXY(ptLines, tmpX, tmpY, nil, nil, 'Predicted', clBlack);
|
|
|
|
rightLabels.Add(tmpY[1], tmpY[1], 'Predicted');
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
|
|
|
|
2020-09-20 21:49:11 +00:00
|
|
|
FChartFrame.Chart.Legend.Visible := false;
|
2020-08-22 17:31:05 +00:00
|
|
|
end;
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
|
2020-08-22 17:31:05 +00:00
|
|
|
procedure TPlotXYFrm.UpdateBtnStates;
|
|
|
|
begin
|
|
|
|
XinBtn.Enabled := (VarList.ItemIndex > -1) and (XEdit.Text = '');
|
|
|
|
XoutBtn.Enabled := (XEdit.Text <> '');
|
2020-09-21 21:39:40 +00:00
|
|
|
|
2020-08-22 17:31:05 +00:00
|
|
|
YinBtn.Enabled := (VarList.ItemIndex > -1) and (YEdit.Text = '');
|
|
|
|
YoutBtn.Enabled := (YEdit.Text <> '');
|
2020-09-21 21:39:40 +00:00
|
|
|
|
|
|
|
FReportFrame.UpdateBtnStates;
|
|
|
|
FChartFrame.UpdateBtnStates;
|
2020-03-30 18:01:44 +00:00
|
|
|
end;
|
2020-08-22 17:31:05 +00:00
|
|
|
|
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
function TPlotXYFrm.Validate(out AMsg: String; out AControl: TWinControl;
|
|
|
|
Xcol, Ycol: Integer): Boolean;
|
|
|
|
begin
|
|
|
|
Result := false;
|
|
|
|
|
|
|
|
if (Xcol = 0) then
|
|
|
|
begin
|
|
|
|
AControl := XEdit;
|
|
|
|
AMsg := 'No case selected for X.';
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if (Ycol = 0) then
|
|
|
|
begin
|
|
|
|
AControl := YEdit;
|
|
|
|
AMsg := 'No case selected for Y.';
|
|
|
|
exit;
|
|
|
|
end;
|
|
|
|
Result := true;
|
|
|
|
end;
|
|
|
|
|
2020-08-22 17:31:05 +00:00
|
|
|
|
2020-03-30 18:01:44 +00:00
|
|
|
procedure TPlotXYFrm.VarListSelectionChange(Sender: TObject; User: boolean);
|
|
|
|
begin
|
|
|
|
UpdateBtnStates;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
end.
|
|
|
|
|