LazStats: Refactor PlotXYUnit to use Calc_BivariateRegression()
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7758 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
3cf0e45644
commit
7f6ad8982a
@ -264,7 +264,7 @@
|
||||
<Unit20>
|
||||
<Filename Value="forms\analysis\descriptive\plotxyunit.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="PlotXYFrm"/>
|
||||
<ComponentName Value="PlotXYForm"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<UnitName Value="PlotXYUnit"/>
|
||||
|
@ -1,4 +1,4 @@
|
||||
inherited PlotXYFrm: TPlotXYFrm
|
||||
inherited PlotXYForm: TPlotXYForm
|
||||
Left = 427
|
||||
Height = 500
|
||||
Top = 175
|
||||
|
@ -8,15 +8,15 @@ interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
|
||||
StdCtrls, ExtCtrls, Buttons, ComCtrls,
|
||||
MainUnit, Globals, FunctionsLib, BasicStatsReportAndChartFormUnit,
|
||||
StdCtrls, ExtCtrls, Buttons, ComCtrls, Grids,
|
||||
MainUnit, Globals, MathUnit, BasicStatsReportAndChartFormUnit,
|
||||
ReportFrameUnit, ChartFrameUnit;
|
||||
|
||||
type
|
||||
|
||||
{ TPlotXYFrm }
|
||||
{ TPlotXYForm }
|
||||
|
||||
TPlotXYFrm = class(TBasicStatsReportAndChartForm)
|
||||
TPlotXYForm = class(TBasicStatsReportAndChartForm)
|
||||
ConfEdit: TEdit;
|
||||
Label4: TLabel;
|
||||
LineChk: TCheckBox;
|
||||
@ -41,15 +41,20 @@ type
|
||||
procedure YOutBtnClick(Sender: TObject);
|
||||
|
||||
private
|
||||
procedure PlotXY(XPoints, YPoints, UpConf, LowConf: DblDyneVec;
|
||||
XMean, YMean, R, Slope, Intercept: Double);
|
||||
procedure PlotXY(XPoints, YPoints: DblDyneVec;
|
||||
const ARegressionResults: TBivariateRegressionResults);
|
||||
|
||||
function PrepareData(ADataGrid: TStringGrid;
|
||||
out xCol, ycol: Integer; out XData, YData: DblDyneVec;
|
||||
out ColNoSelected: IntDyneVec): Boolean;
|
||||
|
||||
procedure WriteToReport(ARegressionResults: TBivariateRegressionResults);
|
||||
|
||||
protected
|
||||
procedure AdjustConstraints; override;
|
||||
procedure Compute; override;
|
||||
procedure UpdateBtnStates; override;
|
||||
function Validate(out AMsg: String; out AControl: TWinControl;
|
||||
Xcol,Ycol: Integer): Boolean; reintroduce;
|
||||
function Validate(out AMsg: String; out AControl: TWinControl): Boolean; override;
|
||||
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
@ -57,7 +62,8 @@ type
|
||||
end;
|
||||
|
||||
var
|
||||
PlotXYFrm: TPlotXYFrm;
|
||||
PlotXYForm: TPlotXYForm;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
@ -65,12 +71,12 @@ implementation
|
||||
|
||||
uses
|
||||
TAChartUtils, TAChartAxisUtils, TALegend, TASources, TACustomSeries, TASeries,
|
||||
MathUnit, GridProcs, Utils;
|
||||
GridProcs, Utils;
|
||||
|
||||
|
||||
{ TPlotXYFrm }
|
||||
{ TPlotXYForm }
|
||||
|
||||
constructor TPlotXYFrm.Create(AOwner: TComponent);
|
||||
constructor TPlotXYForm.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited;
|
||||
|
||||
@ -98,7 +104,7 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TPlotXYFrm.AdjustConstraints;
|
||||
procedure TPlotXYForm.AdjustConstraints;
|
||||
begin
|
||||
ParamsPanel.Constraints.MinHeight := OptionsGroup.Top + OptionsGroup.Height +
|
||||
OptionsGroup.BorderSpacing.Bottom + ButtonBevel.Height +
|
||||
@ -110,26 +116,19 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TPlotXYFrm.Compute;
|
||||
procedure TPlotXYForm.Compute;
|
||||
var
|
||||
xMean, yMean, xVariance, yVariance, xStddev, yStddev: double;
|
||||
SXX, SXY, SYY, R, slope, intercept, t, confBand: Double;
|
||||
sePred, predicted, sedata: double;
|
||||
i, xCol, yCol, N, DF: integer;
|
||||
xValues: DblDyneVec = nil;
|
||||
yValues: DblDyneVec = nil;
|
||||
UpConf: DblDyneVec = nil;
|
||||
lowConf: DblDyneVec = nil;
|
||||
ColNoSelected: IntDyneVec= nil;
|
||||
xCol, yCol: Integer;
|
||||
confBand: Double;
|
||||
regressionRes: TBivariateRegressionResults;
|
||||
C: TWinControl;
|
||||
msg: String;
|
||||
lReport: TStrings;
|
||||
begin
|
||||
xCol := OS3MainFrm.DataGrid.Rows[0].IndexOf(XEdit.Text);
|
||||
yCol := OS3MainFrm.DataGrid.Rows[0].IndexOf(YEdit.Text);
|
||||
|
||||
// Validation
|
||||
if not Validate(msg, C, Xcol, Ycol) then
|
||||
// Validation: Make sure that XEdit and YEdit are not empty
|
||||
if not Validate(msg, C) then
|
||||
begin
|
||||
C.SetFocus;
|
||||
ErrorMsg(msg);
|
||||
@ -137,99 +136,36 @@ begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
SetLength(ColNoSelected, 2);
|
||||
ColNoSelected[0] := Xcol;
|
||||
ColNoSelected[1] := Ycol;
|
||||
|
||||
xValues := CollectValues(OS3MainFrm.DataGrid, xCol, ColNoSelected);
|
||||
yValues := CollectValues(OS3MainFrm.DataGrid, yCol, ColNoSelected);
|
||||
if (Length(yValues) = 0) then
|
||||
begin
|
||||
ErrorMsg('No y data');
|
||||
// Extract data from Grid
|
||||
if not PrepareData(OS3MainFrm.DataGrid, xCol, yCol, xValues, yValues, ColNoSelected) then
|
||||
exit;
|
||||
end;
|
||||
if (Length(xValues) <> Length(yValues)) then
|
||||
begin
|
||||
ErrorMsg('Different count of x and y values.');
|
||||
exit;
|
||||
end;
|
||||
N := Length(yValues);
|
||||
|
||||
Calc_MeanVarStddevSS(xValues, xMean, xVariance, xStdDev, SXX);
|
||||
Calc_MeanVarStddevSS(yValues, yMean, yVariance, yStdDev, SYY);
|
||||
SXY := 0;
|
||||
for i := 0 to N-1 do
|
||||
SXY := SXY + xValues[i] * yValues[i];
|
||||
// Sort on x values
|
||||
SortOnX(xValues, yValues);
|
||||
|
||||
R := (SXY - xMean * yMean * N) / ((N - 1) * xStdDev * yStdDev);
|
||||
sePred := sqrt(1.0 - sqr(R)) * yStdDev * sqrt((N - 1) / (N - 2));
|
||||
slope := R * yStdDev / xStdDev;
|
||||
intercept := yMean - slope * xMean;
|
||||
// Calculate regression
|
||||
confBand := StrToFloat(ConfEdit.Text) / 100.0;
|
||||
Calc_BivariateRegression(xValues, yValues, confBand, regressionRes);
|
||||
|
||||
// Print the descriptive statistics to the output frame
|
||||
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;
|
||||
end;
|
||||
|
||||
// Get upper and lower confidence points for each X value
|
||||
if ConfChk.Checked then
|
||||
begin
|
||||
SortOnX(xValues, yValues);
|
||||
|
||||
SetLength(UpConf, N);
|
||||
SetLength(lowConf, N);
|
||||
|
||||
confBand := StrToFloat(ConfEdit.Text) / 100.0;
|
||||
DF := N - 2;
|
||||
t := InverseT(confBand, DF);
|
||||
for i := 0 to N-1 do
|
||||
begin
|
||||
predicted := intercept + slope * xValues[i];
|
||||
seData := sePred * sqrt(1.0 + 1/N + sqr(xValues[i] - XMean) / SXX);
|
||||
upConf[i] := predicted + t * seData;
|
||||
lowConf[i] := predicted - t * seData;
|
||||
end;
|
||||
end
|
||||
else
|
||||
confBand := 0.0;
|
||||
WriteToReport(regressionRes);
|
||||
|
||||
// Plot the values (and optional line and confidence band if elected)
|
||||
PlotXY(xValues, yValues, upConf, lowConf, xMean, yMean, R, slope, intercept);
|
||||
PlotXY(xValues, yValues, regressionRes);
|
||||
end;
|
||||
|
||||
|
||||
procedure TPlotXYFrm.PlotXY(XPoints, YPoints, UpConf, LowConf: DblDyneVec;
|
||||
XMean, YMean, R, Slope, Intercept: Double);
|
||||
procedure TPlotXYForm.PlotXY(XPoints, YPoints: DblDyneVec;
|
||||
const ARegressionResults: TBivariateRegressionResults);
|
||||
var
|
||||
tmpX: array of Double = nil;
|
||||
tmpY: array of Double = nil;
|
||||
tmpX: DblDyneVec = nil;
|
||||
tmpY: DblDyneVec = nil;
|
||||
conf: DblDyneVec = nil;
|
||||
xmin, xmax, ymin, ymax: Double;
|
||||
rightLabels: TListChartSource;
|
||||
topLabels: TListChartSource;
|
||||
ser: TChartSeries;
|
||||
i: Integer;
|
||||
begin
|
||||
rightLabels := FChartFrame.Chart.AxisList[2].Marks.Source as TListChartSource;
|
||||
rightLabels.Clear;
|
||||
@ -239,16 +175,20 @@ begin
|
||||
|
||||
// Titles
|
||||
FChartFrame.SetTitle('X vs. Y plot using file ' + OS3MainFrm.FileNameEdit.Text);
|
||||
FChartFrame.SetFooter(Format('R(X,Y) = %.3f, Slope = %.3f, Intercept = %.3f', [
|
||||
R, Slope, Intercept
|
||||
]));
|
||||
with ARegressionResults do
|
||||
FChartFrame.SetFooter(Format('R(X,Y) = %.3f, Slope = %.3f, Intercept = %.3f', [
|
||||
R, Slope, Intercept
|
||||
]));
|
||||
FChartFrame.SetXTitle(XEdit.Text);
|
||||
FChartFrame.SetYTitle(YEdit.Text);
|
||||
|
||||
// Draw upper confidence band
|
||||
if ConfChk.Checked then
|
||||
begin
|
||||
ser := FChartFrame.PlotXY(ptLines, XPoints, UpConf, nil, nil, 'Upper confidence band', clRed);
|
||||
SetLength(conf, ARegressionResults.Count);
|
||||
for i := 0 to High(conf) do
|
||||
conf[i] := ARegressionResults.ConfidenceLimits(XPoints[i], true);
|
||||
ser := FChartFrame.PlotXY(ptLines, XPoints, conf, nil, nil, 'Upper confidence band', clRed);
|
||||
rightLabels.Add(ser.yValue[ser.Count-1], ser.YValue[ser.Count-1], 'UCL');
|
||||
end;
|
||||
|
||||
@ -258,7 +198,10 @@ begin
|
||||
// Draw lower confidence band
|
||||
if ConfChk.Checked then
|
||||
begin
|
||||
ser := FChartFrame.PlotXY(ptLines, XPoints, LowConf, nil, nil, 'Lower confidence band', clRed);
|
||||
SetLength(conf, ARegressionResults.Count);
|
||||
for i := 0 to High(conf) do
|
||||
conf[i] := ARegressionResults.ConfidenceLimits(XPoints[i], false);
|
||||
ser := FChartFrame.PlotXY(ptLines, XPoints, conf, nil, nil, 'Lower confidence band', clRed);
|
||||
rightLabels.Add(ser.yValue[ser.Count-1], ser.YValue[ser.Count-1], 'LCL');
|
||||
end;
|
||||
|
||||
@ -268,19 +211,26 @@ begin
|
||||
|
||||
// Draw means
|
||||
if MeansChk.Checked then
|
||||
begin
|
||||
FChartFrame.VertLine(XMean, clGreen, psDashDot, 'Mean ' + XEdit.Text);
|
||||
topLabels.Add(XMean, XMean, 'Mean ' + XEdit.Text);
|
||||
FChartFrame.HorLine(YMean, clGreen, psDash, 'Mean ' + YEdit.Text);
|
||||
rightLabels.Add(YMean, YMean, 'Mean ' + YEdit.Text);
|
||||
end;
|
||||
with ARegressionResults do
|
||||
begin
|
||||
FChartFrame.VertLine(XMean, clGreen, psDashDot, 'Mean ' + XEdit.Text);
|
||||
topLabels.Add(XMean, XMean, 'Mean ' + XEdit.Text);
|
||||
FChartFrame.HorLine(YMean, clGreen, psDash, 'Mean ' + YEdit.Text);
|
||||
rightLabels.Add(YMean, YMean, 'Mean ' + YEdit.Text);
|
||||
end;
|
||||
|
||||
// Draw regression line
|
||||
if LineChk.Checked then
|
||||
begin
|
||||
SetLength(tmpX, 2); SetLength(tmpY, 2);
|
||||
tmpX[0] := xmin; tmpY[0] := tmpX[0] * slope + intercept;
|
||||
tmpX[1] := xmax; tmpY[1] := tmpX[1] * slope + intercept;
|
||||
SetLength(tmpX, 2);
|
||||
SetLength(tmpY, 2);
|
||||
tmpX[0] := xmin;
|
||||
tmpX[1] := xmax;
|
||||
with ARegressionResults do
|
||||
begin
|
||||
tmpY[1] := tmpX[1] * Slope + Intercept;
|
||||
tmpY[0] := tmpX[0] * Slope + Intercept;
|
||||
end;
|
||||
ser := FChartFrame.PlotXY(ptLines, tmpX, tmpY, nil, nil, 'Predicted', clBlack);
|
||||
rightLabels.Add(tmpY[1], tmpY[1], 'Predicted');
|
||||
end;
|
||||
@ -289,67 +239,110 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TPlotXYfrm.Reset;
|
||||
function TPlotXYForm.PrepareData(ADataGrid: TStringGrid;
|
||||
out xCol, ycol: Integer; out XData, YData: DblDyneVec;
|
||||
out ColNoSelected: IntDyneVec): Boolean;
|
||||
var
|
||||
N: Integer;
|
||||
begin
|
||||
Result := false;
|
||||
|
||||
ColNoSelected := nil;
|
||||
XData := nil;
|
||||
YData := nil;
|
||||
|
||||
xCol := GetVariableIndex(ADataGrid, XEdit.Text);
|
||||
yCol := GetVariableIndex(ADataGrid, YEdit.Text);
|
||||
if xCol = -1 then
|
||||
begin
|
||||
ErrorMsg('X variable not found.');
|
||||
exit;
|
||||
end;
|
||||
|
||||
if yCol = -1 then
|
||||
begin
|
||||
ErrorMsg('Y variable not found.');
|
||||
exit;
|
||||
end;
|
||||
|
||||
SetLength(ColNoSelected, 2);
|
||||
ColNoSelected[0] := xCol;
|
||||
ColNoSelected[1] := yCol;
|
||||
|
||||
XData := CollectValues(ADataGrid, xCol, colNoSelected);
|
||||
YData := CollectValues(ADataGrid, ycol, colNoSelected);
|
||||
N := Length(XData);
|
||||
if N < 3 then
|
||||
begin
|
||||
ErrorMsg('At least three data points required.');
|
||||
exit;
|
||||
end;
|
||||
if N <> Length(YData) then
|
||||
begin
|
||||
ErrorMsg('Equal count of cases required for x and y variables.');
|
||||
exit;
|
||||
end;
|
||||
|
||||
Result := true;
|
||||
end;
|
||||
|
||||
|
||||
procedure TPlotXYForm.Reset;
|
||||
var
|
||||
i: integer;
|
||||
begin
|
||||
inherited;
|
||||
|
||||
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]);
|
||||
|
||||
if Assigned(FChartFrame) then
|
||||
FChartFrame.Clear;
|
||||
if Assigned(FReportFrame) then
|
||||
FReportFrame.Clear;
|
||||
|
||||
UpdateBtnStates;
|
||||
end;
|
||||
|
||||
|
||||
procedure TPlotXYFrm.UpdateBtnStates;
|
||||
procedure TPlotXYForm.UpdateBtnStates;
|
||||
begin
|
||||
inherited;
|
||||
|
||||
XInBtn.Enabled := (VarList.ItemIndex > -1) and (XEdit.Text = '');
|
||||
XoutBtn.Enabled := (XEdit.Text <> '');
|
||||
|
||||
YinBtn.Enabled := (VarList.ItemIndex > -1) and (YEdit.Text = '');
|
||||
YoutBtn.Enabled := (YEdit.Text <> '');
|
||||
|
||||
if Assigned(FReportFrame) then
|
||||
FReportFrame.UpdateBtnStates;
|
||||
if Assigned(FChartFrame) then
|
||||
FChartFrame.UpdateBtnStates;
|
||||
end;
|
||||
|
||||
|
||||
function TPlotXYFrm.Validate(out AMsg: String; out AControl: TWinControl;
|
||||
Xcol, Ycol: Integer): Boolean;
|
||||
function TPlotXYForm.Validate(out AMsg: String; out AControl: TWinControl): Boolean;
|
||||
begin
|
||||
Result := false;
|
||||
|
||||
if (Xcol < 0) then
|
||||
if XEdit.Text = '' then
|
||||
begin
|
||||
AControl := XEdit;
|
||||
AMsg := 'No case selected for X.';
|
||||
AMsg := 'No variable selected for X.';
|
||||
exit;
|
||||
end;
|
||||
|
||||
if (Ycol < 0) then
|
||||
if YEdit.Text = '' then
|
||||
begin
|
||||
AControl := YEdit;
|
||||
AMsg := 'No case selected for Y.';
|
||||
AMsg := 'No variable selected for Y.';
|
||||
exit;
|
||||
end;
|
||||
|
||||
Result := true;
|
||||
end;
|
||||
|
||||
|
||||
procedure TPlotXYFrm.VarListDblClick(Sender: TObject);
|
||||
procedure TPlotXYForm.VarListDblClick(Sender: TObject);
|
||||
var
|
||||
index: integer;
|
||||
begin
|
||||
@ -366,13 +359,49 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TPlotXYFrm.VarListSelectionChange(Sender: TObject; User: boolean);
|
||||
procedure TPlotXYForm.VarListSelectionChange(Sender: TObject; User: boolean);
|
||||
begin
|
||||
UpdateBtnStates;
|
||||
end;
|
||||
|
||||
|
||||
procedure TPlotXYFrm.XInBtnClick(Sender: TObject);
|
||||
procedure TPlotXYForm.WriteToReport(ARegressionResults: TBivariateRegressionResults);
|
||||
var
|
||||
lReport: TStrings;
|
||||
begin
|
||||
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('---------- -------- -------- --------');
|
||||
with ARegressionResults do
|
||||
begin
|
||||
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', [StdErrorPredicted]);
|
||||
lReport.Add(' Number of good cases: %8d', [Count]);
|
||||
end;
|
||||
|
||||
FReportFrame.DisplayReport(lReport);
|
||||
finally
|
||||
lReport.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TPlotXYForm.XInBtnClick(Sender: TObject);
|
||||
var
|
||||
index: integer;
|
||||
begin
|
||||
@ -386,7 +415,7 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TPlotXYFrm.XOutBtnClick(Sender: TObject);
|
||||
procedure TPlotXYForm.XOutBtnClick(Sender: TObject);
|
||||
begin
|
||||
if XEdit.Text <> '' then
|
||||
begin
|
||||
@ -397,7 +426,7 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TPlotXYFrm.YInBtnClick(Sender: TObject);
|
||||
procedure TPlotXYForm.YInBtnClick(Sender: TObject);
|
||||
var
|
||||
index: integer;
|
||||
begin
|
||||
@ -411,7 +440,7 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TPlotXYFrm.YOutBtnClick(Sender: TObject);
|
||||
procedure TPlotXYForm.YOutBtnClick(Sender: TObject);
|
||||
begin
|
||||
if YEdit.Text <> '' then
|
||||
begin
|
||||
|
@ -19,7 +19,7 @@ object OS3MainFrm: TOS3MainFrm
|
||||
OnCreate = FormCreate
|
||||
OnDestroy = FormDestroy
|
||||
OnShow = FormShow
|
||||
LCLVersion = '2.0.10.0'
|
||||
LCLVersion = '2.1.0.0'
|
||||
object Panel1: TPanel
|
||||
Left = 0
|
||||
Height = 35
|
||||
|
@ -2071,9 +2071,9 @@ end;
|
||||
// Menu "Analysis" > "Descriptive" > "Plot X vs Y"
|
||||
procedure TOS3MainFrm.mnuAnalysisDescr_PlotXvsYClick(Sender: TObject);
|
||||
begin
|
||||
if PlotXYFrm = nil then
|
||||
Application.CreateForm(TPlotXYFrm, PlotXYFrm);
|
||||
PlotXYFrm.Show;
|
||||
if PlotXYForm = nil then
|
||||
Application.CreateForm(TPlotXYForm, PlotXYForm);
|
||||
PlotXYForm.Show;
|
||||
end;
|
||||
|
||||
procedure TOS3MainFrm.mnuAnalysisDescr_ResistanceLineClick(Sender: TObject);
|
||||
|
Loading…
Reference in New Issue
Block a user