You've already forked lazarus-ccr
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7409 8e941d3f-bd1b-0410-a28a-d453659cc2b4
745 lines
23 KiB
ObjectPascal
745 lines
23 KiB
ObjectPascal
// Use file "Sickness.laz" for testing
|
|
|
|
unit ResistanceLineUnit;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
|
|
StdCtrls, ExtCtrls, Buttons, Printers,
|
|
MainUnit, Globals, FunctionsLib, OutputUnit, DataProcs, DictionaryUnit,
|
|
ContextHelpUnit, BlankFrmUnit;
|
|
|
|
type
|
|
|
|
{ TResistanceLineForm }
|
|
|
|
TResistanceLineForm = class(TForm)
|
|
Bevel1: TBevel;
|
|
Bevel2: TBevel;
|
|
HorCenterBevel: TBevel;
|
|
GridChk: TCheckBox;
|
|
Memo1: TLabel;
|
|
PlotMediansChk: TCheckBox;
|
|
StdCorChk: TCheckBox;
|
|
PointsChk: TCheckBox;
|
|
ConfChk: TCheckBox;
|
|
ConfEdit: TEdit;
|
|
DescChk: TCheckBox;
|
|
GroupBox1: TGroupBox;
|
|
Label5: TLabel;
|
|
LineChk: TCheckBox;
|
|
VarList: TListBox;
|
|
MeansChk: TCheckBox;
|
|
ResetBtn: TButton;
|
|
ComputeBtn: TButton;
|
|
CloseBtn: TButton;
|
|
XInBtn: TBitBtn;
|
|
YInBtn: TBitBtn;
|
|
XOutBtn: TBitBtn;
|
|
YOutBtn: TBitBtn;
|
|
XEdit: TEdit;
|
|
YEdit: TEdit;
|
|
Label1: TLabel;
|
|
Label2: TLabel;
|
|
Label3: TLabel;
|
|
Label4: TLabel;
|
|
procedure ComputeBtnClick(Sender: TObject);
|
|
procedure FormActivate(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure ResetBtnClick(Sender: TObject);
|
|
procedure StdCorChkChange(Sender: TObject);
|
|
procedure VarListSelectionChange(Sender: TObject; User: boolean);
|
|
procedure XInBtnClick(Sender: TObject);
|
|
procedure XOutBtnClick(Sender: TObject);
|
|
procedure YInBtnClick(Sender: TObject);
|
|
procedure YOutBtnClick(Sender: TObject);
|
|
private
|
|
{ private declarations }
|
|
FAutoSized: Boolean;
|
|
function Median(var X: DblDyneVec; ASize: integer): double;
|
|
procedure PlotXY(var Xpoints, YPoints, UpConf, LowConf: DblDyneVec;
|
|
ConfBand: double; Xmean, Ymean, R, Slope, Intercept: double;
|
|
Xmax, Xmin, Ymax, Ymin: double; N, PlotNo: integer);
|
|
procedure UpdateBtnStates;
|
|
|
|
public
|
|
{ public declarations }
|
|
end;
|
|
|
|
var
|
|
ResistanceLineForm: TResistanceLineForm;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Math;
|
|
|
|
{ TResistanceLineForm }
|
|
|
|
procedure TResistanceLineForm.ResetBtnClick(Sender: TObject);
|
|
var
|
|
i: integer;
|
|
begin
|
|
StdCorChk.Checked := false;
|
|
GridChk.Checked := false;
|
|
PlotMediansChk.Checked := false;
|
|
XEdit.Text := '';
|
|
YEdit.Text := '';
|
|
VarList.Clear;
|
|
ConfEdit.Text := FormatFloat('0.0', DEFAULT_CONFIDENCE_LEVEL_PERCENT);
|
|
for i := 1 to NoVariables do
|
|
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
|
|
UpdateBtnStates;
|
|
end;
|
|
|
|
procedure TResistanceLineForm.StdCorChkChange(Sender: TObject);
|
|
begin
|
|
if StdCorChk.Checked then GroupBox1.Enabled := true else GroupBox1.Enabled := false;
|
|
end;
|
|
|
|
procedure TResistanceLineForm.ComputeBtnClick(Sender: TObject);
|
|
var
|
|
XYPoints : DblDyneMat;
|
|
XMedians : DblDyneVec;
|
|
YMedians : DblDyneVec;
|
|
XVector, YVector : DblDyneVec;
|
|
cellstring, outline : string;
|
|
ColNoSelected : IntDyneVec;
|
|
UpConf : DblDyneVec;
|
|
lowConf : DblDyneVec;
|
|
GrpSize : IntDyneVec;
|
|
Xcol, Ycol, N, NoSelected, i, j, size, size1, size2, size3 : integer;
|
|
X, Y, tempX, tempY : double;
|
|
Xmin, Xmax, Ymin, Ymax, SSx, t, DF : double;
|
|
Xmean, Ymean, Xvariance, Yvariance, Xstddev, Ystddev, ConfBand : double;
|
|
R, SEPred, Slope, Intercept, predicted, sedata : double;
|
|
slope1, slope2 : double;
|
|
c, c1, c2, c3 : double; // constants obtained from control points
|
|
lReport: TStrings;
|
|
begin
|
|
SetLength(XYPoints, NoCases, NoCases);
|
|
SetLength(XMedians, 3);
|
|
SetLength(YMedians, 3);
|
|
SetLength(XVector, NoCases);
|
|
SetLength(YVector, NoCases);
|
|
SetLength(ColNoSelected, NoVariables);
|
|
SetLength(UpConf, NoCases + 1);
|
|
SetLength(lowConf, NoCases + 1);
|
|
SetLength(GrpSize, 3);
|
|
Xcol := 0;
|
|
Ycol := 0;
|
|
Xmax := -1.0e20;
|
|
Xmin := 1.0e20;
|
|
Ymax := -1.0e20;
|
|
Ymin := 1.0e20;
|
|
Xmean := 0.0;
|
|
Ymean := 0.0;
|
|
Xvariance := 0.0;
|
|
Yvariance := 0.0;
|
|
R := 0.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;
|
|
NoSelected := 2;
|
|
ColNoSelected[0] := Xcol;
|
|
ColNoSelected[1] := Ycol;
|
|
N := 0;
|
|
for i := 1 to NoCases do
|
|
begin
|
|
if not GoodRecord(i,NoSelected,ColNoSelected) then continue;
|
|
X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[Xcol,i]));
|
|
Y := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[Ycol,i]));
|
|
if X > Xmax then Xmax := X;
|
|
if X < Xmin then Xmin := X;
|
|
if Y > Ymax then Ymax := Y;
|
|
if Y < Ymin then Ymin := Y;
|
|
Xmean := Xmean + X;
|
|
Ymean := Ymean + Y;
|
|
Xvariance := Xvariance + X * X;
|
|
Yvariance := Yvariance + Y * Y;
|
|
R := R + X * Y;
|
|
XYPoints[N,0] := X;
|
|
XYPoints[N,1] := Y;
|
|
inc(N);
|
|
end;
|
|
|
|
// sort on X values
|
|
for i := 0 to N-2 do
|
|
begin
|
|
for j := i + 1 to N-1 do
|
|
begin
|
|
if XYPoints[i,0] > XYPoints[j,0] then // swap
|
|
begin
|
|
tempX := XYPoints[i,0];
|
|
tempY := XYPoints[i,1];
|
|
XYPoints[i,0] := XYPoints[j,0];
|
|
XYPoints[i,1] := XYPoints[j,1];
|
|
XYPoints[j,0] := tempX;
|
|
XYPoints[j,1] := tempY;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
// calculate statistics
|
|
Xvariance := Xvariance - Xmean * Xmean / N;
|
|
SSx := Xvariance;
|
|
Xvariance := Xvariance / (N - 1);
|
|
Xstddev := sqrt(Xvariance);
|
|
|
|
Yvariance := Yvariance - Ymean * 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 - (R * 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 if requested
|
|
lReport := TStringList.Create;
|
|
try
|
|
if DescChk.Checked then
|
|
begin
|
|
lReport.Add('Original X versus Y Plot Data');
|
|
lReport.Add('');
|
|
lReport.Add('X = %s, Y = %s from file: %s',[
|
|
Xedit.Text, YEdit.Text, OS3MainFrm.FileNameEdit.Text
|
|
]);
|
|
lReport.Add('');
|
|
lReport.Add('Variable Mean Variance Std.Dev.');
|
|
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('Correlation: %8.4f', [R]);
|
|
lReport.Add('Slope: %8.2f', [Slope]);
|
|
lReport.Add('Intercept: %8.2f', [Intercept]);
|
|
lReport.Add('Standard Error of Estimate: %8.2f', [SEPred]);
|
|
lReport.Add('Number of good cases: %8d', [N]);
|
|
lReport.Add('');
|
|
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 := 1 to N do
|
|
begin
|
|
X := XYpoints[i-1,0];
|
|
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);
|
|
if UpConf[i] > Ymax then Ymax := UpConf[i];
|
|
if lowConf[i] < Ymin then Ymin := lowConf[i];
|
|
end;
|
|
end else
|
|
ConfBand := 0.0;
|
|
|
|
// plot the values (and optional line and confidence band if elected)
|
|
if PointsChk.Checked then
|
|
begin
|
|
for i := 0 to N-1 do
|
|
begin
|
|
XVector[i] := XYPoints[i,0];
|
|
YVector[i] := XYPoints[i,1];
|
|
end;
|
|
PlotXY(
|
|
XVector, YVector, UpConf, LowConf, ConfBand, Xmean, Ymean, R,
|
|
Slope, Intercept, Xmax, Xmin, Ymax, Ymin, N, 1
|
|
);
|
|
end;
|
|
//LineChk.Checked := false;
|
|
//ConfChk.Checked := false;
|
|
ConfBand := 0.0;
|
|
|
|
// Now do the resistant line analysis
|
|
// obtain 1/3 size
|
|
size := n div 3;
|
|
size1 := size;
|
|
size3 := size;
|
|
size2 := n - size1 - size3;
|
|
GrpSize[0] := size1;
|
|
GrpSize[1] := size2;
|
|
GrpSize[2] := size3;
|
|
|
|
// get median for each group of x and y values
|
|
// first group:
|
|
for i := 0 to size1-1 do
|
|
begin
|
|
XVector[i] := XYPoints[i,0];
|
|
YVector[i] := XYPoints[i,1];
|
|
end;
|
|
XMedians[0] := Median(XVector,size1);
|
|
YMedians[0] := Median(YVector,size1);
|
|
|
|
// second group
|
|
j := 0;
|
|
for i := size1 to size1 + size2 - 1 do
|
|
begin
|
|
XVector[j] := XYPoints[i,0];
|
|
YVector[j] := XYPoints[i,1];
|
|
inc(j);
|
|
end;
|
|
XMedians[1] := Median(XVector,size2);
|
|
YMedians[1] := Median(YVector,size2);
|
|
|
|
// third group
|
|
j := 0;
|
|
for i := (size1 + size2) to N-1 do
|
|
begin
|
|
XVector[j] := XYPoints[i,0];
|
|
YVector[j] := XYPoints[i,1];
|
|
inc(j);
|
|
end;
|
|
XMedians[2] := Median(XVector,size3);
|
|
YMedians[2] := Median(YVector,size3);
|
|
|
|
lReport.Add('Group X Median Y Median Size');
|
|
for i := 0 to 2 do
|
|
lReport.Add('%3d %5.3f %5.3f %d', [i+1, XMedians[i], YMedians[i], GrpSize[i]]);
|
|
lReport.Add('');
|
|
|
|
slope1 := (YMedians[1] - YMedians[0]) / (XMedians[1] - XMedians[0]);
|
|
slope2 := (YMedians[2] - YMedians[1]) / (XMedians[2] - XMedians[1]);
|
|
lReport.Add('Half Slopes: %10.3f and %.3f', [slope1, slope2]);
|
|
|
|
Slope := (YMedians[2] - YMedians[0]) / (XMedians[2] - XMedians[0]);
|
|
lReport.Add('Slope: %10.3f', [Slope]);
|
|
|
|
tempx := slope2 / slope1;
|
|
lReport.Add('Ratio of half slopes: %10.3f',[tempx]);
|
|
|
|
// obtain estimate of the constant for the prediction equation
|
|
c1 := slope * XMedians[0] - YMedians[0];
|
|
c2 := slope * XMedians[1] - YMedians[1];
|
|
c3 := slope * XMedians[2] - YMedians[2];
|
|
c := (c1 + c2 + c3) / 3.0;
|
|
lReport.Add('Equation: y := %.3f * X + (%.3f)', [slope, c]);
|
|
|
|
if GridChk.Checked then
|
|
begin
|
|
// Get the residuals (Y - predicted Y) for each X value and place in the grid
|
|
outline := 'Pred.' + OS3MainFrm.DataGrid.Cells[Ycol,0];
|
|
DictionaryFrm.NewVar(NoVariables+1);
|
|
DictionaryFrm.DictGrid.Cells[1,NoVariables] := outline;
|
|
OS3MainFrm.DataGrid.Cells[NoVariables,0] := outline;
|
|
|
|
outline := 'Residual';
|
|
DictionaryFrm.NewVar(NoVariables+1);
|
|
DictionaryFrm.DictGrid.Cells[1,NoVariables] := outline;
|
|
OS3MainFrm.DataGrid.Cells[NoVariables,0] := outline;
|
|
|
|
for i := 1 to NoCases do
|
|
begin
|
|
if not GoodRecord(i,NoSelected,ColNoSelected) then continue;
|
|
X := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[Xcol,i]));
|
|
Y := StrToFloat(Trim(OS3MainFrm.DataGrid.Cells[Ycol,i]));
|
|
if c >= 0 then
|
|
predicted := slope * X + c
|
|
else
|
|
predicted := slope * X - c;
|
|
Y := Y - predicted; // residual
|
|
outline := Format('%9.3f',[predicted]);
|
|
OS3MainFrm.DataGrid.Cells[NoVariables-1,i] := outline;
|
|
outline := Format('%9.3f',[Y]);
|
|
OS3MainFrm.DataGrid.Cells[NoVariables,i] := outline;
|
|
end;
|
|
end;
|
|
|
|
DisplayReport(lReport);
|
|
|
|
// plot the values (and optional line and confidence band if elected)
|
|
if PlotMediansChk.Checked then
|
|
PlotXY(
|
|
XMedians, YMedians, UpConf, LowConf, ConfBand, Xmean, Ymean, R,
|
|
Slope, Intercept, Xmax, Xmin, Ymax, Ymin, 3, 2
|
|
);
|
|
|
|
finally
|
|
lReport.Free;
|
|
GrpSize := nil;
|
|
LowConf := nil;
|
|
UpConf := nil;
|
|
ColNoSelected := nil;
|
|
YVector := nil;
|
|
XVector := nil;
|
|
YMedians := nil;
|
|
XMedians := nil;
|
|
XYPoints := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure TResistanceLineForm.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.MinWidth := XEdit.Width;
|
|
|
|
Constraints.MinWidth := Width;
|
|
Constraints.MinHeight := Height;
|
|
|
|
FAutoSized := true;
|
|
end;
|
|
|
|
procedure TResistanceLineForm.FormCreate(Sender: TObject);
|
|
begin
|
|
Assert(OS3MainFrm <> nil);
|
|
|
|
if BlankFrm = nil then Application.CreateForm(TBlankFrm, BlankFrm);
|
|
if DictionaryFrm = nil then Application.CreateForm(TDictionaryFrm, DictionaryFrm);
|
|
end;
|
|
|
|
procedure TResistanceLineForm.XInBtnClick(Sender: TObject);
|
|
var
|
|
index: integer;
|
|
begin
|
|
index := VarList.ItemIndex;
|
|
if (index > -1) and (XEdit.Text = '') then
|
|
begin
|
|
XEdit.Text := VarList.items[index];
|
|
VarList.Items.Delete(index);
|
|
end;
|
|
UpdateBtnStates;
|
|
end;
|
|
|
|
procedure TResistanceLineForm.XOutBtnClick(Sender: TObject);
|
|
begin
|
|
if XEdit.Text <> '' then
|
|
begin
|
|
VarList.Items.Add(XEdit.Text);
|
|
XEdit.Text := '';
|
|
end;
|
|
UpdateBtnStates;
|
|
end;
|
|
|
|
procedure TResistanceLineForm.YInBtnClick(Sender: TObject);
|
|
var
|
|
index: integer;
|
|
begin
|
|
index := VarList.ItemIndex;
|
|
if (index > -1) and (YEdit.Text = '') then
|
|
begin
|
|
YEdit.Text := VarList.items[index];
|
|
VarList.Items.Delete(index);
|
|
end;
|
|
UpdateBtnStates;
|
|
end;
|
|
|
|
procedure TResistanceLineForm.YOutBtnClick(Sender: TObject);
|
|
begin
|
|
if YEdit.Text <> '' then
|
|
begin
|
|
VarList.Items.Add(YEdit.Text);
|
|
YEdit.Text := '';
|
|
end;
|
|
UpdateBtnStates;
|
|
end;
|
|
|
|
function TResistanceLineForm.Median(VAR X: DblDyneVec; ASize: integer): double;
|
|
var
|
|
midpt: integer;
|
|
value: double;
|
|
i, j: integer;
|
|
begin
|
|
// sort values
|
|
for i := 0 to ASize-2 do
|
|
begin
|
|
for j := i + 1 to ASize-1 do
|
|
begin
|
|
if X[i] > X[j] then // swap
|
|
begin
|
|
value := X[i];
|
|
X[i] := X[j];
|
|
X[j] := value;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if ASize > 2 then
|
|
begin
|
|
midpt := ASize div 2;
|
|
if 2 * midpt = ASize then // even no. of values
|
|
begin
|
|
value := (X[midpt-1] + X[midpt]) / 2;
|
|
end else
|
|
value := X[midpt]; // odd no. of values
|
|
Median := value;
|
|
end else
|
|
if ASize = 2 then
|
|
Median := (X[0] + X[1]) / 2;
|
|
|
|
Result := Median;
|
|
end;
|
|
|
|
procedure TResistanceLineForm.PlotXY(var Xpoints, Ypoints, UpConf, LowConf: DblDyneVec;
|
|
ConfBand, XMean, YMean, R, Slope, Intercept: double;
|
|
Xmax, Xmin, Ymax, Ymin: double; N, PlotNo: integer);
|
|
var
|
|
i, xpos, ypos, hleft, hright, vtop, vbottom, imagewide: integer;
|
|
vhi, hwide, offset, strhi, imagehi: integer;
|
|
valincr, Yvalue, Xvalue: double;
|
|
Title: string;
|
|
YU, YL, XU, XL: double;
|
|
begin
|
|
BlankFrm.Image1.Canvas.Clear;
|
|
if PlotNo = 1 then
|
|
begin
|
|
Title := 'X versus Y PLOT Using File: ' + OS3MainFrm.FileNameEdit.Text;
|
|
BlankFrm.Caption := Title;
|
|
end
|
|
else
|
|
begin
|
|
Title := 'Median Plot for three groups';
|
|
BlankFrm.Caption := Title;
|
|
end;
|
|
imagewide := BlankFrm.Image1.Width;
|
|
imagehi := BlankFrm.Image1.Height;
|
|
vtop := 40;
|
|
vbottom := round(imagehi) - 80;
|
|
vhi := vbottom - vtop;
|
|
hleft := 100;
|
|
hright := imagewide - 80;
|
|
hwide := hright - hleft;
|
|
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
|
|
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
|
|
|
|
// Draw chart border
|
|
BlankFrm.Image1.Canvas.Rectangle(0,0,imagewide,imagehi);
|
|
|
|
// draw Means
|
|
if MeansChk.Checked then
|
|
begin
|
|
ypos := round(vhi * ( (Ymax - Ymean) / (Ymax - Ymin)));
|
|
ypos := ypos + vtop;
|
|
xpos := hleft;
|
|
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
|
|
xpos := hright;
|
|
BlankFrm.Image1.Canvas.Pen.Color := clGreen;
|
|
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
|
|
Title := 'MEAN ';
|
|
Title := Title + YEdit.Text;
|
|
strhi := BlankFrm.Image1.Canvas.TextHeight(Title);
|
|
ypos := ypos - strhi div 2;
|
|
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
|
|
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
|
|
|
|
xpos := round(hwide * ( (Xmean - Xmin) / (Xmax - Xmin)));
|
|
xpos := xpos + hleft;
|
|
ypos := vtop;
|
|
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
|
|
ypos := vbottom;
|
|
BlankFrm.Image1.Canvas.Pen.Color := clGreen;
|
|
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
|
|
Title := 'MEAN ';
|
|
Title := Title + XEdit.Text;
|
|
strhi := BlankFrm.Image1.Canvas.TextWidth(Title);
|
|
xpos := xpos - strhi div 2;
|
|
ypos := vtop - BlankFrm.Image1.Canvas.TextHeight(Title);
|
|
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
|
|
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
|
|
end;
|
|
|
|
// draw slope line
|
|
if LineChk.Checked then
|
|
begin
|
|
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
|
|
Yvalue := (Xpoints[0] * slope) + intercept; // predicted score
|
|
ypos := round(vhi * ( (Ymax - Yvalue) / (Ymax - Ymin)));
|
|
ypos := ypos + vtop;
|
|
xpos := round(hwide * ( (Xpoints[0]- Xmin) / (Xmax - Xmin)));
|
|
xpos := xpos + hleft;
|
|
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
|
|
Yvalue := (Xpoints[N-1] * slope) + intercept; // predicted score
|
|
ypos := round(vhi * ( (Ymax - Yvalue) / (Ymax - Ymin)));
|
|
ypos := ypos + vtop;
|
|
xpos := round(hwide * ( (Xpoints[N-1] - Xmin) / (Xmax - Xmin)));
|
|
xpos := xpos + hleft;
|
|
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
|
|
end;
|
|
|
|
// draw horizontal axis
|
|
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
|
|
BlankFrm.Image1.Canvas.MoveTo(hleft,vbottom);
|
|
BlankFrm.Image1.Canvas.LineTo(hright,vbottom);
|
|
valincr := (Xmax - Xmin) / 10.0;
|
|
for i := 1 to 11 do
|
|
begin
|
|
ypos := vbottom;
|
|
Xvalue := Xmin + valincr * (i - 1);
|
|
xpos := round(hwide * ((Xvalue - Xmin) / (Xmax - Xmin)));
|
|
xpos := xpos + hleft;
|
|
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
|
|
ypos := ypos + 10;
|
|
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
|
|
Title := format('%.2f',[Xvalue]);
|
|
offset := BlankFrm.Image1.Canvas.TextWidth(Title) div 2;
|
|
xpos := xpos - offset;
|
|
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
|
|
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
|
|
end;
|
|
if PlotNo = 1 then
|
|
begin
|
|
xpos := hleft + (hwide div 2) - (BlankFrm.Image1.Canvas.TextWidth(XEdit.Text) div 2);
|
|
ypos := vbottom + 20;
|
|
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,XEdit.Text);
|
|
Title := format('R(X,Y) = %.3f, Slope = %.2f, Intercept = %.2f',
|
|
[R,Slope,Intercept]);
|
|
xpos := hleft + (hwide div 2) - (BlankFrm.Image1.Canvas.TextWidth(Title) div 2);
|
|
ypos := ypos + 15;
|
|
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
|
|
end;
|
|
|
|
// Draw vertical axis
|
|
Title := YEdit.Text;
|
|
xpos := hleft - BlankFrm.Image1.Canvas.TextWidth(Title) div 2;
|
|
ypos := vtop - BlankFrm.Image1.Canvas.TextHeight(Title) - 10;
|
|
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,YEdit.Text);
|
|
xpos := hleft;
|
|
ypos := vtop;
|
|
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
|
|
ypos := vbottom;
|
|
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
|
|
valincr := (Ymax - Ymin) / 10.0;
|
|
for i := 1 to 11 do
|
|
begin
|
|
Title := format('%.2f',[Ymax - ((i-1)*valincr)]);
|
|
strhi := BlankFrm.Image1.Canvas.TextHeight(Title);
|
|
xpos := hLeft - 20 - BlankFrm.Image1.Canvas.TextWidth(Title); //10;
|
|
Yvalue := Ymax - (valincr * (i-1));
|
|
ypos := round(vhi * ( (Ymax - Yvalue) / (Ymax - Ymin)));
|
|
ypos := ypos + vtop - strhi div 2;
|
|
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
|
|
xpos := hleft;
|
|
ypos := ypos + strhi div 2;
|
|
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
|
|
xpos := hleft - 10;
|
|
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
|
|
end;
|
|
|
|
// draw points for x and y pairs
|
|
for i := 0 to N-1 do
|
|
begin
|
|
ypos := round(vhi * ( (Ymax - Ypoints[i]) / (Ymax - Ymin)));
|
|
ypos := ypos + vtop;
|
|
xpos := round(hwide * ( (Xpoints[i] - Xmin) / (Xmax - Xmin)));
|
|
xpos := xpos + hleft;
|
|
BlankFrm.Image1.Canvas.Brush.Color := clYellow;
|
|
BlankFrm.Image1.Canvas.Brush.Style := bsSolid;
|
|
BlankFrm.Image1.Canvas.Pen.Color := clNavy;
|
|
BlankFrm.Image1.Canvas.Ellipse(xpos,ypos,xpos+5,ypos+5);
|
|
if ((PlotNo = 2) and (i = 0)) then
|
|
begin
|
|
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
|
|
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,'M1');
|
|
end;
|
|
if ((PlotNo = 2) and (i > 0)) then
|
|
begin
|
|
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
|
|
Title := format('M%d',[i+1]);
|
|
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
|
|
end;
|
|
end;
|
|
if ((PlotNo = 2) and (i > 0)) then
|
|
begin // draw slope line
|
|
BlankFrm.Image1.Canvas.Pen.Color := clRed;
|
|
ypos := round(vhi * ( (Ymax - Ypoints[0]) / (Ymax - Ymin)));
|
|
ypos := ypos + vtop;
|
|
xpos := round(hwide * ( (Xpoints[0] - Xmin) / (Xmax - Xmin)));
|
|
xpos := xpos + hleft;
|
|
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
|
|
YL := Ypoints[0];
|
|
XL := xpoints[0];
|
|
ypos := round(vhi * ( (Ymax - Ypoints[2]) / (Ymax - Ymin)));
|
|
ypos := ypos + vtop;
|
|
xpos := round(hwide * ( (Xpoints[2] - Xmin) / (Xmax - Xmin)));
|
|
xpos := xpos + hleft;
|
|
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
|
|
YU := Ypoints[2];
|
|
XU := xpoints[2];
|
|
slope := (YU - YL) / (XU - XL);
|
|
ypos := vbottom + 20;
|
|
BlankFrm.Image1.Canvas.Brush.Color := clYellow;
|
|
Title := format('Slope = %.2f',[Slope]);
|
|
xpos := hleft + (hwide div 2) - (BlankFrm.Image1.Canvas.TextWidth(Title) div 2);
|
|
ypos := ypos + 15;
|
|
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
|
|
end;
|
|
|
|
// draw confidence bands if requested
|
|
if ConfBand <> 0.0 then
|
|
begin
|
|
BlankFrm.Image1.Canvas.Pen.Color := clRed;
|
|
ypos := round(vhi * ((Ymax - UpConf[1]) / (Ymax - Ymin)));
|
|
ypos := ypos + vtop;
|
|
xpos := round(hwide * ( (Xpoints[0] - Xmin) / (Xmax - Xmin)));
|
|
xpos := xpos + hleft;
|
|
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
|
|
for i := 2 to N do
|
|
begin
|
|
ypos := round(vhi * ((Ymax - UpConf[i]) / (Ymax - Ymin)));
|
|
ypos := ypos + vtop;
|
|
xpos := round(hwide * ( (Xpoints[i-1] - Xmin) / (Xmax - Xmin)));
|
|
xpos := xpos + hleft;
|
|
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
|
|
end;
|
|
ypos := round(vhi * ((Ymax - lowConf[1]) / (Ymax - Ymin)));
|
|
ypos := ypos + vtop;
|
|
xpos := round(hwide * ( (Xpoints[0] - Xmin) / (Xmax - Xmin)));
|
|
xpos := xpos + hleft;
|
|
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
|
|
for i := 2 to N do
|
|
begin
|
|
ypos := round(vhi * ((Ymax - lowConf[i]) / (Ymax - Ymin)));
|
|
ypos := ypos + vtop;
|
|
xpos := round(hwide * ( (Xpoints[i-1] - Xmin) / (Xmax - Xmin)));
|
|
xpos := xpos + hleft;
|
|
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
|
|
end;
|
|
end;
|
|
BlankFrm.ShowModal;
|
|
end;
|
|
|
|
procedure TResistanceLineForm.UpdateBtnStates;
|
|
begin
|
|
XInBtn.Enabled := (VarList.ItemIndex > -1) and (XEdit.Text = '');
|
|
YInBtn.Enabled := (VarList.ItemIndex > -1) and (YEdit.Text = '');
|
|
XOutBtn.Enabled := (XEdit.Text <> '');
|
|
YOutBtn.Enabled := (YEdit.Text <> '');
|
|
end;
|
|
|
|
procedure TResistanceLineForm.VarListSelectionChange(Sender: TObject;
|
|
User: boolean);
|
|
begin
|
|
UpdateBtnStates;
|
|
end;
|
|
|
|
initialization
|
|
{$I resistancelineunit.lrs}
|
|
|
|
end.
|
|
|