65.9K
CodeProject 正在变化。 阅读更多。
Home

SPC XBAR 和 Range 图

starIconstarIconstarIconstarIconstarIcon

5.00/5 (5投票s)

2015年1月25日

CPOL

3分钟阅读

viewsIcon

50298

downloadIcon

2314

使用 C# 的 XBAR 和 Range 图。

引言

在我们开始之前,请参考我之前关于 USL 和 LSL 的控制图的文章 控制图链接。 在我之前的文章中,我解释了如何为 USL 和 LSL 数据检查创建一个简单的控制条形图。

在今天的这篇文章中,我将解释如何创建一个简单的 SPC(统计过程控制)X-bar 和 Range 线性图表。 如果您有兴趣学习 SPC 和 X-Bar,Range 图表请参考以下链接

现在,让我们看看我是如何创建 SPC X-Bar 和 Range 图表的。 我的主要目标是制作一个非常简单的 SPC 图表,供最终用户使用。

我创建了一个 SPC Xbar/Range 图表作为用户控件,以便可以在所有项目中轻松使用它。

在本文中,我附上了一个名为 SHANUSPCXbarRangeChartSRC.zip 的 zip 文件,其中包含

  1. SHANUXbarRangeChart”文件夹(此文件夹包含 <span style="font-size: 12px; background-color: rgb(255,255,255)">SHANUXbarRangeChart</span> 用户控件源代码。)
  2. SHANUSPCXBarDemo”文件夹(此文件夹包含演示程序,其中包括 <span style="font-size: 12px; background-color: rgb(255,255,255)">SHANUXbarRangeChart</span> 用户控件,带有随机数据样本)。

注意:我使用 DataTable 作为 UserControl 的数据输入。 从 Windows Form 中,我们需要将 DataTable 传递给用户控件以绘制 XBAR 和 Range 线性图。

