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

使用 C# 创建 SPC CP 和 CPK 图表

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (23投票s)

2015年7月2日

CPOL

7分钟阅读

viewsIcon

67192

downloadIcon

4800

使用 C# 创建一个简单的 SP、CP 和 CPK 图表

引言

在本文中,我们可以详细了解如何创建一个简单的SPC(统计过程控制)CP、CPK 图表

我一直在从事几个自动化项目。如今,汽车行业对自动化测量设备感兴趣,以确保质量并在全球产业中竞争。任何自动化软件的主要部分都是获得准确的质量检查结果,为此,我们使用 SPC(统计过程控制)来查找质量结果。

您还可以查看我之前与工厂自动化相关的文章,例如:

能力是获取任何零件的连续数据,并将结果与CpCpkPpPpk 进行比较。其中CpCpk 是过程能力,PpPpk 是过程性能。让我们以我一个正在制造自动化测量机器中使用的实际项目为例。现在我们以汽车发动机的凸轮轴、曲轴或任何零件为例,这些零件需要进行质量控制检查。检查零件将使用某种传感器进行测量,例如,在我们的项目中,我们使用数字传感器测量凸轮轴和曲轴。使用传感器,我们获得连续数据,并将实时数据与 SPC Cp、Cpk、Pp 和 Ppk 图表进行检查。将最终输出显示给操作员和质量控制工程师。这是我的实际项目屏幕。所有测量数据均已从数字传感器接收。

我隐藏了 SPC Cp、Cpk、Pp 和 Ppk 图表,因为当时我们使用了一些第三方图表控件。市面上的 SPC 图表控件很少,而且没有免费的 SPC Cp、Cpk、Pp 和 Ppk 图表。我想创建一个简单的 SPC Cp、Cpk、Pp 和 Ppk 图表。结果,在对 SPC 及其所有功能进行了长时间研究后,我创建了一个简单的 SPC Cp、Cpk、Pp 和 Ppk 图表。希望大家都会喜欢。

我将 SPC 图表创建为用户控件。您只需将我的用户控件 DLL 添加到项目中即可使用。

Shanu CpCpkChart 用户控件特性

  • 显示带有总和、均值和极差值的图表
  • Cp、Cpk、Pp、Ppk 带有警报结果文本,NG(不合格)为红色,OK(合格)为绿色
  • 均值 (XBAR) 和极差 (RBAR) 图表,带有警报图像,NG 为红色,OK 为绿色
  • 自动计算并显示 XBAR 和 RBAR 值的上限 (UCL)、下限 (LCL)
  • 将图表保存为图像(注意:要保存图表图像,请双击图表或右键单击并选择“另存为图像”)。
  • 实时数据收集并在图表中显示
  • 用户可以添加图表水印文本

首先,我们来看看 CpCpk 是什么。

Cp 和 Cpk -> 过程能力

  • Cp - 衡量数据在规格限(USL、LSL)内拟合得如何
  • Cpk - 衡量数据在规格限之间的中心度

Cp、Cpk 公式

Cp=(USL-LSL/6SIGMA) -> USL-LSL/6*RBAR/d2
Cpk=min(USL-XBAR/3Sigma,LSL-XBAR/3Sigma)

Pp 和 Ppk -> 过程性能

  • Pp - 衡量数据在规格限(USL、LSL)内拟合得如何
  • Ppk - 衡量数据在规格限之间的中心度

Pp、Ppk 公式

Pp=(USL-LSL/6SIGMA) -> USL-LSL/6 STDEV

Ppk=min(USL-XBAR/3STDEV,LSL-XBAR/3STDEV)

参考网站

现在我们来看看我是如何创建一个 SPC Cp、Cpk 图表的。我的主要目标是制作一个非常简单的 SPC 图表,供最终用户使用。

我已将 SPC Cp、Cpk 图表创建为用户控件,以便在所有项目中都能轻松使用。

我附加了一个名为 ShanuSPCCpCpkChart.zip 的 zip 文件,您可以在本文顶部的链接处下载。它包含我的 SPC 图表用户控件源代码和一个演示程序。

  1. "ShanuCPCPKChart.dll":您可以在项目中使用此用户控件,并将数据作为 DataTable 传递给 userControl
    在用户控件中,我将获取 DataTable 值并计算结果以显示为:
  • Sum
  • 平均
  • Range
  • Cp
  • Cpk
  • Pp
  • Ppk

