You've already forked lazarus-ccr
LazStats: Use TAChart in ABRAnovaUnit.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7796 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -311,8 +311,6 @@ inherited ABRAnovaForm: TABRAnovaForm
|
|||||||
Left = 350
|
Left = 350
|
||||||
Height = 336
|
Height = 336
|
||||||
Width = 465
|
Width = 465
|
||||||
ActivePage = ChartPage
|
|
||||||
TabIndex = 1
|
|
||||||
end
|
end
|
||||||
object ListChartSource_AB: TListChartSource[3]
|
object ListChartSource_AB: TListChartSource[3]
|
||||||
Left = 465
|
Left = 465
|
||||||
|
@ -7,10 +7,9 @@ unit ABRANOVAUnit;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
contexthelpunit, Classes, SysUtils, FileUtil, TASources, TAStyles, Forms,
|
Classes, SysUtils, FileUtil, TASources, TAStyles, Forms,
|
||||||
Controls, Graphics, Dialogs, StdCtrls, Buttons, ExtCtrls, ComCtrls, MainUnit,
|
Controls, Graphics, Dialogs, StdCtrls, Buttons, ExtCtrls, ComCtrls, MainUnit,
|
||||||
FunctionsLib, GraphLib, Globals, DataProcs, MatrixLib,
|
FunctionsLib, Globals, DataProcs, MatrixLib, BasicStatsReportAndChartFormUnit;
|
||||||
BasicStatsReportAndChartFormUnit;
|
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -49,7 +48,9 @@ type
|
|||||||
procedure COutBtnClick(Sender: TObject);
|
procedure COutBtnClick(Sender: TObject);
|
||||||
procedure VarListDblClick(Sender: TObject);
|
procedure VarListDblClick(Sender: TObject);
|
||||||
private
|
private
|
||||||
{ private declarations }
|
type TInteraction = (AB, AC, BC);
|
||||||
|
|
||||||
|
private
|
||||||
ColNoSelected: IntDyneVec;
|
ColNoSelected: IntDyneVec;
|
||||||
ACol, BCol, NoSelected, MinA, MaxA, MinB, MaxB, NoAGrps, NoBGrps : integer;
|
ACol, BCol, NoSelected, MinA, MaxA, MinB, MaxB, NoAGrps, NoBGrps : integer;
|
||||||
group, MaxRows, MaxCols, TotalN, NinGrp : integer;
|
group, MaxRows, MaxCols, TotalN, NinGrp : integer;
|
||||||
@ -69,13 +70,16 @@ type
|
|||||||
RowLabels, ColLabels : StrDyneVec;
|
RowLabels, ColLabels : StrDyneVec;
|
||||||
selected : integer;
|
selected : integer;
|
||||||
|
|
||||||
|
FBtnAB, FBtnAC, FBtnBC: TToolButton;
|
||||||
|
procedure InteractionChanged(Sender: TObject);
|
||||||
|
|
||||||
function InitData: Boolean;
|
function InitData: Boolean;
|
||||||
procedure GetData;
|
procedure GetData;
|
||||||
procedure Calculate;
|
procedure Calculate;
|
||||||
procedure Summarize(AReport: TStrings);
|
procedure Summarize(AReport: TStrings);
|
||||||
procedure MeansReport(AReport: TStrings);
|
procedure MeansReport(AReport: TStrings);
|
||||||
procedure BoxTests(AReport: TStrings);
|
procedure BoxTests(AReport: TStrings);
|
||||||
procedure GraphMeans;
|
procedure PlotMeans(AInteraction: TInteraction);
|
||||||
procedure CleanUp;
|
procedure CleanUp;
|
||||||
|
|
||||||
protected
|
protected
|
||||||
@ -99,15 +103,53 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Math,
|
Math,
|
||||||
MathUnit, GridProcs;
|
TAChartUtils, TALegend, TACustomSource, TACustomSeries, TASeries,
|
||||||
|
Utils, MathUnit, GridProcs, ChartFrameUnit;
|
||||||
|
|
||||||
{ TABRAnovaForm }
|
{ TABRAnovaForm }
|
||||||
|
|
||||||
constructor TABRAnovaForm.Create(AOwner: TComponent);
|
constructor TABRAnovaForm.Create(AOwner: TComponent);
|
||||||
|
var
|
||||||
|
btn: TToolButton;
|
||||||
begin
|
begin
|
||||||
inherited;
|
inherited;
|
||||||
if GraphFrm = nil then
|
|
||||||
Application.CreateForm(TGraphFrm, GraphFrm);
|
FChartFrame.Chart.Margins.Bottom := 0;
|
||||||
|
FChartFrame.Chart.BottomAxis.AxisPen.Visible := true;
|
||||||
|
FChartFrame.Chart.BottomAxis.ZPosition := 1;
|
||||||
|
FChartFrame.Chart.BottomAxis.Grid.Visible := false;
|
||||||
|
|
||||||
|
FChartFrame.ChartToolbar.ShowCaptions := true;
|
||||||
|
FChartFrame.ChartToolbar.ButtonHeight := 40;;
|
||||||
|
|
||||||
|
|
||||||
|
btn := TToolButton.Create(FChartFrame.ChartToolbar);
|
||||||
|
btn.Style := tbsDivider;
|
||||||
|
AddButtonToToolbar(btn, FChartFrame.ChartToolbar);
|
||||||
|
|
||||||
|
FBtnAB := TToolButton.Create(FChartFrame.ChartToolbar);
|
||||||
|
FBtnAB.Caption := 'AB interaction';
|
||||||
|
FBtnAB.Down := true;
|
||||||
|
FBtnAB.Style := tbsCheck;
|
||||||
|
FBtnAB.Grouped := true;
|
||||||
|
FBtnAB.OnClick := @InteractionChanged;
|
||||||
|
AddButtonToToolbar(FBtnAB, FChartFrame.ChartToolbar);
|
||||||
|
|
||||||
|
FBtnAC := TToolButton.Create(FChartFrame.ChartToolbar);
|
||||||
|
FBtnAC.Caption := 'AC interaction';
|
||||||
|
FBtnAC.Grouped := true;
|
||||||
|
FBtnAC.Style := tbsCheck;
|
||||||
|
FBtnAC.OnClick := @InteractionChanged;
|
||||||
|
AddButtonToToolbar(FBtnAC, FChartFrame.ChartToolbar);
|
||||||
|
|
||||||
|
FBtnBC := TToolButton.Create(FChartFrame.ChartToolbar);
|
||||||
|
FbtnBC.Caption := 'BC interaction';
|
||||||
|
FBtnBC.Grouped := true;
|
||||||
|
FBtnBC.Style := tbsCheck;
|
||||||
|
FBtnBC.OnClick := @InteractionChanged;
|
||||||
|
AddButtonToToolbar(FBtnBC, FChartFrame.ChartToolbar);
|
||||||
|
|
||||||
|
PageControl.ActivePageIndex := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -210,9 +252,11 @@ begin
|
|||||||
Acnt := nil;
|
Acnt := nil;
|
||||||
SumPSqr := nil;
|
SumPSqr := nil;
|
||||||
AMatrix := nil;
|
AMatrix := nil;
|
||||||
BCSums := nil;
|
{
|
||||||
|
BCSums := nil; // needed for plotting
|
||||||
ACSums := nil;
|
ACSums := nil;
|
||||||
ABSums := nil;
|
ABSums := nil;
|
||||||
|
}
|
||||||
CSums := nil;
|
CSums := nil;
|
||||||
BSums := nil;
|
BSums := nil;
|
||||||
ASums := nil;
|
ASums := nil;
|
||||||
@ -243,6 +287,7 @@ end;
|
|||||||
procedure TABRAnovaForm.Compute;
|
procedure TABRAnovaForm.Compute;
|
||||||
var
|
var
|
||||||
lReport: TStrings;
|
lReport: TStrings;
|
||||||
|
interaction: TInteraction;
|
||||||
begin
|
begin
|
||||||
lReport := TStringList.Create;
|
lReport := TStringList.Create;
|
||||||
try
|
try
|
||||||
@ -252,9 +297,18 @@ begin
|
|||||||
Calculate;
|
Calculate;
|
||||||
Summarize(lReport);
|
Summarize(lReport);
|
||||||
MeansReport(lReport);
|
MeansReport(lReport);
|
||||||
if TestChk.Checked then BoxTests(lReport);
|
if TestChk.Checked then
|
||||||
|
BoxTests(lReport);
|
||||||
|
|
||||||
FReportFrame.DisplayReport(lReport);
|
FReportFrame.DisplayReport(lReport);
|
||||||
if PlotChk.Checked then GraphMeans;
|
|
||||||
|
if PlotChk.Checked then
|
||||||
|
begin
|
||||||
|
if FBtnAB.Down then interaction := AB else
|
||||||
|
if FBtnAC.Down then interaction := AC else
|
||||||
|
if FBtnBC.Down then interaction := BC;
|
||||||
|
PlotMeans(interaction);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
lReport.Free;
|
lReport.Free;
|
||||||
@ -389,6 +443,23 @@ begin
|
|||||||
Result := true;
|
Result := true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TABRAnovaForm.InteractionChanged(Sender: TObject);
|
||||||
|
var
|
||||||
|
interaction: TInteraction;
|
||||||
|
begin
|
||||||
|
if TObject(Sender) is TToolButton then
|
||||||
|
TToolButton(Sender).Down := true;
|
||||||
|
|
||||||
|
if FBtnAB.Down then
|
||||||
|
interaction := AB
|
||||||
|
else if FBtnAC.Down then
|
||||||
|
interaction := AC
|
||||||
|
else if FBtnBC.Down then
|
||||||
|
interaction := BC;
|
||||||
|
|
||||||
|
PlotMeans(interaction);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TABRAnovaForm.GetData;
|
procedure TABRAnovaForm.GetData;
|
||||||
var
|
var
|
||||||
i, j, SubjA, SubjB: integer;
|
i, j, SubjA, SubjB: integer;
|
||||||
@ -868,120 +939,93 @@ begin
|
|||||||
XVector := nil;
|
XVector := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TABRAnovaForm.GraphMeans;
|
|
||||||
|
procedure TABRAnovaForm.PlotMeans(AInteraction: TInteraction);
|
||||||
|
const
|
||||||
|
X_TITLE: array[TInteraction] of string = (
|
||||||
|
'B TREATMENT GROUP',
|
||||||
|
'C TREATMENT (WITHIN SUBJECTS) GROUP',
|
||||||
|
'C TREATMENT (WITHIN SUBJECTS) GROUP'
|
||||||
|
);
|
||||||
|
SERIES_TITLE: array[TInteraction] of string = (
|
||||||
|
'A%d',
|
||||||
|
'A%d',
|
||||||
|
'B%d'
|
||||||
|
);
|
||||||
|
|
||||||
var
|
var
|
||||||
MaxMean : double;
|
idx: Integer;
|
||||||
i, j : integer;
|
item: PChartDataItem;
|
||||||
|
ser: TChartSeries;
|
||||||
|
serSource: TListChartSource;
|
||||||
|
i, j: Integer;
|
||||||
begin
|
begin
|
||||||
// Do AB interaction
|
FChartFrame.Clear;
|
||||||
// Get maximum cell mean
|
ListChartSource_AB.Clear;
|
||||||
MaxMean := ABSums[0,0] / (NinGrp*NoSelected);
|
ListChartSource_AC.Clear;
|
||||||
SetLength(GraphFrm.Ypoints,NoAGrps,NoBGrps);
|
ListChartSource_BC.Clear;
|
||||||
SetLength(GraphFrm.Xpoints,1,NoBGrps);
|
ChartStyles.Styles.Clear;
|
||||||
for i := 1 to NoAGrps do
|
|
||||||
begin
|
|
||||||
GraphFrm.SetLabels[i] := 'A ' + IntToStr(i);
|
|
||||||
for j := 1 to NoBGrps do
|
|
||||||
begin
|
|
||||||
GraphFrm.Ypoints[i-1,j-1] := ABSums[i-1,j-1] / (NinGrp * NoSelected);
|
|
||||||
if GraphFrm.Ypoints[i-1,j-1] > MaxMean then MaxMean := GraphFrm.Ypoints[i-1,j-1];
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
for j := 1 to NoBGrps do
|
|
||||||
begin
|
|
||||||
GraphFrm.Xpoints[0,j-1] := j;
|
|
||||||
end;
|
|
||||||
|
|
||||||
GraphFrm.nosets := NoAGrps;
|
ListChartSource_AB.YCount := NoAGrps;
|
||||||
GraphFrm.nbars := NoBGrps;
|
for j := 0 to NoBGrps-1 do
|
||||||
GraphFrm.Heading := 'AxBxR ANOVA';
|
begin
|
||||||
GraphFrm.XTitle := 'B TREATMENT GROUP';
|
idx := ListChartSource_AB.Add(j+1, 0);
|
||||||
GraphFrm.YTitle := 'Mean';
|
item := ListChartSource_AB.Item[idx];
|
||||||
GraphFrm.barwideprop := 0.5;
|
for i := 0 to NoAGrps-1 do
|
||||||
GraphFrm.AutoScaled := false;
|
item^.SetY(i, ABSums[i, j] / (NInGrp * NoSelected));
|
||||||
GraphFrm.GraphType := 2; // 3d Vertical Bar Chart
|
end;
|
||||||
GraphFrm.miny := 0.0;
|
|
||||||
GraphFrm.maxy := maxmean;
|
|
||||||
GraphFrm.BackColor := clCream;
|
|
||||||
GraphFrm.WallColor := clDkGray;
|
|
||||||
GraphFrm.FloorColor := clLtGray;
|
|
||||||
GraphFrm.ShowBackWall := true;
|
|
||||||
GraphFrm.ShowModal;
|
|
||||||
|
|
||||||
// Do AC interaction
|
ListChartSource_AC.YCount := NoAGrps;
|
||||||
MaxMean := ACSums[0,0] / (NinGrp*NoBGrps);
|
for j := 0 to NoSelected-1 do
|
||||||
SetLength(GraphFrm.Ypoints,NoAGrps,NoSelected);
|
begin
|
||||||
SetLength(GraphFrm.Xpoints,1,NoSelected);
|
idx := ListChartSource_AC.Add(j+1, 0);
|
||||||
for i := 1 to NoAGrps do
|
item := ListChartSource_AC.Item[idx];
|
||||||
begin
|
for i := 0 to NoAGrps-1 do
|
||||||
GraphFrm.SetLabels[i] := 'A ' + IntToStr(i);
|
item^.SetY(i, ACSums[i, j] / (NInGrp * NoBGrps));
|
||||||
for j := 1 to NoSelected do
|
end;
|
||||||
begin
|
|
||||||
GraphFrm.Ypoints[i-1,j-1] := ACSums[i-1,j-1] / (NinGrp * NoBGrps);
|
|
||||||
if GraphFrm.Ypoints[i-1,j-1] > MaxMean then MaxMean := GraphFrm.Ypoints[i-1,j-1];
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
for j := 1 to NoSelected do
|
|
||||||
begin
|
|
||||||
GraphFrm.Xpoints[0,j-1] := j;
|
|
||||||
end;
|
|
||||||
GraphFrm.nosets := NoAGrps;
|
|
||||||
GraphFrm.nbars := NoSelected;
|
|
||||||
GraphFrm.Heading := 'AxBxR ANOVA';
|
|
||||||
GraphFrm.XTitle := 'C TREATMENT (WITHIN SUBJECTS) GROUP';
|
|
||||||
GraphFrm.YTitle := 'Mean';
|
|
||||||
GraphFrm.barwideprop := 0.5;
|
|
||||||
GraphFrm.AutoScaled := false;
|
|
||||||
GraphFrm.GraphType := 2; // 3d Vertical Bar Chart
|
|
||||||
GraphFrm.miny := 0.0;
|
|
||||||
GraphFrm.maxy := maxmean;
|
|
||||||
GraphFrm.BackColor := clCream;
|
|
||||||
GraphFrm.WallColor := clDkGray;
|
|
||||||
GraphFrm.FloorColor := clLtGray;
|
|
||||||
GraphFrm.ShowBackWall := true;
|
|
||||||
GraphFrm.ShowModal;
|
|
||||||
|
|
||||||
// Do BC interaction
|
ListChartSource_BC.YCount := NoBGrps;
|
||||||
SetLength(GraphFrm.Ypoints,NoBGrps,NoSelected);
|
for j := 0 to NoSelected-1 do
|
||||||
SetLength(GraphFrm.Xpoints,NoSelected);
|
begin
|
||||||
MaxMean := BCSums[0,0] / (NinGrp*NoAGrps);
|
idx := ListChartSource_BC.Add(j+1, 0);
|
||||||
for i := 1 to NoBGrps do
|
item := ListChartSource_BC.Item[idx];
|
||||||
for j := 1 to NoSelected do
|
for i := 0 to NoBGrps-1 do
|
||||||
if ((BCSums[i-1,j-1] / (NinGrp*NoAGrps)) > MaxMean) then
|
item^.SetY(i, BCSums[i, j] / (NInGrp * NoAGrps));
|
||||||
MaxMean := BCSums[i-1,j-1] / (NinGrp*NoAGrps);
|
end;
|
||||||
for i := 1 to NoBGrps do
|
|
||||||
|
case AInteraction of
|
||||||
|
AB: serSource := ListChartSource_AB;
|
||||||
|
AC: serSource := ListChartSource_AC;
|
||||||
|
BC: serSource := ListChartSource_BC;
|
||||||
|
end;
|
||||||
|
|
||||||
|
ser := FChartFrame.PlotXY(ptBars, nil, nil, nil, nil, '', clDefault);
|
||||||
|
with TBarSeries(ser) do
|
||||||
|
begin
|
||||||
|
Source := serSource;
|
||||||
|
Legend.Multiplicity := lmStyle;
|
||||||
|
Stacked := false;
|
||||||
|
Styles := ChartStyles;
|
||||||
|
end;
|
||||||
|
|
||||||
|
for i := 0 to ser.Source.YCount-1 do
|
||||||
|
begin
|
||||||
|
with TChartStyle(ChartStyles.Styles.Add) do
|
||||||
begin
|
begin
|
||||||
GraphFrm.SetLabels[i] := 'B ' + IntToStr(i);
|
Text := Format(SERIES_TITLE[AInteraction], [i+1]);
|
||||||
for j := 1 to NoSelected do
|
Brush.Color := DATA_COLORS[i mod Length(DATA_COLORS)];
|
||||||
begin
|
UseBrush := true;
|
||||||
GraphFrm.Ypoints[i-1,j-1] := BCSums[i-1,j-1] / (NinGrp * NoAGrps);
|
|
||||||
if GraphFrm.Ypoints[i-1,j-1] > MaxMean then MaxMean := GraphFrm.Ypoints[i-1,j-1];
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
for j := 1 to NoSelected do
|
end;
|
||||||
begin
|
|
||||||
GraphFrm.Xpoints[0,j-1] := j;
|
FChartFrame.Chart.BottomAxis.Marks.Source := ser.Source;
|
||||||
end;
|
FChartFrame.Chart.BottomAxis.Marks.Style := smsXValue;
|
||||||
GraphFrm.nosets := NoBGrps;
|
FChartFrame.SetTitle('AxBxR ANOVA');
|
||||||
GraphFrm.nbars := NoSelected;
|
FChartFrame.SetXTitle(X_TITLE[AInteraction]);
|
||||||
GraphFrm.Heading := 'AxBxR ANOVA';
|
FChartFrame.SetYTitle('Means');
|
||||||
GraphFrm.XTitle := 'C TREATMENT (WITHIN SUBJECTS) GROUP';
|
|
||||||
GraphFrm.YTitle := 'Mean';
|
|
||||||
GraphFrm.barwideprop := 0.5;
|
|
||||||
GraphFrm.AutoScaled := false;
|
|
||||||
GraphFrm.GraphType := 2; // 3d Vertical Bar Chart
|
|
||||||
GraphFrm.miny := 0.0;
|
|
||||||
GraphFrm.maxy := maxmean;
|
|
||||||
GraphFrm.BackColor := clCream;
|
|
||||||
GraphFrm.WallColor := clDkGray;
|
|
||||||
GraphFrm.FloorColor := clLtGray;
|
|
||||||
GraphFrm.ShowBackWall := true;
|
|
||||||
GraphFrm.ShowModal;
|
|
||||||
// cleanup the heap
|
|
||||||
GraphFrm.Xpoints := nil;
|
|
||||||
GraphFrm.Ypoints := nil;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TABRAnovaForm.Reset;
|
procedure TABRAnovaForm.Reset;
|
||||||
var
|
var
|
||||||
i: integer;
|
i: integer;
|
||||||
@ -1053,7 +1097,7 @@ begin
|
|||||||
|
|
||||||
if CList.Items.Count = 0 then
|
if CList.Items.Count = 0 then
|
||||||
begin
|
begin
|
||||||
AMsg := 'No Repeated Measures variables specified.';
|
AMsg := 'No Repeated Measures variable(s) specified.';
|
||||||
AControl := CList;
|
AControl := CList;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
@ -31,13 +31,13 @@ inherited BasicStatsReportAndChartForm: TBasicStatsReportAndChartForm
|
|||||||
Height = 434
|
Height = 434
|
||||||
Top = 8
|
Top = 8
|
||||||
Width = 396
|
Width = 396
|
||||||
ActivePage = ReportPage
|
ActivePage = ChartPage
|
||||||
Align = alClient
|
Align = alClient
|
||||||
BorderSpacing.Left = 4
|
BorderSpacing.Left = 4
|
||||||
BorderSpacing.Top = 8
|
BorderSpacing.Top = 8
|
||||||
BorderSpacing.Right = 8
|
BorderSpacing.Right = 8
|
||||||
BorderSpacing.Bottom = 8
|
BorderSpacing.Bottom = 8
|
||||||
TabIndex = 0
|
TabIndex = 1
|
||||||
TabOrder = 2
|
TabOrder = 2
|
||||||
object ReportPage: TTabSheet
|
object ReportPage: TTabSheet
|
||||||
Caption = 'Report'
|
Caption = 'Report'
|
||||||
|
@ -69,6 +69,7 @@ object ChartFrame: TChartFrame
|
|||||||
Caption = 'Save'
|
Caption = 'Save'
|
||||||
ImageIndex = 4
|
ImageIndex = 4
|
||||||
OnClick = tbSaveChartClick
|
OnClick = tbSaveChartClick
|
||||||
|
ShowCaption = False
|
||||||
end
|
end
|
||||||
object tbPrintChart: TToolButton
|
object tbPrintChart: TToolButton
|
||||||
Left = 26
|
Left = 26
|
||||||
@ -77,6 +78,7 @@ object ChartFrame: TChartFrame
|
|||||||
Caption = 'Print'
|
Caption = 'Print'
|
||||||
ImageIndex = 5
|
ImageIndex = 5
|
||||||
OnClick = tbPrintChartClick
|
OnClick = tbPrintChartClick
|
||||||
|
ShowCaption = False
|
||||||
end
|
end
|
||||||
object tbCopyChart: TToolButton
|
object tbCopyChart: TToolButton
|
||||||
Left = 51
|
Left = 51
|
||||||
@ -85,6 +87,7 @@ object ChartFrame: TChartFrame
|
|||||||
Caption = 'Copy'
|
Caption = 'Copy'
|
||||||
ImageIndex = 7
|
ImageIndex = 7
|
||||||
OnClick = tbCopyChartClick
|
OnClick = tbCopyChartClick
|
||||||
|
ShowCaption = False
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
object PrintDialog: TPrintDialog
|
object PrintDialog: TPrintDialog
|
||||||
|
Reference in New Issue
Block a user