Using the Code

  1. 首先,我们将从用户控件开始。要创建用户控件,
    1. 创建一个新的 Windows 控件库项目。
    2. 设置项目的名称并单击“确定”(这里,我的用户控件名称是 <span style="font-size: 12px; background-color: rgb(255,255,255)">SHANUXbarRangeChart</span>)。
    3. 添加所有需要的控件。
    4. 在代码隐藏中,声明所有 public 变量和 Public 方法。 在用户控件中,我添加了一个面板和一个名为“PIC_SHANUSPC”的 PictureBox 控件。
       //Public Variable
              
              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);

      声明变量后,我创建了一个 public 函数,即 Bindgrid。 此函数将从 Windows Form 中使用,以传递 DataTable。 在此函数中,我检查 DataTable,如果 DataTable 不是 null,我刷新 PictureBox,这将调用 PictureBox paint 方法。

       public void Bindgrid(DataTable dtnew)
          {
              if (dtnew != null)
              {
                  dt = dtnew;
                  PIC_SHANUSPC.Refresh();
              }
         }

      PictureBox paint 事件中,我将检查 DataTable 数据。 使用这些数据,我创建了所有数据的 SumMeanRange。 使用此信息,我使用标准公式创建了 UCLLCL。 有关 UCL 和 LCL 计算的详细信息,请检查上面的链接。 使用所有这些信息,我使用 GrawLineDrawRectangle 绘制了 SPC XBAR 和 Range 图表。

        //Paint Method 
              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;
      
                 // 1) For the Chart Data Display ---------
                 e.Graphics.DrawRectangle(Pens.Black, 10, 10, 
                            PIC_SHANUSPC.Width - 20, First_chartDatarectHeight);
      
                 // for the chart data Horizontal Line Display
                 e.Graphics.DrawLine(B1pen, 10, 30, PIC_SHANUSPC.Width - 10, 30);
                 e.Graphics.DrawLine(B1pen, 10, 60, PIC_SHANUSPC.Width - 10, 60);
      
                 // for the chart data Vertical Line Display
                 e.Graphics.DrawLine(B1pen, 60, 10, 60, First_chartDatarectHeight + 8);
                 e.Graphics.DrawLine(B1pen, 110, 10, 110, First_chartDatarectHeight + 8);
      
                 //-------------
      
                 // DrawItemEventArgs String
      
                 e.Graphics.DrawString("SUM", f12, a1, 14, 12);
      
                 e.Graphics.DrawString("MEAN", f12, a1, 14, 40);
      
                 e.Graphics.DrawString("Range", f12, a1, 14, 68);
      
                 // load data 
                 //Outer Loop for Columns count
                 int xLineposition = 110;
                 int xStringDrawposition = 14;
      
                 for (int iCol = 1; iCol <= dt.Columns.Count - 1; iCol++)
                 {
                     //inner Loop for Rows count
                     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);
                     //Sum Data Display
                     e.Graphics.DrawString(Math.Round(Sumresult, 3).ToString(), 
                                           f10, a2, xStringDrawposition, 12);
      
                     //MEAN Data Display
                     Meanresult = Sumresult / NoofTrials;
                     e.Graphics.DrawString(Math.Round(Meanresult, 3).ToString(), 
                                           f10, a2, xStringDrawposition, 40);
                     //RANGE Data Display
                     Rangeresult = maxRangeValue - minRangeValue;
                     e.Graphics.DrawString(Math.Round(Rangeresult, 3).ToString(), 
                                           f10, a2, xStringDrawposition, 68);
      
                     //XDoubleBar used to display in chart
                     XDoublkeBAR = XDoublkeBAR + Meanresult;
      
                     //RBAR used to display in chart
                     RBAR = RBAR + Rangeresult;
      
                     intMeanArrayVals[iCol - 1] = Meanresult;
                     intRangeArrayVals[iCol - 1] = Rangeresult;
                 }
                 //End 1 ) -------------------
      
                 // 2) -------------------------- 
                 // XdoubleBAr/RBAR/UCL and LCL Calculation.
      
                 //XDoubleBar used to display in chart
                 XDoublkeBAR = XDoublkeBAR / NoofParts;
      
                 //RBAR used to display in chart
                 RBAR = RBAR / NoofParts;
      
                 //XBARUCL to display in chart
                 XBARUCL = XDoublkeBAR + UCLLCLTYPE("A2", RBAR, NoofTrials);
                 //XBARLCL to display in chart
                 XBARLCL = XDoublkeBAR - UCLLCLTYPE("A2", RBAR, NoofTrials);
      
                 //XBARUCL to display in chart
                 RANGEUCL = UCLLCLTYPE("D4", RBAR, NoofTrials);
      
                 //XBARLCL to display in chart
                 RANGELCL = UCLLCLTYPE("D3", RBAR, NoofTrials);
      
                 //---------------------------------
      
                 //3) Average chart Display ---------------
                 //  e.Graphics.DrawRectangle(Pens.Black, 10, 10, 
                 //  picSpcChart.Width - 20, First_chartDatarectHeight);
                 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);
      
                 //Mean Line Chart
      
                 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");
      
                 //End 3)---------------------
             }

      对于 UCL 和 LCL,我们需要在计算中使用 A2、D4、D3 常数。 为此,我创建了一个名为“UCLLCLTYPE”的函数,该函数将返回这些常数。 例如,要计算 UCL 和 LCL,请参阅以下代码

      //In paint method, we have used this to call the UCL and LCL constant data.
      
      //XBARUCL to display in chart - >This is to calculate  XBAR UCL
                 XBARUCL = XDoublkeBAR + UCLLCLTYPE("A2", RBAR, NoofTrials);
                 //XBARLCL to display in chart - >This is to calculate  XBAR LCL
                 XBARLCL = XDoublkeBAR - UCLLCLTYPE("A2", RBAR, NoofTrials);
      
                 //RANGEUCL to display in chart 
                 RANGEUCL = UCLLCLTYPE("D4", RBAR, NoofTrials);
      
                 //RANGELCL to display in chart
                 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;
                 //Constant value for the UCL and LCL calculation.
                 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;
             }
    5. 完成保存后,构建并运行项目。
  2. 现在,我们创建一个 Windows 应用程序并添加和测试我们的“SHANUXbarRangeChart”用户控件。
    1. 创建一个新的 Windows 项目。
    2. 打开您的表单,然后从工具箱 > 右键单击 > 选择项目 >,浏览选择您的用户控件 DLL 并添加。
    3. 将用户控件拖到您的 Windows 窗体上。
    4. 调用用户控件的“Bindgrid”方法并将 Datatable 传递给 Usercontrol 并检查结果。
     private void button1_Click(object sender, EventArgs e)
            {
                loadgrid();
                //shanuXBARChart is the User-control Name 
                //here we call the function and pass the DataTable.
                shanuXBARChart.Bindgrid(dt);          
            }

    在“loadgrid”方法中,我将随机数据加载到 DataTable 并显示在 gridview 中。

结论

本文的主要目的是创建一个简单且标准的 SPC X-Bar 和 Range 图表用户控件。 我计划向图表中添加更多功能。

历史

  • 2014/07/16:初始版本
© . All rights reserved.