将所有结果绑定到带有笑脸警报图像的图表中。如果数据良好,则显示绿色笑脸;如果数据为 NG(不合格)。使用均值和极差值,我将绘制均值和极差图表以及警报图像。

用户可以向 ShanuCPCPKChart 用户控件传递 USL(上规格限)、LSL(下规格限)Cpk 限值。使用 USL、LSL 和 Cpk 值,将计算结果并显示相应的警报,如果 Cp、Cpk、Pp、Ppk 值不合格则为红色。如果结果良好,则在图表中为 Cp、Cpk、Pp、Ppk 显示绿色文本。

"ShanuSPCCpCPK_Demo" 文件夹 - 此文件夹包含演示程序,其中包括带有随机数据样本的 ShanuCPCPKChart 用户控件。

注意:我使用 DataTable 作为用户控件的数据输入。从 Windows 窗体,我们需要将 DataTable 传递给用户控件,以绘制 Cp、Cpk、Pp 和 Ppk 结果与 SPC 极差图。

保存图表 用户可以通过双击图表控件或右键单击图表并选择保存来保存图表。

Using the Code

我使用的是 Visual Studio 2010。

1) SPC 用户控件程序

首先,我们将从用户控件开始。要创建用户控件,

  1. 创建一个新的 Windows 控件库项目。
  2. 设置项目名称并点击确定(此处,我的用户控件名称是 ShanuCPCPKChart)。
  3. 添加所有需要的控件。
  4. 在代码隐藏中,声明所有 public 变量和 Public 方法。在用户控件中,我添加了一个面板和一个 Picture Box 控件。
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;
        Double[] intSTDEVArrayVals;
        Double[] intXBARArrayVals;

        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 a3 = new LinearGradientBrush(new RectangleF(0, 0, 100, 19), 
        Color.DarkRed, Color.Red, LinearGradientMode.Horizontal);
        LinearGradientBrush a1 = new LinearGradientBrush(new RectangleF(0, 0, 100, 19), 
        Color.Blue, Color.DarkBlue, LinearGradientMode.Horizontal);

声明变量后,我创建了一个 public 函数 Bindgrid。此函数将从 Windows 窗体使用,用于传递 DataTable。在此函数中,我将检查 DataTable,如果 DataTable 不为 null,我将刷新 PictureBox,这将调用 PictureBox paint 方法来绘制 SPC 图表的所有新值。

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

PictureBox paint 事件中,我将检查 DataTable 数据。使用数据,我计算并绘制 SPC 图表中的所有总和、均值、极差、Cp、Cpk、Pp 和 Ppk 的结果。使用这些信息,我通过标准公式创建了UCLLCL。有关 UCL 和 LCL 计算的详细信息,请参阅上面的链接。在所有值计算完成后,我将在 PictureBox 中使用 GDI+ 绘制 SPC 图表,并将结果显示给最终用户。

