You've already forked lazarus-ccr
427 lines
14 KiB
ObjectPascal
427 lines
14 KiB
ObjectPascal
![]() |
unit MultXvsYUnit;
|
||
|
|
||
|
{$mode objfpc}{$H+}
|
||
|
|
||
|
interface
|
||
|
|
||
|
uses
|
||
|
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
|
||
|
StdCtrls, Buttons, MainUnit, Globals, functionsLib, OutPutUnit, DataProcs,
|
||
|
DictionaryUnit, Math, Clipbrd, contexthelpunit;
|
||
|
|
||
|
|
||
|
type
|
||
|
|
||
|
{ TMultXvsYFrm }
|
||
|
|
||
|
TMultXvsYFrm = class(TForm)
|
||
|
HelpBtn: TButton;
|
||
|
XInBtn: TBitBtn;
|
||
|
XOutBtn: TBitBtn;
|
||
|
YInBtn: TBitBtn;
|
||
|
YOutBtn: TBitBtn;
|
||
|
GroupInBtn: TBitBtn;
|
||
|
GroupOutBtn: TBitBtn;
|
||
|
ResetBtn: TButton;
|
||
|
CancelBtn: TButton;
|
||
|
ComputeBtn: TButton;
|
||
|
ReturnBtn: TButton;
|
||
|
DescChk: TCheckBox;
|
||
|
LinesChk: TCheckBox;
|
||
|
XEdit: TEdit;
|
||
|
YEdit: TEdit;
|
||
|
GroupEdit: TEdit;
|
||
|
GroupBox1: TGroupBox;
|
||
|
LabelEdit: TEdit;
|
||
|
Label1: TLabel;
|
||
|
Label2: TLabel;
|
||
|
Label3: TLabel;
|
||
|
Label4: TLabel;
|
||
|
Label5: TLabel;
|
||
|
VarList: TListBox;
|
||
|
procedure ComputeBtnClick(Sender: TObject);
|
||
|
procedure FormShow(Sender: TObject);
|
||
|
procedure GroupInBtnClick(Sender: TObject);
|
||
|
procedure GroupOutBtnClick(Sender: TObject);
|
||
|
procedure HelpBtnClick(Sender: TObject);
|
||
|
procedure ResetBtnClick(Sender: TObject);
|
||
|
procedure XInBtnClick(Sender: TObject);
|
||
|
procedure XOutBtnClick(Sender: TObject);
|
||
|
procedure YInBtnClick(Sender: TObject);
|
||
|
procedure YOutBtnClick(Sender: TObject);
|
||
|
private
|
||
|
{ private declarations }
|
||
|
procedure plotxy(var XValues : DblDyneMat;
|
||
|
YValues : DblDyneMat;
|
||
|
MaxX, MinX, MaxY, MinY : double;
|
||
|
N, NoY, MinGrp : integer);
|
||
|
|
||
|
public
|
||
|
{ public declarations }
|
||
|
end;
|
||
|
|
||
|
var
|
||
|
MultXvsYFrm: TMultXvsYFrm;
|
||
|
|
||
|
implementation
|
||
|
uses BlankFrmUnit;
|
||
|
|
||
|
{ TMultXvsYFrm }
|
||
|
|
||
|
procedure TMultXvsYFrm.ResetBtnClick(Sender: TObject);
|
||
|
VAR i : integer;
|
||
|
begin
|
||
|
VarList.Clear;
|
||
|
for i := 1 to NoVariables do
|
||
|
VarList.Items.Add(OS3MainFrm.DataGrid.Cells[i,0]);
|
||
|
XEdit.Text := '';
|
||
|
YEdit.Text := '';
|
||
|
GroupEdit.Text := '';
|
||
|
DescChk.Checked := false;
|
||
|
LinesChk.Checked := false;
|
||
|
XInBtn.Visible := true;
|
||
|
YInBtn.Visible := true;
|
||
|
GroupInBtn.Visible := true;
|
||
|
XOutBtn.Visible := false;
|
||
|
YOutBtn.Visible := false;
|
||
|
GroupOutBtn.Visible := false;
|
||
|
end;
|
||
|
|
||
|
procedure TMultXvsYFrm.GroupInBtnClick(Sender: TObject);
|
||
|
VAR i : integer;
|
||
|
begin
|
||
|
i := VarList.ItemIndex;
|
||
|
GroupEdit.Text := VarList.Items.Strings[i];
|
||
|
VarList.Items.Delete(i);
|
||
|
GroupInBtn.Visible := false;
|
||
|
GroupOutBtn.Visible := true;
|
||
|
end;
|
||
|
|
||
|
procedure TMultXvsYFrm.ComputeBtnClick(Sender: TObject);
|
||
|
var
|
||
|
i, j, k, N, NoGrps, XCol, YCol, GrpCol, Grp, MinGrp, MaxGrp : integer;
|
||
|
NoSelected, MaxGrpSize : integer;
|
||
|
selected, NoInGrp : IntDyneVec;
|
||
|
YValues, XValues : DblDyneMat;
|
||
|
Means, StdDevs : DblDyneVec;
|
||
|
MinX, MaxX, MinY, MaxY, X, Y, temp : double;
|
||
|
cellstring, prtline : string;
|
||
|
|
||
|
begin
|
||
|
MaxGrpSize := 0;
|
||
|
SetLength(selected,3);
|
||
|
MaxX := -1.0e20;
|
||
|
MinX := 1.0e20;
|
||
|
MaxY := -1.0e20;
|
||
|
MinY := 1.0e20;
|
||
|
MinGrp := 1000;
|
||
|
MaxGrp := -1000;
|
||
|
N:=0;
|
||
|
|
||
|
// Get selected variables
|
||
|
for i := 1 to NoVariables do
|
||
|
begin
|
||
|
cellstring := OS3MainFrm.DataGrid.Cells[i,0];
|
||
|
if (cellstring = XEdit.Text) then selected[0] := i;
|
||
|
if (cellstring = YEdit.Text) then selected[1] := i;
|
||
|
if (cellstring = GroupEdit.Text) then selected[2] := i;
|
||
|
end;
|
||
|
XCol := selected[0];
|
||
|
YCol := selected[1];
|
||
|
GrpCol := selected[2];
|
||
|
NoSelected := 3;
|
||
|
|
||
|
// Get number of groups
|
||
|
for i := 1 to NoCases do
|
||
|
begin
|
||
|
Grp := StrToInt(OS3MainFrm.DataGrid.Cells[GrpCol,i]);
|
||
|
if (Grp > MaxGrp) then MaxGrp := Grp;
|
||
|
if (Grp < MinGrp) then MinGrp := Grp;
|
||
|
end;
|
||
|
NoGrps := (MaxGrp - MinGrp) + 1;
|
||
|
|
||
|
OutPutFrm.RichEdit.Clear;
|
||
|
OutPutFrm.RichEdit.Lines.Add('X VERSUS Y FOR GROUPS PLOT');
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
SetLength(YValues,NoCases+1,NoGrps+1);
|
||
|
SetLength(XValues,NoCases+1,NoGrps+1);
|
||
|
SetLength(Means,2);
|
||
|
SetLength(StdDevs,2);
|
||
|
SetLength(NoInGrp,NoGrps);
|
||
|
|
||
|
for i := 0 to 1 do
|
||
|
begin
|
||
|
Means[i] := 0.0;
|
||
|
StdDevs[i] := 0.0;
|
||
|
end;
|
||
|
for i := 0 to NoGrps - 1 do NoInGrp[i] := 0;
|
||
|
|
||
|
for i := 1 to NoCases do
|
||
|
begin
|
||
|
if (not GoodRecord(i,NoSelected,selected))then continue;
|
||
|
N := N + 1;
|
||
|
X := StrToFloat(OS3MainFrm.DataGrid.Cells[XCol,i]);
|
||
|
if (X > MaxX) then MaxX := X;
|
||
|
if (X < MinX) then MinX := X;
|
||
|
Y := StrToFloat(OS3MainFrm.DataGrid.Cells[YCol,i]);
|
||
|
if (Y > MaxY) then MaxY := Y;
|
||
|
if (Y < MinY) then MinY := Y;
|
||
|
end;
|
||
|
|
||
|
for i := 1 to NoCases do
|
||
|
begin
|
||
|
if (not GoodRecord(i,NoSelected,selected))then continue;
|
||
|
Y := StrToFloat(OS3MainFrm.DataGrid.Cells[YCol,i]);
|
||
|
if (Y > MaxY) then MaxY := Y;
|
||
|
if (Y < MinY) then MinY := Y;
|
||
|
Grp := StrToInt(OS3MainFrm.DataGrid.Cells[GrpCol,i]);
|
||
|
Grp := Grp - MinGrp;
|
||
|
NoInGrp[Grp] := NoInGrp[Grp] + 1;
|
||
|
if (NoInGrp[Grp] > MaxGrpSize) then MaxGrpSize := NoInGrp[Grp];
|
||
|
YValues[NoInGrp[Grp]-1,Grp] := Y;
|
||
|
XValues[NoInGrp[Grp]-1,Grp] := StrToFloat(OS3MainFrm.DataGrid.Cells[XCol,i]);
|
||
|
end;
|
||
|
|
||
|
// get descriptive data
|
||
|
if (DescChk.Checked) then
|
||
|
begin
|
||
|
for i := 1 to NoCases do
|
||
|
begin
|
||
|
if (not GoodRecord(i,NoSelected,selected)) then continue;
|
||
|
Y := StrToFloat(OS3MainFrm.DataGrid.Cells[YCol,i]);
|
||
|
X := StrToFloat(OS3MainFrm.DataGrid.Cells[XCol,i]);
|
||
|
Means[0] := Means[0] + X;
|
||
|
StdDevs[0] := StdDevs[0] + (X * X);
|
||
|
Means[1] := Means[1] + Y;
|
||
|
StdDevs[1] := StdDevs[1] + (Y * Y);
|
||
|
end;
|
||
|
for i := 0 to 1 do
|
||
|
begin
|
||
|
StdDevs[i] := StdDevs[i] - (Means[i] * Means[i]) / N;
|
||
|
StdDevs[i] := StdDevs[i] / (N - 1);
|
||
|
StdDevs[i] := sqrt(StdDevs[i]);
|
||
|
Means[i] := Means[i] / N;
|
||
|
end;
|
||
|
OutPutFrm.RichEdit.Lines.Add('VARIABLE MEAN STANDARED DEVIATION');
|
||
|
prtline := format(' X %9.3f %8.3f',[Means[0],StdDevs[0]]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(prtline);
|
||
|
prtline := format(' Y %9.3f %8.3f',[Means[1],StdDevs[1]]);
|
||
|
OutPutFrm.RichEdit.Lines.Add(prtline);
|
||
|
OutPutFrm.RichEdit.Lines.Add('');
|
||
|
OutPutFrm.ShowModal;
|
||
|
end;
|
||
|
|
||
|
// sort on X
|
||
|
for i := 0 to NoGrps - 1 do
|
||
|
begin
|
||
|
for j := 0 to MaxGrpSize-2 do
|
||
|
begin
|
||
|
for k := j+1 to MaxGrpSize - 1 do
|
||
|
begin
|
||
|
if (XValues[j,i] > XValues[k,i]) then // swap
|
||
|
begin
|
||
|
temp := XValues[j,i];
|
||
|
XValues[j,i] := XValues[k,i];
|
||
|
XValues[k,i] := temp;
|
||
|
temp := YValues[j,i];
|
||
|
YValues[j,i] := YValues[k,i];
|
||
|
YValues[k,i] := temp;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
BlankFrm.Show;
|
||
|
plotxy(XValues, YValues, MaxX, MinX, MaxY, MinY, MaxGrpSize, NoGrps, MinGrp);
|
||
|
|
||
|
NoInGrp := nil;
|
||
|
StdDevs := nil;
|
||
|
Means := nil;
|
||
|
XValues := nil;
|
||
|
YValues := nil;
|
||
|
end;
|
||
|
|
||
|
procedure TMultXvsYFrm.FormShow(Sender: TObject);
|
||
|
begin
|
||
|
ResetBtnClick(self);
|
||
|
end;
|
||
|
|
||
|
procedure TMultXvsYFrm.GroupOutBtnClick(Sender: TObject);
|
||
|
begin
|
||
|
VarList.Items.Add(GroupEdit.Text);
|
||
|
GroupEdit.Text := '';
|
||
|
GroupInBtn.Visible := true;
|
||
|
GroupOutBtn.Visible := false;
|
||
|
end;
|
||
|
|
||
|
procedure TMultXvsYFrm.HelpBtnClick(Sender: TObject);
|
||
|
begin
|
||
|
ContextHelpForm.HelpMessage((Sender as TButton).tag);
|
||
|
end;
|
||
|
|
||
|
procedure TMultXvsYFrm.XInBtnClick(Sender: TObject);
|
||
|
VAR i : integer;
|
||
|
begin
|
||
|
i := VarList.ItemIndex;
|
||
|
XEdit.Text := VarList.Items.Strings[i];
|
||
|
VarList.Items.Delete(i);
|
||
|
XInBtn.Visible := false;
|
||
|
XOutBtn.Visible := true;
|
||
|
end;
|
||
|
|
||
|
procedure TMultXvsYFrm.XOutBtnClick(Sender: TObject);
|
||
|
begin
|
||
|
VarList.Items.Add(XEdit.Text);
|
||
|
XEdit.Text := '';
|
||
|
XInBtn.Visible := true;
|
||
|
XOutBtn.Visible := false;
|
||
|
end;
|
||
|
|
||
|
procedure TMultXvsYFrm.YInBtnClick(Sender: TObject);
|
||
|
VAR i : integer;
|
||
|
begin
|
||
|
i := VarList.ItemIndex;
|
||
|
YEdit.Text := VarList.Items.Strings[i];
|
||
|
VarList.Items.Delete(i);
|
||
|
YInBtn.Visible := false;
|
||
|
YOutBtn.Visible := true;
|
||
|
end;
|
||
|
|
||
|
procedure TMultXvsYFrm.YOutBtnClick(Sender: TObject);
|
||
|
begin
|
||
|
VarList.Items.Add(YEdit.Text);
|
||
|
YEdit.Text := '';
|
||
|
YInBtn.Visible := true;
|
||
|
YOutBtn.Visible := false;
|
||
|
end;
|
||
|
|
||
|
procedure TMultXvsYFrm.plotxy(var XValues : DblDyneMat;
|
||
|
YValues : DblDyneMat;
|
||
|
MaxX, MinX, MaxY, MinY : double;
|
||
|
N, NoY, MinGrp : integer);
|
||
|
var
|
||
|
// routine to plot X versus multiple Y values
|
||
|
xpos, ypos, hleft, hright, vtop, vbottom, imagewide : integer;
|
||
|
vhi, hwide, offset, strhi, imagehi, i, j, k, Grp : integer;
|
||
|
maxval, minval, valincr, Yvalue, Xvalue, value : double;
|
||
|
Title, outline : string;
|
||
|
Colors : array[0..12] of TColor;
|
||
|
begin
|
||
|
Colors[1] := clRed;
|
||
|
Colors[2] := clBlue;
|
||
|
Colors[3] := clGreen;
|
||
|
Colors[4] := clNavy;
|
||
|
Colors[5] := clTeal;
|
||
|
Colors[6] := clAqua;
|
||
|
Colors[7] := clLime;
|
||
|
Colors[8] := clFuchsia;
|
||
|
Colors[9] := clGray;
|
||
|
Colors[10] := clPurple;
|
||
|
Colors[11] := clOlive;
|
||
|
Colors[0] := clMaroon;
|
||
|
Title := LabelEdit.Text;
|
||
|
BlankFrm.Image1.Canvas.Clear;
|
||
|
BlankFrm.Caption := Title;
|
||
|
imagewide := BlankFrm.Image1.Width;
|
||
|
imagehi := BlankFrm.Image1.Height;
|
||
|
// ImageFrm.Image.Canvas.FloodFill(0,0,clWhite,fsBorder);
|
||
|
vtop := 20;
|
||
|
vbottom := ceil(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
|
||
|
// ImageFrm.Image.Canvas.Rectangle(0,0,imagewide,imagehi);
|
||
|
|
||
|
// draw horizontal axis
|
||
|
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
|
||
|
BlankFrm.Image1.Canvas.MoveTo(hleft,vbottom);
|
||
|
BlankFrm.Image1.Canvas.LineTo(hright,vbottom);
|
||
|
valincr := (MaxX - MinX) / 10.0;
|
||
|
for i := 1 to 10 do
|
||
|
begin
|
||
|
ypos := vbottom;
|
||
|
Xvalue := MinX + valincr * (i - 1);
|
||
|
xpos := ceil(hwide * ((Xvalue - MinX) / (MaxX - MinX)));
|
||
|
xpos := xpos + hleft;
|
||
|
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
|
||
|
ypos := ypos + 10;
|
||
|
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
|
||
|
outline := format('%6.2f',[Xvalue]);
|
||
|
Title := outline;
|
||
|
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;
|
||
|
xpos := hleft + (hwide div 2) - (BlankFrm.Image1.Canvas.TextWidth(XEdit.Text) div 2);
|
||
|
ypos := vbottom + 20;
|
||
|
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,XEdit.Text);
|
||
|
|
||
|
// Draw vertical axis
|
||
|
Title := 'Y VALUES';
|
||
|
xpos := hleft - BlankFrm.Image1.Canvas.TextWidth(Title) div 2;
|
||
|
ypos := vtop - BlankFrm.Image1.Canvas.TextHeight(Title);
|
||
|
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
|
||
|
xpos := hleft;
|
||
|
ypos := vtop;
|
||
|
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
|
||
|
ypos := vbottom;
|
||
|
BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
|
||
|
valincr := (MaxY - MinY) / 10.0;
|
||
|
for i := 1 to 10 do
|
||
|
begin
|
||
|
value := MaxY - ((i-1) * valincr);
|
||
|
outline := format('%8.2f',[value]);
|
||
|
Title := outline;
|
||
|
strhi := BlankFrm.Image1.Canvas.TextHeight(Title);
|
||
|
xpos := 10;
|
||
|
Yvalue := MaxY - (valincr * (i-1));
|
||
|
ypos := ceil(vhi * ( (MaxY - Yvalue) / (MaxY - MinY)));
|
||
|
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 j := 0 to NoY - 1 do
|
||
|
begin
|
||
|
BlankFrm.Image1.Canvas.Brush.Style := bsSolid;
|
||
|
BlankFrm.Image1.Canvas.Brush.Color := Colors[j mod 12];
|
||
|
BlankFrm.Image1.Canvas.Pen.Color := Colors[j mod 12];
|
||
|
Grp := MinGrp + j;
|
||
|
Title := 'GROUP ' + IntToStr(Grp);
|
||
|
for i := 1 to N do
|
||
|
begin
|
||
|
ypos := ceil(vhi * ( (MaxY - YValues[i-1,j]) / (MaxY - MinY)));
|
||
|
ypos := ypos + vtop;
|
||
|
xpos := ceil(hwide * ( (XValues[i-1,j] - MinX) / (MaxX - MinX)));
|
||
|
xpos := xpos + hleft;
|
||
|
if (i = 1) then BlankFrm.Image1.Canvas.MoveTo(xpos,ypos);
|
||
|
if (LinesChk.Checked) then BlankFrm.Image1.Canvas.LineTo(xpos,ypos);
|
||
|
BlankFrm.Image1.Canvas.Ellipse(xpos,ypos,xpos+5,ypos+5);
|
||
|
end;
|
||
|
strhi := BlankFrm.Image1.Canvas.TextHeight(Title);
|
||
|
BlankFrm.Image1.Canvas.Brush.Color := clWhite;
|
||
|
BlankFrm.Image1.Canvas.Pen.Color := clBlack;
|
||
|
xpos := hwide + hleft;
|
||
|
BlankFrm.Image1.Canvas.MoveTo(xpos,ypos-strhi);
|
||
|
BlankFrm.Image1.Canvas.TextOut(xpos,ypos,Title);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
initialization
|
||
|
{$I multxvsyunit.lrs}
|
||
|
|
||
|
end.
|
||
|
|