In code behind, declare all the public
variables and Public
method. In User control, I have added one panel and one PictureBox
Control named as "PIC_SHANUSPC
".
public DataTable dt=new DataTable();
Font f12 = new Font("arial", 12, FontStyle.Bold, GraphicsUnit.Pixel);
Pen B1pen = new Pen(Color.Black, 1);
Pen B2pen = new Pen(Color.Black, 2);
Double XDoublkeBAR = 0;
Double RBAR = 0;
Double XBARUCL = 0;
Double XBARLCL = 0;
Double RANGEUCL = 0;
Double RANGELCL = 0;
Double[] intMeanArrayVals;
Double[] intRangeArrayVals;
int First_chartDatarectHeight = 80;
Font f10 = new Font("arial", 10, FontStyle.Bold, GraphicsUnit.Pixel);
LinearGradientBrush a2 = new LinearGradientBrush(new RectangleF(0, 0, 100, 19),
Color.DarkGreen, Color.Green, LinearGradientMode.Horizontal);
LinearGradientBrush a1 = new LinearGradientBrush(new RectangleF(0, 0, 100, 19),
Color.Blue, Color.DarkBlue, LinearGradientMode.Horizontal);
Once the variable is declared, I have created a public
function as Bindgrid
. This function will be used from Windows Form to pass the DataTable
. In this function, I check for the DataTable
and if the DataTable
is not null
, I refresh the PictureBox
which will call the PictureBox paint
method.
public void Bindgrid(DataTable dtnew)
{
if (dtnew != null)
{
dt = dtnew;
PIC_SHANUSPC.Refresh();
}
}
In PictureBox paint
event, I will check for the DataTable
data. Using the data, I have created the Sum
, Mean
and Range
of all data. Using this information, I have created UCL and LCL by Standard formula. For details about UCL and LCL calculation, kindly check the above links. Using all this information, I have drawn the SPC XBAR and Range Chart using GrawLine
, DrawRectangle
.
public void PIC_SHANUSPC_Paint(object sender, PaintEventArgs e)
{
if (dt.Rows.Count <= 0)
{
return;
}
int opacity = 48;
e.Graphics.DrawString("SHANU SPC CHART",
new Font("Arial", 72),
new SolidBrush(Color.FromArgb(opacity, Color.OrangeRed)),
80,
PIC_SHANUSPC.Height / 2 - 50);
int NoofTrials = dt.Rows.Count;
int NoofParts = dt.Columns.Count - 1;
intMeanArrayVals = new Double[NoofParts];
intRangeArrayVals = new Double[NoofParts];
PIC_SHANUSPC.Width = dt.Columns.Count * 50 + 40;
e.Graphics.DrawRectangle(Pens.Black, 10, 10,
PIC_SHANUSPC.Width - 20, First_chartDatarectHeight);
e.Graphics.DrawLine(B1pen, 10, 30, PIC_SHANUSPC.Width - 10, 30);
e.Graphics.DrawLine(B1pen, 10, 60, PIC_SHANUSPC.Width - 10, 60);
e.Graphics.DrawLine(B1pen, 60, 10, 60, First_chartDatarectHeight + 8);
e.Graphics.DrawLine(B1pen, 110, 10, 110, First_chartDatarectHeight + 8);
e.Graphics.DrawString("SUM", f12, a1, 14, 12);
e.Graphics.DrawString("MEAN", f12, a1, 14, 40);
e.Graphics.DrawString("Range", f12, a1, 14, 68);
int xLineposition = 110;
int xStringDrawposition = 14;
for (int iCol = 1; iCol <= dt.Columns.Count - 1; iCol++)
{
Double Sumresult = 0;
Double Meanresult = 0;
Double Rangeresult = 0;
Double minRangeValue = int.MaxValue;
Double maxRangeValue = int.MinValue;
for (int iRow = 0; iRow < dt.Rows.Count; iRow++)
{
Sumresult = Sumresult + System.Convert.ToDouble
(dt.Rows[iRow][iCol].ToString());
Double accountLevel = System.Convert.ToDouble
(dt.Rows[iRow][iCol].ToString());
minRangeValue = Math.Min(minRangeValue, accountLevel);
maxRangeValue = Math.Max(maxRangeValue, accountLevel);
}
xLineposition = xLineposition + 50;
xStringDrawposition = xStringDrawposition + 50;
e.Graphics.DrawLine(B1pen, xLineposition, 10,
xLineposition, First_chartDatarectHeight + 8);
e.Graphics.DrawString(Math.Round(Sumresult, 3).ToString(),
f10, a2, xStringDrawposition, 12);
Meanresult = Sumresult / NoofTrials;
e.Graphics.DrawString(Math.Round(Meanresult, 3).ToString(),
f10, a2, xStringDrawposition, 40);
Rangeresult = maxRangeValue - minRangeValue;
e.Graphics.DrawString(Math.Round(Rangeresult, 3).ToString(),
f10, a2, xStringDrawposition, 68);
XDoublkeBAR = XDoublkeBAR + Meanresult;
RBAR = RBAR + Rangeresult;
intMeanArrayVals[iCol - 1] = Meanresult;
intRangeArrayVals[iCol - 1] = Rangeresult;
}
XDoublkeBAR = XDoublkeBAR / NoofParts;
RBAR = RBAR / NoofParts;
XBARUCL = XDoublkeBAR + UCLLCLTYPE("A2", RBAR, NoofTrials);
XBARLCL = XDoublkeBAR - UCLLCLTYPE("A2", RBAR, NoofTrials);
RANGEUCL = UCLLCLTYPE("D4", RBAR, NoofTrials);
RANGELCL = UCLLCLTYPE("D3", RBAR, NoofTrials);
int chartAvarageDatarectHeight = 18;
e.Graphics.DrawRectangle(Pens.Black, 10,
First_chartDatarectHeight + 20, PIC_SHANUSPC.Width - 20,
chartAvarageDatarectHeight);
e.Graphics.DrawLine(B2pen, 476, 116, 480, 100);
e.Graphics.DrawString("MEAN CHART",
f12, a1, 14, First_chartDatarectHeight + 22);
e.Graphics.DrawString("XBarS:",
f12, a1, 160, First_chartDatarectHeight + 22);
e.Graphics.DrawString(Math.Round(XDoublkeBAR, 3).ToString(),
f12, a2, 202, First_chartDatarectHeight + 22);
e.Graphics.DrawString("UCL:",
f12, a1, 300, First_chartDatarectHeight + 22);
e.Graphics.DrawString(Math.Round(XBARUCL, 3).ToString(),
f12, a2, 330, First_chartDatarectHeight + 22);
e.Graphics.DrawString("LCL:",
f12, a1, 400, First_chartDatarectHeight + 22);
e.Graphics.DrawString(Math.Round(XBARLCL, 3).ToString(),
f12, a2, 430, First_chartDatarectHeight + 22);
e.Graphics.DrawString("RANGE CHART",
f12, a1, 490, First_chartDatarectHeight + 22);
e.Graphics.DrawString("RBar : ",
f12, a1, 600, First_chartDatarectHeight + 22);
e.Graphics.DrawString(Math.Round(RBAR, 3).ToString(),
f12, a2, 638, First_chartDatarectHeight + 22);
e.Graphics.DrawString("UCL : ",
f12, a1, 700, First_chartDatarectHeight + 22);
e.Graphics.DrawString(Math.Round(RANGEUCL, 3).ToString(),
f12, a2, 734, First_chartDatarectHeight + 22);
e.Graphics.DrawString("LCL : ",
f12, a1, 800, First_chartDatarectHeight + 22);
e.Graphics.DrawString(Math.Round(RANGELCL, 3).ToString(),
f12, a2, 834, First_chartDatarectHeight + 22);
DrawLineChart(e.Graphics, intMeanArrayVals, XBARUCL, XBARLCL,
PIC_SHANUSPC.Width - 70, 164, 60, 130, "MEAN");
DrawLineChart(e.Graphics, intRangeArrayVals, RANGEUCL, RANGELCL,
PIC_SHANUSPC.Width - 70, 164, 60, 300, "RANGE");
}
For UCL and LCL, we need to use the A2, D4, D3 Constants in calculation. For this, I have created a function named as "UCLLCLTYPE
" which will return the constants. For example, to calculate UCL and LCL, see the code below:
XBARUCL = XDoublkeBAR + UCLLCLTYPE("A2", RBAR, NoofTrials);
XBARLCL = XDoublkeBAR - UCLLCLTYPE("A2", RBAR, NoofTrials);
RANGEUCL = UCLLCLTYPE("D4", RBAR, NoofTrials);
RANGELCL = UCLLCLTYPE("D3", RBAR, NoofTrials);
public double UCLLCLTYPE(String ControlUCLLCLType, Double RBAR, int NoofTrials)
{
Double Result = 0;
Double A2Val = 0;
Double D3val = 0;
Double D4val = 0;
if (ControlUCLLCLType == "A2")
{
switch (NoofTrials)
{
case 2:
A2Val = 1.880;
break;
case 3:
A2Val = 1.023;
break;
case 4:
A2Val = 0.729;
break;
case 5:
A2Val = 0.577;
break;
case 6:
A2Val = 0.483;
break;
case 7:
A2Val = 0.419;
break;
case 8:
A2Val = 0.373;
break;
case 9:
A2Val = 0.337;
break;
case 10:
A2Val = 0.308;
break;
case 11:
A2Val = 0.285;
break;
case 12:
A2Val = 0.266;
break;
case 13:
A2Val = 0.249;
break;
case 14:
A2Val = 0.235;
break;
case 15:
A2Val = 0.223;
break;
case 16:
A2Val = 0.212;
break;
case 17:
A2Val = 0.203;
break;
case 18:
A2Val = 0.194;
break;
case 19:
A2Val = 0.187;
break;
case 20:
A2Val = 0.180;
break;
case 21:
A2Val = 0.173;
break;
case 22:
A2Val = 0.167;
break;
case 23:
A2Val = 0.162;
break;
case 24:
A2Val = 0.157;
break;
case 25:
A2Val = 0.153;
break;
}
Result = A2Val * RBAR;
}
else if (ControlUCLLCLType == "D3")
{
switch (NoofTrials)
{
case 2:
D3val = 0;
break;
case 3:
D3val = 0;
break;
case 4:
D3val = 0;
break;
case 5:
D3val = 0;
break;
case 6:
D3val = 0;
break;
case 7:
D3val = 0.076;
break;
case 8:
D3val = 0.136;
break;
case 9:
D3val = 0.184;
break;
case 10:
D3val = 0.223;
break;
case 11:
D3val = 0.256;
break;
case 12:
D3val = 0.283;
break;
case 13:
D3val = 0.307;
break;
case 14:
D3val = 0.328;
break;
case 15:
D3val = 0.347;
break;
case 16:
D3val = 0.363;
break;
case 17:
D3val = 0.378;
break;
case 18:
D3val = 0.391;
break;
case 19:
D3val = 0.403;
break;
case 20:
D3val = 0.415;
break;
case 21:
D3val = 0.425;
break;
case 22:
D3val = 0.434;
break;
case 23:
D3val = 0.443;
break;
case 24:
D3val = 0.451;
break;
case 25:
D3val = 0.459;
break;
}
Result = D3val * RBAR;
}
else if (ControlUCLLCLType == "D4")
{
switch (NoofTrials)
{
case 2:
D4val = 3.268;
break;
case 3:
D4val = 2.574;
break;
case 4:
D4val = 2.282;
break;
case 5:
D4val = 2.114;
break;
case 6:
D4val = 2.004;
break;
case 7:
D4val = 1.924;
break;
case 8:
D4val = 1.864;
break;
case 9:
D4val = 1.816;
break;
case 10:
D4val = 1.777;
break;
case 11:
D4val = 1.744;
break;
case 12:
D4val = 1.717;
break;
case 13:
D4val = 1.693;
break;
case 14:
D4val = 1.672;
break;
case 15:
D4val = 1.653;
break;
case 16:
D4val = 1.637;
break;
case 17:
D4val = 1.622;
break;
case 18:
D4val = 1.608;
break;
case 19:
D4val = 1.597;
break;
case 20:
D4val = 1.585;
break;
case 21:
D4val = 1.575;
break;
case 22:
D4val = 1.566;
break;
case 23:
D4val = 1.557;
break;
case 24:
D4val = 1.548;
break;
case 25:
D4val = 1.541;
break;
}
Result = D4val * RBAR;
}
return Result;
}