public void PicBox_Paint(object sender, PaintEventArgs e)
        {
            if (dt.Rows.Count <= 0)
            {
                return;
            }

            int opacity = 68; // 50% opaque (0 = invisible, 255 = fully opaque)

            e.Graphics.DrawString(ChartWaterMarkText,
                new Font("Arial", 72),
                new SolidBrush(Color.FromArgb(opacity, Color.OrangeRed)),
                80,
                  PicBox.Height / 2 - 15);

            int NoofTrials = dt.Rows.Count;
            int NoofParts = dt.Columns.Count - 1;

            intMeanArrayVals = new Double[NoofParts];
            intRangeArrayVals = new Double[NoofParts];
            intSTDEVArrayVals = new Double[NoofParts];
            intXBARArrayVals = new Double[NoofParts];

            if (dt.Rows.Count <= 0)
            {
                return;
            }

            PicBox.Width = dt.Columns.Count * 50 + 40;

            // 1) For the Chart Data Display ---------

     e.Graphics.DrawRectangle(Pens.Black, 10, 10, PicBox.Width - 20, 
                              First_chartDatarectHeight + 78);

            // for the chart data Horizontal Line Display
            e.Graphics.DrawLine(B1pen, 10, 25, PicBox.Width - 10, 25);
            e.Graphics.DrawLine(B1pen, 10, 45, PicBox.Width - 10, 45);
            e.Graphics.DrawLine(B1pen, 10, 65, PicBox.Width - 10, 65);
            e.Graphics.DrawLine(B1pen, 10, 85, PicBox.Width - 10, 85);
            e.Graphics.DrawLine(B1pen, 10, 105, PicBox.Width - 10, 105);
            e.Graphics.DrawLine(B1pen, 10, 125, PicBox.Width - 10, 125);
            e.Graphics.DrawLine(B1pen, 10, 145, PicBox.Width - 10, 145);
            // e.Graphics.DrawLine(B1pen, 10, 165, PicBox.Width - 10, 165);

            // for the chart data Vertical Line Display
            e.Graphics.DrawLine(B1pen, 60, 10, 60, First_chartDatarectHeight + 87);
            e.Graphics.DrawLine(B1pen, 110, 10, 110, First_chartDatarectHeight + 87);

            //-------------

            // DrawItemEventArgs String

            e.Graphics.DrawString("SUM", f12, a1, 14, 10);
            e.Graphics.DrawString("MEAN", f12, a1, 14, 30);
            e.Graphics.DrawString("Range", f12, a1, 14, 50);
            e.Graphics.DrawString("Cp", f12, a1, 14, 70);
            e.Graphics.DrawString("Cpk", f12, a1, 14, 90);
            e.Graphics.DrawString("Pp", f12, a1, 14, 110);
            e.Graphics.DrawString("Ppk", f12, a1, 14, 130);

            // load data
            //Outer Loop for Columns count
            int xLineposition = 110;
            int xStringDrawposition = 14;
            Double[] locStdevarr;
            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;

                locStdevarr = new Double[NoofTrials];

                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);
              locStdevarr[iRow] = System.Convert.ToDouble(dt.Rows[iRow][iCol].ToString());
                }

                xLineposition = xLineposition + 50;
                xStringDrawposition = xStringDrawposition + 50;

       e.Graphics.DrawLine(B1pen, xLineposition, 10, xLineposition, 
                           First_chartDatarectHeight + 87);
                //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, 30);

                //RANGE Data Display
                Rangeresult = maxRangeValue - minRangeValue;
       e.Graphics.DrawString(Math.Round(Rangeresult, 3).ToString(), 
                             f10, a2, xStringDrawposition, 50);

                //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;
                intSTDEVArrayVals[iCol - 1] = StandardDeviation(locStdevarr);
            }

            //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);

            //2.1) Status Display inside pic grid +++++++++++++++++++++++++++

            int XCirclegDrawposition = 24;
            int YCirclegDrawposition = 147;

            xStringDrawposition = 14;
            for (int i = 0; i < intMeanArrayVals.Length; i++)
            {
                Color pointColor = new Color();
                pointColor = Color.YellowGreen;
                XCirclegDrawposition = XCirclegDrawposition + 50;
                Point p1 = new Point();
                p1.X = XCirclegDrawposition;
                p1.Y = YCirclegDrawposition;

                if (intMeanArrayVals[i] < XBARLCL)
                {
                    pointColor = Color.Red;
                }
                else if (intMeanArrayVals[i] > XBARUCL)
                {
                    pointColor = Color.Red;
                }

                Pen pen = new Pen(Color.SeaGreen);
                e.Graphics.DrawPie(pen, p1.X, p1.Y, 18, 18, 0, 360);
                e.Graphics.FillPie(new SolidBrush(pointColor), p1.X, p1.Y, 18, 18, 10, 360);

                pen = new Pen(Color.Black);
                e.Graphics.DrawPie(pen, p1.X + 3, p1.Y + 4, 2, 2, 10, 360);
                e.Graphics.DrawPie(pen, p1.X + 11, p1.Y + 4, 2, 2, 10, 360);
                e.Graphics.DrawPie(pen, p1.X + 5, p1.Y + 12, 8, 4, 10, 180);

                // 1)
                //Cp Calculation (((((((((((((((((((((((((((
                //Cp=(USL-LSL/6SIGMA) -> USL-LSL/6*RBAR/d2

                Double d2 = d2Return(NoofTrials);
                Double USLResult = USLs - LSLs;
                Double RBARS = intRangeArrayVals[i] / NoofTrials;
                Double Sigma = RBARS / d2;

                Double CpResult = USLResult / 6 * Sigma;

                xStringDrawposition = xStringDrawposition + 50;
    e.Graphics.DrawString(Math.Round(CpResult, 3).ToString(), 
                          f10, a2, xStringDrawposition, 70);

                //End Cp Calculation  ))))))))))))))

                // 2)

                //Cpk Calculation \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

                //Cpk=min(USL-XBAR/3Sigma,LSL-XBAR/3Sigma)

                Double CpU = USLs - intMeanArrayVals[i] / 3 * Sigma;

                Double CpL = intMeanArrayVals[i] - LSLs / 3 * Sigma;

                Double CpkResult = Math.Min(CpU, CpL);

                if (CpkResult < CpkPpKAcceptanceValue)
                {
    e.Graphics.DrawString(Math.Round(CpkResult, 3).ToString(), 
                          f10, a3, xStringDrawposition, 90);
                }
                else
                {
    e.Graphics.DrawString(Math.Round(CpkResult, 3).ToString(), 
                          f10, a2, xStringDrawposition, 90);
                }

                //End Cpk Calculation  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

                // 3)
                //Pp Calculation {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{

                //Pp=(USL-LSL/6SIGMA) -> USL-LSL/6 STDEV

                Double PpResult = USLResult / 6 * intSTDEVArrayVals[i];

    e.Graphics.DrawString(Math.Round(PpResult, 3).ToString(), 
                          f10, a2, xStringDrawposition, 110);

                //End Pp Calculation  }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}

                // 4)

                //PpK Calculation ``````````````````````````````````````````````````````

                //PpK=min(USL-XBAR/3STDEV,LSL-XBAR/3STDEVa)
                Double PpU = USLs - intMeanArrayVals[i] / 3 * intSTDEVArrayVals[i];
                Double PpL = intMeanArrayVals[i] - LSLs / 3 * intSTDEVArrayVals[i];
                Double PpkResult = Math.Min(PpU, PpL);
                if (PpkResult < CpkPpKAcceptanceValue)
                {
     e.Graphics.DrawString(Math.Round(PpkResult, 3).ToString(), 
                           f10, a3, xStringDrawposition, 130);
                }
                else
                {
    e.Graphics.DrawString(Math.Round(PpkResult, 3).ToString(), 
                          f10, a2, xStringDrawposition, 130);
                }
                // end of Ppk `````````````````````````````````````````````````````````````
            }

            //end of 2.1) ++++++++++++++++

            //---------------------------------
            //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 + 96, 
                             PicBox.Width - 20, chartAvarageDatarectHeight);

            e.Graphics.DrawLine(B2pen, 476, 194, 480, 176);
            e.Graphics.DrawString
            ("MEAN CHART", f12, a1, 14, First_chartDatarectHeight + 98);
            e.Graphics.DrawString
            ("XBarS:", f12, a1, 160, First_chartDatarectHeight + 98);
    e.Graphics.DrawString(Math.Round(XDoublkeBAR, 3).ToString(), 
                          f12, a2, 202, First_chartDatarectHeight + 98);
            e.Graphics.DrawString("UCL:", f12, a1, 300, First_chartDatarectHeight + 98);
    e.Graphics.DrawString(Math.Round(XBARUCL, 3).ToString(), 
                          f12, a2, 330, First_chartDatarectHeight + 98);

            e.Graphics.DrawString("LCL:", f12, a1, 400, First_chartDatarectHeight + 98);
    e.Graphics.DrawString(Math.Round(XBARLCL, 3).ToString(), 
                          f12, a2, 430, First_chartDatarectHeight + 98);

            e.Graphics.DrawString("RANGE CHART", f12, a1, 490, First_chartDatarectHeight + 98);

            e.Graphics.DrawString
            ("RBar : ", f12, a1, 600, First_chartDatarectHeight + 98);
    e.Graphics.DrawString(Math.Round(RBAR, 3).ToString(), f12, 
               a2, 638, First_chartDatarectHeight + 98);
            e.Graphics.DrawString("UCL : ", f12, a1, 700, First_chartDatarectHeight + 98);
    e.Graphics.DrawString(Math.Round(RANGEUCL, 3).ToString(), 
                          f12, a2, 734, First_chartDatarectHeight + 98);
            e.Graphics.DrawString("LCL : ", f12, a1, 800, First_chartDatarectHeight + 98);
    e.Graphics.DrawString(Math.Round(RANGELCL, 3).ToString(), 
                          f12, a2, 834, First_chartDatarectHeight + 98);

            // vertical Line
            e.Graphics.DrawLine(B2pen, 860, 194, 866, 176);
            e.Graphics.DrawString("USL : ", f12, a1, 880, First_chartDatarectHeight + 98);
    e.Graphics.DrawString(Math.Round(USLs, 3).ToString(), 
               f12, a2, 910, First_chartDatarectHeight + 98);
        e.Graphics.DrawString("LSL : ", f12, a1, 960, First_chartDatarectHeight + 98);
    e.Graphics.DrawString(Math.Round(LSLs, 3).ToString(), 
                          f12, a2, 990, First_chartDatarectHeight + 98);

            //Mean Line Chart
    DrawLineChart(e.Graphics, intMeanArrayVals, XBARUCL, XBARLCL, 
    PicBox.Width - 70, 154, 60, 170, "MEAN", XDoublkeBAR);

    DrawLineChart(e.Graphics, intRangeArrayVals, RANGEUCL, 
    RANGELCL, PicBox.Width - 70, 154, 60, 340, "RANGE", RBAR);
            //End 3)---------------------
        }

2) 演示程序

现在我们创建一个 Windows 应用程序,添加并测试我们的 "ShanuCPCPKChart" 用户控件。

  1. 创建一个新的 Windows 项目。
  2. 打开您的窗体,然后在工具箱 > 右键单击 > 选择项 > 浏览并选择您的用户控件 DLL 并添加。
  3. 将用户控件拖到您的 Windows 窗体上。
  4. 调用用户控件的 "Bindgrid" 方法,并将 Datatable 传递给 Usercontrol 并检查结果。

全局变量声明

#region Local Vairables
        DataTable dt = new DataTable();
        private static readonly Random random = new Random();
        Double gridMinvalue = 1.2;
        Double gridMaxvalue = 2.4;
        int totalColumntoDisplay = 20;
        Double USLs = 2.27;
        Double LSLs = 1.26;
        Double CpkPpkAcceptanceValue = 1.33;
        #endregion

窗体加载事件

在窗体加载事件中,我调用 loadGridColumn() 方法。在此函数中,我为 datatable 添加了列。我使用了 20 列,将用于添加 20 个样本数据,每个样本包含 5 次试验。

//Create Datatable  Colums.
        public void loadGridColums()
    {
      dt.Columns.Add("No");
for (int jval = 1; jval <= totalColumntoDisplay; jval++)
             {
                dt.Columns.Add(jval.ToString());
             }
        }

接下来在窗体加载事件中,我调用 loadgrid() 方法。在此方法中,我生成 20 列的样本随机数来绘制我们的图表。

public void loadgrid()
        {
            dt.Clear();
            dt.Rows.Clear();
            for (int i = 1; i <= 5; i++)
            {
               DataRow row = dt.NewRow();
                row["NO"] = i.ToString();
                for (int jval = 1; jval <= totalColumntoDisplay; jval++)
                {
                    row[jval.ToString()] = RandomNumberBetween(gridMinvalue, gridMaxvalue);
                }            

                dt.Rows.Add(row);
            }
            dataGridView1.AutoResizeColumns();
            dataGridView1.DataSource = dt;
            dataGridView1.AutoResizeColumns();
        }

接下来在窗体加载中,我已将 USL、LSL、Cpk 值和 Datatable 传递给 "shanuCPCPKChart" 用户控件,以生成 XBAR 和极差图表,并显示 Cp、Cpk、Pp 和 Ppk 结果。

private void Form1_Load(object sender, EventArgs e)
        {
            loadGridColums();
            loadgrid();
            USLs = Convert.ToDouble(txtusl.Text);
            LSLs = Convert.ToDouble(txtLSL.Text);
            CpkPpkAcceptanceValue = Convert.ToDouble(txtData.Text);
            shanuCPCPKChart.USL = USLs;
            shanuCPCPKChart.LSL = LSLs;
            shanuCPCPKChart.CpkPpKAcceptanceValue = CpkPpkAcceptanceValue;
            shanuCPCPKChart.Bindgrid(dt);  
        }

为了显示实时数据图表结果,我在这里使用了计时器,可以通过随机数据绑定数据,并将所有结果传递给用户控件以刷新和显示结果。

private void timer1_Tick(object sender, EventArgs e)
        {
            loadgrid();
            USLs = Convert.ToDouble(txtusl.Text);
            LSLs = Convert.ToDouble(txtLSL.Text);
            CpkPpkAcceptanceValue = Convert.ToDouble(txtData.Text);
            shanuCPCPKChart.USL = USLs;
            shanuCPCPKChart.LSL = LSLs;
            shanuCPCPKChart.CpkPpKAcceptanceValue = CpkPpkAcceptanceValue;
            shanuCPCPKChart.Bindgrid(dt);  
        }

关注点

我很乐意地说,这将是第一个带有源代码的免费 SPC Cp、Cpk、Pp 和 Ppk 图表控件。如果您喜欢这些控件,请为本文投票。

历史

  • 2015 年 7 月 2 日:初始版本
© . All rights reserved.