init: 潍柴发动机线 管理后端 项目首次入库

This commit is contained in:
XingCheng3
2026-06-08 12:04:29 +08:00
commit 973692401d
152 changed files with 116669 additions and 0 deletions

View File

@@ -0,0 +1,144 @@
using System;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Web.UI.DataVisualization.Charting;
/// <summary>
///CalculateData 的摘要说明
/// </summary>
public class CalculateData
{
public CalculateData()
{
//
//TODO: 在此处添加构造函数逻辑
//
}
/// <summary>
/// 观测值最大值
/// </summary>
/// <param name="Xn">子组观测值</param>
/// <returns></returns>
static private double Max(double[] Xn)
{
double temp;
temp = Xn[0];
for (int i = 0; i < Xn.Length; i++)
{
temp = (Xn[i] > temp) ? Xn[i] : temp;
}
return temp;
}
/// <summary>
/// 观测值最小值
/// </summary>
/// <param name="Xn">子组观测值</param>
/// <returns></returns>
static private double Min(double[] Xn)
{
double temp;
temp = Xn[0];
for (int i = 0; i < Xn.Length; i++)
{
temp = (Xn[i] < temp) ? Xn[i] : temp;
}
return temp;
}
/// <summary>
/// 计算X在区间[ValueDownValueUp]的数量
/// </summary>
/// <param name="X"></param>
/// <param name="GroupCount"></param>
/// <param name="ValueDown"></param>
/// <param name="ValueUp"></param>
/// <param name="Yk"></param>
static private void SumRang(double[] X, int GroupCount, double[] ValueDown, double[] ValueUp, out double[] Yk, out double[] YkCount)
{
int temp = 0;
//总数量
int allCount = 0;
Yk = new double[GroupCount];
YkCount = new double[GroupCount];
for (int j = 0; j < GroupCount - 1; j++)
{
temp = 0;
for (int i = 0; i < X.Length; i++)
{
if (X[i] >= ValueDown[j] & X[i] < ValueUp[j])
{
temp = temp + 1;
allCount++;
}
}
Yk[j] = temp;
}
for (int i = 0; i < X.Length; i++)
{
if (X[i] >= ValueDown[GroupCount - 1] & X[i] <= ValueUp[GroupCount - 1])
{
temp = temp + 1;
allCount++;
}
}
Yk[GroupCount - 1] = temp;
for (int i = 0; i < Yk.Length; i++)
{
YkCount[i] = Yk[i];
Yk[i] = Yk[i] / (double)allCount * 100;
}
}
public static void DataPareto(double[] Data,int GroupCount)
{
Spc_Data_Pareto m_Spc_Data_Pareto = new Spc_Data_Pareto();
//数组最大值
double minValue = Min(Data);
//数组最小值
double maxValue = Max(Data);
//X轴刻度
double XSpan = (maxValue - minValue) / GroupCount;
//X轴下刻度线
double[] XSpanDown = new double[GroupCount];
//X轴上刻度线
double[] XSpanUp = new double[GroupCount];
double[] Yk=new double[GroupCount];
XSpanDown[0] = minValue;
XSpanUp[0] = minValue + XSpan;
for (int i = 1; i < GroupCount; i++)
{
XSpanDown[i] = minValue + i * XSpan;
XSpanUp[i] = minValue + (i + 1) * XSpan;
}
//数据在区间数组的数量
SumRang(Data, GroupCount, XSpanDown, XSpanUp, out Yk, out m_Spc_Data_Pareto.YCount);
for (int i = 0; i < GroupCount; i++)
{
if (i == 0)
{
m_Spc_Data_Pareto.AxisX[i] = minValue + XSpan / 2;
}
else
{
m_Spc_Data_Pareto.AxisX[i] = minValue + XSpan;
}
}
}
}
/// <summary>
/// 排列图数据
/// </summary>
public class Spc_Data_Pareto
{
//X轴数据
public double[] AxisX;
//所有数据在X轴各范围内的数量
public double[] YCount;
}

View File

@@ -0,0 +1,225 @@
using System;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Web.UI.DataVisualization.Charting;
using System.Data.SqlClient;
using System.Web.UI.DataVisualization.Charting.Utilities;
/// <summary>
///DrawChart 的摘要说明
/// </summary>
public partial class DrawChart
{
/// <summary>
/// 排列图
/// </summary>
/// <param name="X"></param>
/// <param name="chart1"></param>
public static void ChartQualityData_Pareto(double[] X,Chart chart1)
{
int n=8;
chart1.Series["RawData"].Points.DataBindY(X);
DrawPareto drawPareto = new DrawPareto();
drawPareto.SegmentIntervalNumber = n;
drawPareto.ShowPercentOnSecondaryYAxis = false;
drawPareto.CreatePareto(chart1, "RawData", "Histogram");
drawPareto.MakeParetoChart(chart1, "Histogram", "Pareto");
// Set chart types for output data
chart1.Series["Pareto"].ChartType = SeriesChartType.Line;
// set the markers for each point of the Pareto Line
chart1.Series["Pareto"].IsValueShownAsLabel = true;
chart1.Series["Pareto"].MarkerColor = Color.Red;
chart1.Series["Pareto"].MarkerBorderColor = Color.MidnightBlue;
chart1.Series["Pareto"].MarkerStyle = MarkerStyle.Circle;
chart1.Series["Pareto"].MarkerSize = 6;
chart1.Series["Pareto"].LabelFormat = "0.#"; // format with one decimal and leading zero
// Set Color of line Pareto chart
chart1.Series["Pareto"].Color = Color.FromArgb(252, 180, 65);
}
/// <summary>
/// 直方图
/// </summary>
/// <param name="X"></param>
/// <param name="chart1"></param>
public static void ChartQualityData_Histogram(double[] X, Chart chart1)
{
int n = 8;
chart1.Series["RawData"].Points.DataBindY(X);
// Populate single axis data distribution series. Show Y value of the
// data series as X value and set all Y values to 1.
foreach (DataPoint dataPoint in chart1.Series["RawData"].Points)
{
chart1.Series["DataDistribution"].Points.AddXY(dataPoint.YValues[0], 1);
}
// Create a histogram series
HistogramChartHelper histogramHelper = new HistogramChartHelper();
histogramHelper.SegmentIntervalNumber = n;
histogramHelper.ShowPercentOnSecondaryYAxis = false;
// NOTE: Interval width may be specified instead of interval number
//histogramHelper.SegmentIntervalWidth = 15;
histogramHelper.CreateHistogram(chart1, "RawData", "Histogram");
}
/// <summary>
/// 分析正态分布图
/// </summary>
/// <param name="X">被分析数据组</param>
/// <param name="Usl">理论上限</param>
/// <param name="Lsl">理论下限</param>
/// <param name="chart1"></param>
public static void ChartQualityData_NormalDistribution(double[] X, double Usl, double Lsl, Chart chart1)
{
double x;
double s;
double QU;
double QL;
double cp;
double cpk;
double[] sx;
double[] sy;
double ValueUp = Max(X);
double ValueDown = Min(X);
//计算SPC参数
SpcCaculator.SpcValue(X, ref Usl, ref Lsl, out x, out s, out QU, out QL, out cp, out cpk, out sx, out sy);
//坐标轴
double ValueUpX = Convert.ToDouble(Max(sx).ToString("F4"));
double ValueDownX = Convert.ToDouble(Min(sx).ToString("F4"));
double ValueUpY = Convert.ToDouble(Max(sy).ToString("F4"));
ValueDownX = Math.Min(ValueDownX, Lsl);
ValueDownX = Math.Min(ValueDownX, QL);
ValueUpX = Math.Max(ValueUpX, Usl);
ValueUpX = Math.Max(ValueUpX, QU);
double X1 = (ValueUpX - ValueDownX) / 10;
chart1.ChartAreas["ChartArea1"].AxisX.Minimum = Math.Round(ValueDownX - X1, 4);
chart1.ChartAreas["ChartArea1"].AxisX.Maximum = Math.Round(ValueUpX + X1, 4);
chart1.ChartAreas["ChartArea1"].AxisY.Minimum = 0;
chart1.ChartAreas["ChartArea1"].AxisY.Maximum = Math.Round(ValueUpY + ValueUpY / 10, 4);
//绘图正态分布曲线(共取了11个点)
for (int i = 0; i < sx.Length; i++)
{
chart1.Series[0].Points.AddXY(Math.Round(sx[i], 4), Math.Round(sy[i], 4));
}
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[1].IntervalOffset = sx[5];
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[1].Text = "SL=" + sx[5].ToString("F4");
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[2].IntervalOffset = Usl;
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[2].Text = "USL=" + Usl.ToString("F4");
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[3].IntervalOffset = Lsl;
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[3].Text = "LSL=" + Lsl.ToString("F4");
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[4].IntervalOffset = QL;
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[4].Text = "QL=" + QL.ToString("F4");
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[5].IntervalOffset = QU;
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[5].Text = "QU=" + QU.ToString("F4");
//将CpCpk绘制到图形中
DarwCpCpk(chart1, cp, cpk);
//TextAnnotation annotation3;
//annotation3 = new TextAnnotation();
//annotation3.Text = "Cp=" + cp.ToString("F2");
//annotation3.ForeColor = Color.Black;
//annotation3.Font = new Font("Arial", 11); ;
//annotation3.X = 60;
//annotation3.Y = 90;
//chart1.Annotations.Add(annotation3);
//annotation3 = new TextAnnotation();
//annotation3.Text = "Cpk=" + cpk.ToString("F2");
//annotation3.ForeColor = Color.Black;
//annotation3.Font = new Font("Arial", 11); ;
//annotation3.X = 80;
//annotation3.Y = 90;
//chart1.Annotations.Add(annotation3);
}
/// <summary>
/// SPC分析基本趋势图
/// </summary>
/// <param name="dt"></param>
/// <param name="chart1"></param>
public static void ChartQualityData_TrendPictureBasic_new(DataTable dt, double Usl, double Lsl, Chart chart1)
{
double x;
double s;
double QU;
double QL;
double cp;
double cpk;
double[] sx;
double[] sy;
double[] X;
if (dt.Rows.Count < 3) return;
X = new double[dt.Rows.Count];
for (int i = 0; i < dt.Rows.Count; i++)
{
X[i] = Convert.ToDouble(dt.Rows[i][0]);
}
double ValueUp = Max(X);
double ValueDown = Min(X);
//计算SPC参数
SpcCaculator.SpcValue(X, ref Usl, ref Lsl, out x, out s, out QU, out QL, out cp, out cpk, out sx, out sy);
//坐标轴
double ValueUpX;
double ValueDownX;
ValueDownX = Math.Min(ValueDown, Lsl);
ValueDownX = Math.Min(ValueDownX, QL);
ValueUpX = Math.Max(ValueUp, Usl);
ValueUpX = Math.Max(ValueUpX, QU);
double X1 = (ValueUpX - ValueDownX) / 10;
chart1.ChartAreas["ChartArea1"].AxisY.Minimum = Math.Round(ValueDownX - X1, 4);
chart1.ChartAreas["ChartArea1"].AxisY.Maximum = Math.Round(ValueUpX + X1, 4);
chart1.ChartAreas["ChartArea1"].AxisY.StripLines[1].IntervalOffset = sx[5];
chart1.ChartAreas["ChartArea1"].AxisY.StripLines[1].Text = "SL=" + sx[5].ToString("F4");
chart1.ChartAreas["ChartArea1"].AxisY.StripLines[2].IntervalOffset = Usl;
chart1.ChartAreas["ChartArea1"].AxisY.StripLines[2].Text = "USL=" + Usl.ToString("F4");
chart1.ChartAreas["ChartArea1"].AxisY.StripLines[3].IntervalOffset = Lsl;
chart1.ChartAreas["ChartArea1"].AxisY.StripLines[3].Text = "LSL=" + Lsl.ToString("F4");
chart1.ChartAreas["ChartArea1"].AxisY.StripLines[4].IntervalOffset = QU;
chart1.ChartAreas["ChartArea1"].AxisY.StripLines[4].Text = "QU=" + QU.ToString("F4");
chart1.ChartAreas["ChartArea1"].AxisY.StripLines[5].IntervalOffset = QL;
chart1.ChartAreas["ChartArea1"].AxisY.StripLines[5].Text = "QL=" + QL.ToString("F4");
chart1.Series[0].Points.DataBind(dt.DefaultView, "", "测量值", "Tooltip=ToolTip");
//将CpCpk绘制到图形中
DarwCpCpk(chart1, cp, cpk);
}
/// <summary>
/// 将CpCpk绘制到图形中
/// </summary>
/// <param name="chart1"></param>
/// <param name="cp"></param>
/// <param name="cpk"></param>
static private void DarwCpCpk(Chart chart1,double cp,double cpk)
{
TextAnnotation annotation;
annotation = (TextAnnotation)chart1.Annotations["TextAnnotationCp"];
annotation.Text = "Cp=" + cp.ToString("F2");
annotation = (TextAnnotation)chart1.Annotations["TextAnnotationCpk"];
annotation.Text = "Cpk=" + cpk.ToString("F2");
}
}

View File

@@ -0,0 +1,787 @@
using System;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Web.UI.DataVisualization.Charting;
using System.Data.SqlClient;
/// <summary>
///DrawChart 的摘要说明
/// </summary>
public partial class DrawChart
{
public static void ChartQualityData_Pareto(DataTable dt,int n, Chart chart1)
{
chart1.Series["RawData"].Points.DataBindY(dt.Rows, "测量值");
DrawPareto drawPareto = new DrawPareto();
drawPareto.SegmentIntervalNumber = n;
drawPareto.ShowPercentOnSecondaryYAxis = false;
drawPareto.CreatePareto(chart1, "RawData", "Histogram");
drawPareto.MakeParetoChart(chart1, "Histogram", "Pareto");
// Set chart types for output data
chart1.Series["Pareto"].ChartType = SeriesChartType.Line;
// set the markers for each point of the Pareto Line
chart1.Series["Pareto"].IsValueShownAsLabel = true;
chart1.Series["Pareto"].MarkerColor = Color.Red;
chart1.Series["Pareto"].MarkerBorderColor = Color.MidnightBlue;
chart1.Series["Pareto"].MarkerStyle = MarkerStyle.Circle;
chart1.Series["Pareto"].MarkerSize = 6;
chart1.Series["Pareto"].LabelFormat = "0.#"; // format with one decimal and leading zero
// Set Color of line Pareto chart
chart1.Series["Pareto"].Color = Color.FromArgb(252, 180, 65);
}
/// <summary>
/// SPC分析正态分布图
/// </summary>
/// <param name="X"></param>
/// <param name="n"></param>
/// <param name="chart1"></param>
public static void ChartQualityData_NormalDistribution(double[] X, int n, Chart chart1)
{
double ValueUp = Max(X);
double ValueDown = Min(X);
//绘图数据
ASPNet_Drawing.CSpc_Data_Cpk Spc_Data_Cpk = ASPNet_Drawing.Spc_Data.Cpk(X, n, ValueUp, ValueDown);
//坐标轴
double ValueUpX = Convert.ToDouble(Max(Spc_Data_Cpk.NormalDistributionX).ToString("F2"));
double ValueDownX = Convert.ToDouble(Min(Spc_Data_Cpk.NormalDistributionX).ToString("F2"));
double ValueUpY = Convert.ToDouble(Max(Spc_Data_Cpk.NormalDistributionY).ToString("F2"));
double X1 = (ValueUpX - ValueDownX) / 10;
chart1.ChartAreas["ChartArea1"].AxisX.Minimum = Math.Round(ValueDownX - X1, 2);
chart1.ChartAreas["ChartArea1"].AxisX.Maximum = Math.Round(ValueUpX + X1, 2);
chart1.ChartAreas["ChartArea1"].AxisY.Minimum = 0;
chart1.ChartAreas["ChartArea1"].AxisY.Maximum = Math.Round(ValueUpY + ValueUpY / 10, 2);
//绘图
for (int i = 0; i < Spc_Data_Cpk.NormalDistributionX.Length; i++)
{
chart1.Series[0].Points.AddXY(Math.Round(Spc_Data_Cpk.NormalDistributionX[i], 2), Math.Round(Spc_Data_Cpk.NormalDistributionY[i], 2));
}
// Set Strip line item
//chart1.ChartAreas["ChartArea1"].AxisX.StripLines[0].IntervalOffset = Spc_Data_Cpk.LSL;
//chart1.ChartAreas["ChartArea1"].AxisX.StripLines[0].StripWidth = Spc_Data_Cpk.USL - Spc_Data_Cpk.LSL;
// Set Strip line item
//double SL = (ValueUpX + ValueDownX) / 2;
//double USL = SL + 3 * Spc_Data_Cpk.Singma;
//double LSL = SL - 3 * Spc_Data_Cpk.Singma;
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[1].IntervalOffset = Spc_Data_Cpk.NormalDistributionX[4];
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[1].Text = "SL=" + Spc_Data_Cpk.NormalDistributionX[4].ToString("F2");
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[2].IntervalOffset = Spc_Data_Cpk.NormalDistributionX[1];
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[2].Text = "USL=" + Spc_Data_Cpk.NormalDistributionX[1].ToString("F2");
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[3].IntervalOffset = Spc_Data_Cpk.NormalDistributionX[7];
chart1.ChartAreas["ChartArea1"].AxisX.StripLines[3].Text = "LSL=" + Spc_Data_Cpk.NormalDistributionX[7].ToString("F2");
//TextAnnotation annotation1 = new TextAnnotation();
//annotation1.Text = "Cpk=" + Spc_Data_Cpk.Cpk.ToString("F2");
//annotation1.ForeColor = Color.Black;
//annotation1.Font = new Font("Arial", 11); ;
//annotation1.X = 80;
//annotation1.Y = 8;
//chart1.Annotations.Add(annotation1);
//TextAnnotation annotation2 = new TextAnnotation();
//annotation2.Text = "CPL=" + Spc_Data_Cpk.CPL.ToString("F2");
//annotation2.ForeColor = Color.Black;
//annotation2.Font = new Font("Arial", 11); ;
//annotation2.X = 80;
//annotation2.Y = 13;
//chart1.Annotations.Add(annotation2);
//TextAnnotation annotation3 = new TextAnnotation();
//annotation3.Text = "CPU=" + Spc_Data_Cpk.CPU.ToString("F2");
//annotation3.ForeColor = Color.Black;
//annotation3.Font = new Font("Arial", 11); ;
//annotation3.X = 80;
//annotation3.Y = 18;
//chart1.Annotations.Add(annotation3);
}
/// <summary>
/// SPC分析工序能力图
/// 在均值级差图中
/// </summary>
/// <param name="X"></param>
/// <param name="n"></param>
/// <param name="chart1"></param>
public static void ChartQualityData_Cpk_XR(double[] X, int n, Chart chart1)
{
double ValueUp = Max(X);
double ValueDown = Min(X);
//绘图数据
ASPNet_Drawing.CSpc_Data_Cpk Spc_Data_Cpk = ASPNet_Drawing.Spc_Data.Cpk(X, n, ValueUp, ValueDown);
//坐标轴
double ValueUpX = Convert.ToDouble(Max(Spc_Data_Cpk.NormalDistributionX).ToString("F2"));
double ValueDownX = Convert.ToDouble(Min(Spc_Data_Cpk.NormalDistributionX).ToString("F2"));
double ValueUpY = Convert.ToDouble(Max(Spc_Data_Cpk.NormalDistributionY).ToString("F2"));
double X1 = (ValueUpX - ValueDownX) / 10;
chart1.ChartAreas["ChartArea_Cpk"].AxisX.Minimum = Math.Round(ValueDownX - X1, 2);
chart1.ChartAreas["ChartArea_Cpk"].AxisX.Maximum = Math.Round(ValueUpX + X1, 2);
chart1.ChartAreas["ChartArea_Cpk"].AxisY.Minimum = 0;
chart1.ChartAreas["ChartArea_Cpk"].AxisY.Maximum = Math.Round(ValueUpY + ValueUpY / 10, 2);
//绘图
for (int i = 0; i < Spc_Data_Cpk.NormalDistributionX.Length; i++)
{
chart1.Series["Series_Cpk"].Points.AddXY(Math.Round(Spc_Data_Cpk.NormalDistributionX[i], 2), Math.Round(Spc_Data_Cpk.NormalDistributionY[i], 2));
}
ASPNet_Drawing.CSpc_Data_XR Spc_Data_XR = ASPNet_Drawing.Spc_Data.XR(X, n);
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[1].IntervalOffset = Spc_Data_Cpk.NormalDistributionX[4];
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[1].Text = "SL=" + Spc_Data_XR.CL_X.ToString("F2");
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[2].IntervalOffset = Spc_Data_Cpk.NormalDistributionX[1];
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[2].Text = "USL=" + Spc_Data_XR.UCL_X.ToString("F2");
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[3].IntervalOffset = Spc_Data_Cpk.NormalDistributionX[7];
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[3].Text = "LSL=" + Spc_Data_XR.LCL_X.ToString("F2");
TextAnnotation annotation1 = new TextAnnotation();
annotation1.Text = "Cpk=" + Spc_Data_Cpk.Cpk.ToString("F2");
annotation1.ForeColor = Color.Black;
annotation1.Font = new Font("Arial", 6); ;
annotation1.X = 27;
annotation1.Y = 3.5;
chart1.Annotations.Add(annotation1);
TextAnnotation annotation2 = new TextAnnotation();
annotation2.Text = "CPL=" + Spc_Data_Cpk.CPL.ToString("F2");
annotation2.ForeColor = Color.Black;
annotation2.Font = new Font("Arial", 6); ;
annotation2.X = 27;
annotation2.Y = 5;
chart1.Annotations.Add(annotation2);
TextAnnotation annotation3 = new TextAnnotation();
annotation3.Text = "CPU=" + Spc_Data_Cpk.CPU.ToString("F2");
annotation3.ForeColor = Color.Black;
annotation3.Font = new Font("Arial", 6); ;
annotation3.X = 27;
annotation3.Y = 6.5;
chart1.Annotations.Add(annotation3);
}
/// <summary>
/// SPC分析工序能力图
/// 在均值标准差图中
/// </summary>
/// <param name="X"></param>
/// <param name="n"></param>
/// <param name="chart1"></param>
public static void ChartQualityData_Cpk_XS(double[] X, int n, Chart chart1)
{
double ValueUp = Max(X);
double ValueDown = Min(X);
//绘图数据
ASPNet_Drawing.CSpc_Data_Cpk Spc_Data_Cpk = ASPNet_Drawing.Spc_Data.Cpk(X, n, ValueUp, ValueDown);
//坐标轴
double ValueUpX = Convert.ToDouble(Max(Spc_Data_Cpk.NormalDistributionX).ToString("F2"));
double ValueDownX = Convert.ToDouble(Min(Spc_Data_Cpk.NormalDistributionX).ToString("F2"));
double ValueUpY = Convert.ToDouble(Max(Spc_Data_Cpk.NormalDistributionY).ToString("F2"));
double X1 = (ValueUpX - ValueDownX) / 10;
chart1.ChartAreas["ChartArea_Cpk"].AxisX.Minimum = Math.Round(ValueDownX - X1, 2);
chart1.ChartAreas["ChartArea_Cpk"].AxisX.Maximum = Math.Round(ValueUpX + X1, 2);
chart1.ChartAreas["ChartArea_Cpk"].AxisY.Minimum = 0;
chart1.ChartAreas["ChartArea_Cpk"].AxisY.Maximum = Math.Round(ValueUpY + ValueUpY / 10, 2);
//绘图
for (int i = 0; i < Spc_Data_Cpk.NormalDistributionX.Length; i++)
{
chart1.Series["Series_Cpk"].Points.AddXY(Math.Round(Spc_Data_Cpk.NormalDistributionX[i], 2), Math.Round(Spc_Data_Cpk.NormalDistributionY[i], 2));
}
ASPNet_Drawing.CSpc_Data_XR Spc_Data_XR = ASPNet_Drawing.Spc_Data.XR(X, n);
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[1].IntervalOffset = Spc_Data_Cpk.NormalDistributionX[4];
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[1].Text = "SL=" + Spc_Data_XR.CL_X.ToString("F2");
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[2].IntervalOffset = Spc_Data_Cpk.NormalDistributionX[1];
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[2].Text = "USL=" + Spc_Data_XR.UCL_X.ToString("F2");
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[3].IntervalOffset = Spc_Data_Cpk.NormalDistributionX[7];
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[3].Text = "LSL=" + Spc_Data_XR.LCL_X.ToString("F2");
TextAnnotation annotation1 = new TextAnnotation();
annotation1.Text = "Cpk=" + Spc_Data_Cpk.Cpk.ToString("F2");
annotation1.ForeColor = Color.Black;
annotation1.Font = new Font("Arial", 6); ;
annotation1.X = 27;
annotation1.Y = 3.5;
chart1.Annotations.Add(annotation1);
TextAnnotation annotation2 = new TextAnnotation();
annotation2.Text = "CPL=" + Spc_Data_Cpk.CPL.ToString("F2");
annotation2.ForeColor = Color.Black;
annotation2.Font = new Font("Arial", 6); ;
annotation2.X = 27;
annotation2.Y = 5;
chart1.Annotations.Add(annotation2);
TextAnnotation annotation3 = new TextAnnotation();
annotation3.Text = "CPU=" + Spc_Data_Cpk.CPU.ToString("F2");
annotation3.ForeColor = Color.Black;
annotation3.Font = new Font("Arial", 6); ;
annotation3.X = 27;
annotation3.Y = 6.5;
chart1.Annotations.Add(annotation3);
}
/// <summary>
/// SPC分析工序能力图
/// </summary>
/// <param name="X"></param>
/// <param name="n"></param>
/// <param name="chart1"></param>
public static void ChartQualityData_Cpk(double[] X, int n, Chart chart1)
{
double ValueUp = Max(X);
double ValueDown = Min(X);
//绘图数据
ASPNet_Drawing.CSpc_Data_Cpk Spc_Data_Cpk = ASPNet_Drawing.Spc_Data.Cpk(X, n, ValueUp, ValueDown);
//坐标轴
double ValueUpX = Convert.ToDouble(Max(Spc_Data_Cpk.NormalDistributionX).ToString("F2"));
double ValueDownX = Convert.ToDouble(Min(Spc_Data_Cpk.NormalDistributionX).ToString("F2"));
double ValueUpY = Convert.ToDouble(Max(Spc_Data_Cpk.NormalDistributionY).ToString("F2"));
double X1 = (ValueUpX - ValueDownX) / 10;
chart1.ChartAreas["ChartArea_Cpk"].AxisX.Minimum = Math.Round(ValueDownX - X1, 2);
chart1.ChartAreas["ChartArea_Cpk"].AxisX.Maximum = Math.Round(ValueUpX + X1, 2);
chart1.ChartAreas["ChartArea_Cpk"].AxisY.Minimum = 0;
chart1.ChartAreas["ChartArea_Cpk"].AxisY.Maximum = Math.Round(ValueUpY + ValueUpY / 10, 2);
//绘图
for (int i = 0; i < Spc_Data_Cpk.NormalDistributionX.Length; i++)
{
chart1.Series["Series_Cpk"].Points.AddXY(Math.Round(Spc_Data_Cpk.NormalDistributionX[i], 2), Math.Round(Spc_Data_Cpk.NormalDistributionY[i], 2));
}
// Set Strip line item
//chart1.ChartAreas["ChartArea1"].AxisX.StripLines[0].IntervalOffset = Spc_Data_Cpk.LSL;
//chart1.ChartAreas["ChartArea1"].AxisX.StripLines[0].StripWidth = Spc_Data_Cpk.USL - Spc_Data_Cpk.LSL;
// Set Strip line item
//double SL = (ValueUpX + ValueDownX) / 2;
//double USL = SL + 3 * Spc_Data_Cpk.Singma;
//double LSL = SL - 3 * Spc_Data_Cpk.Singma;
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[1].IntervalOffset = Spc_Data_Cpk.NormalDistributionX[4];
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[1].Text = "SL=" + Spc_Data_Cpk.NormalDistributionX[4].ToString("F2");
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[2].IntervalOffset = Spc_Data_Cpk.NormalDistributionX[1];
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[2].Text = "USL=" + Spc_Data_Cpk.NormalDistributionX[1].ToString("F2");
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[3].IntervalOffset = Spc_Data_Cpk.NormalDistributionX[7];
chart1.ChartAreas["ChartArea_Cpk"].AxisX.StripLines[3].Text = "LSL=" + Spc_Data_Cpk.NormalDistributionX[7].ToString("F2");
TextAnnotation annotation1 = new TextAnnotation();
annotation1.Text = "Cpk=" + Spc_Data_Cpk.Cpk.ToString("F2");
annotation1.ForeColor = Color.Black;
annotation1.Font = new Font("Arial", 11); ;
annotation1.X = 80;
annotation1.Y = 8;
chart1.Annotations.Add(annotation1);
TextAnnotation annotation2 = new TextAnnotation();
annotation2.Text = "CPL=" + Spc_Data_Cpk.CPL.ToString("F2");
annotation2.ForeColor = Color.Black;
annotation2.Font = new Font("Arial", 11); ;
annotation2.X = 80;
annotation2.Y = 13;
chart1.Annotations.Add(annotation2);
TextAnnotation annotation3 = new TextAnnotation();
annotation3.Text = "CPU=" + Spc_Data_Cpk.CPU.ToString("F2");
annotation3.ForeColor = Color.Black;
annotation3.Font = new Font("Arial", 11); ;
annotation3.X = 80;
annotation3.Y = 18;
chart1.Annotations.Add(annotation3);
}
/// <summary>
/// 机床报警频次分析
/// </summary>
/// <param name="dt"></param>
/// <param name="chart1"></param>
public static void ChartMachineAlarm(DataTable dt, Chart chart1)
{
if (dt.Rows.Count == 0)
return;
string seriesName = dt.Rows[0]["工位号"].ToString();
chart1.Series.Add(seriesName);
chart1.Series[seriesName].ChartType = SeriesChartType.Column;
chart1.Series[seriesName].BorderWidth = 2;
chart1.Series[seriesName].ToolTip = "报警文本:#VALX \n报警数量#VALY";
chart1.Series[seriesName].Points.DataBindXY(dt.Rows, "报警文本", dt.Rows, "报警数量");
//for (int i = 0; i < 10; i++)
//{
// chart1.Series[seriesName].Points.AddXY(dt.Rows[i]["报警编号"], dt.Rows[i]["报警数量"]);
//}
//chart1.DataBind();
}
///// <summary>
///// 机床状态频次分析
///// </summary>
///// <param name="dt"></param>
///// <param name="chart1"></param>
//public static void ChartMachineStatus(DataTable dt, Chart chart1)
//{
// foreach (DataRow row in dt.Rows)
// {
// // For each Row add a new series
// string seriesName = row["工位号"].ToString();
// chart1.Series.Add(seriesName);
// chart1.Series[seriesName].ChartType = SeriesChartType.StackedBar;
// chart1.Series[seriesName].BorderWidth = 2;
// chart1.Series[seriesName].ToolTip = "工位号:" + seriesName + "\n 频次:= #VALY";
// for (int colIndex = 2; colIndex < dt.Columns.Count; colIndex++)
// {
// // For each column (column 1 and onward) add the value as a point
// string columnName = dt.Columns[colIndex].ColumnName;
// int YVal = (int)row[columnName];
// chart1.Series[seriesName].Points.AddXY(columnName, YVal);
// }
// }
//}
///// <summary>
///// 成海 2012-04-05
///// </summary>
///// <param name="dt"></param>
///// <param name="chart1"></param>
public static void ChartMachineStatus(DataTable dt, Chart chart1)
{
string seriesNameA = "机床上电";
chart1.Series.Add(seriesNameA);
chart1.Series[seriesNameA].ChartType = SeriesChartType.StackedColumn;
chart1.Series[seriesNameA].BorderWidth = 2;
chart1.Series[seriesNameA].ToolTip = "机床状态:" + seriesNameA + "\n 频次:= #VALY";
chart1.Series[seriesNameA].Color = System.Drawing.Color.DeepPink;
string seriesNameB = "循环开始";
chart1.Series.Add(seriesNameB);
chart1.Series[seriesNameB].ChartType = SeriesChartType.StackedColumn;
chart1.Series[seriesNameB].BorderWidth = 2;
chart1.Series[seriesNameB].ToolTip = "机床状态:" + seriesNameB + "\n 频次:= #VALY";
chart1.Series[seriesNameB].Color = System.Drawing.Color.Green;
string seriesNameC = "机床故障";
chart1.Series.Add(seriesNameC);
chart1.Series[seriesNameC].ChartType = SeriesChartType.StackedColumn;
chart1.Series[seriesNameC].BorderWidth = 2;
chart1.Series[seriesNameC].ToolTip = "机床状态:" + seriesNameC + "\n 频次:= #VALY";
chart1.Series[seriesNameC].Color = System.Drawing.Color.Red;
string seriesNameD = "上料无件";
chart1.Series.Add(seriesNameD);
chart1.Series[seriesNameD].ChartType = SeriesChartType.StackedColumn;
chart1.Series[seriesNameD].BorderWidth = 2;
chart1.Series[seriesNameD].ToolTip = "机床状态:" + seriesNameD + "\n 频次:= #VALY";
chart1.Series[seriesNameD].Color = System.Drawing.Color.Blue;
string seriesNameE = "下料堵塞";
chart1.Series.Add(seriesNameE);
chart1.Series[seriesNameE].ChartType = SeriesChartType.StackedColumn;
chart1.Series[seriesNameE].BorderWidth = 2;
chart1.Series[seriesNameE].ToolTip = "机床状态:" + seriesNameE + "\n 频次:= #VALY";
chart1.Series[seriesNameE].Color = System.Drawing.Color.Yellow;
foreach (DataRow row in dt.Rows)
{
string opName = row["工位号"].ToString();
int YValA = (int)row["机床上电"];
chart1.Series[seriesNameA].Points.AddXY(opName, YValA);
int YValB = (int)row["循环开始"];
chart1.Series[seriesNameB].Points.AddXY(opName, YValB);
int YValC = (int)row["机床故障"];
chart1.Series[seriesNameC].Points.AddXY(opName, YValC);
int YValD = (int)row["上料无件"];
chart1.Series[seriesNameD].Points.AddXY(opName, YValD);
int YValE = (int)row["下料堵塞"];
chart1.Series[seriesNameE].Points.AddXY(opName, YValE);
}
}
/// <summary>
/// SPC分析基本趋势图
/// </summary>
/// <param name="dt"></param>
/// <param name="chart1"></param>
public static void ChartQualityData_TrendPictureBasic(DataTable dt, Chart chart1)
{
//string seriesName = "series1";
//chart1.Series.Add(seriesName);
//chart1.Series[seriesName].MarkerStyle = MarkerStyle.Circle;
//chart1.Series[seriesName].MarkerSize = 5;
//chart1.Series[seriesName].MasrkerColor = Color.Magenta;
//chart1.Series[seriesName].ChartType = SeriesChartType.Line;
//chart1.Series[seriesName].BorderWidth = 1;
chart1.Series[0].Points.DataBind(dt.DefaultView, "", "测量值", "Tooltip=ToolTip");
//chart1.DataBinds();
}
/// <summary>
/// 子组平均值的平均值
/// n 子组大小。单个子组观测值的个数
/// </summary>
/// <param name="X">全部测量数据数组</param>
/// <param name="n">子组大小。单个子组观测值的个数</param>
/// <param name="Xk">子组平均值的数组</param>
/// <returns></returns>
static private double Average(double[] X, int n)
{
//k 子组个数
int k;
k = X.Length / n;
double[] Xi = new double[n];
double[] Xk = new double[k];
for (int j = 0; j < k; j++)
{
for (int i = 0; i < n; i++)
{
Xi[i] = X[j * n + i];
}
//子组平均值
Xk[j] = Average(Xi);
}
//子组平均值的平均值
return Average(Xk);
}
/// <summary>
/// 一组观测值的均值
/// </summary>
/// <param name="Xn">子组观测值</param>
/// <returns></returns>
static private double Average(double[] Xn)
{
if (Xn.Length < 1) return 0;
return Sum(Xn) / (double)Xn.Length;
}
/// <summary>
/// 观测值和
/// </summary>
/// <param name="Xn">子组观测值</param>
/// <returns></returns>
static private double Sum(double[] Xn)
{
double temp;
temp = 0;
for (int i = 0; i < Xn.Length; i++)
{
temp = temp + Xn[i];
}
return temp;
}
/// <summary>
/// 观测值最大值
/// </summary>
/// <param name="Xn">子组观测值</param>
/// <returns></returns>
static private double Max(double[] Xn)
{
double temp;
temp = Xn[0];
for (int i = 0; i < Xn.Length; i++)
{
temp = (Xn[i] > temp) ? Xn[i] : temp;
}
return temp;
}
/// <summary>
/// 观测值最小值
/// </summary>
/// <param name="Xn">子组观测值</param>
/// <returns></returns>
static private double Min(double[] Xn)
{
double temp;
temp = Xn[0];
for (int i = 0; i < Xn.Length; i++)
{
temp = (Xn[i] < temp) ? Xn[i] : temp;
}
return temp;
}
/// <summary>
/// 均值极差图
/// </summary>
/// <param name="X"></param>
/// <param name="n"></param>
/// <param name="chart1"></param>
public static void ChartQualityData_XR(double[] X, int n, Chart chart1)
{
//计算XR控制图的数据
ASPNet_Drawing.CSpc_Data_XR Spc_Data_XR = ASPNet_Drawing.Spc_Data.XR(X, n);
for (int i = 0; i < Spc_Data_XR.CL_Xk.Length; i++)
{
//X
chart1.Series["Series_X"].Points.AddXY(i + 1, Spc_Data_XR.CL_Xk[i]);
//R
chart1.Series["Series_R"].Points.AddXY(i + 1, Spc_Data_XR.CL_Rk[i]);
}
chart1.Series["Series_X"].ToolTip = "测量值:= #VALY";
chart1.Series["Series_R"].ToolTip = "测量值:= #VALY";
////均值图Y轴范围
double gapAxis_X = Spc_Data_XR.UCL_X - Spc_Data_XR.LCL_X;
//均值的最大值
double maxXk = Max(Spc_Data_XR.CL_Xk);
//均值的最小值
double minXk = Min(Spc_Data_XR.CL_Xk);
if (maxXk > Spc_Data_XR.UCL_X)
{
chart1.ChartAreas["ChartArea_X"].AxisY.Maximum = Convert.ToDouble((maxXk + gapAxis_X / 8).ToString("F2"));
}
else
{
chart1.ChartAreas["ChartArea_X"].AxisY.Maximum = Convert.ToDouble((Spc_Data_XR.UCL_X + gapAxis_X / 8).ToString("F2"));
}
if (minXk < Spc_Data_XR.LCL_X)
{
chart1.ChartAreas["ChartArea_X"].AxisY.Minimum = Convert.ToDouble((minXk - gapAxis_X / 8).ToString("F2"));
}
else
{
chart1.ChartAreas["ChartArea_X"].AxisY.Minimum = Convert.ToDouble((Spc_Data_XR.LCL_X - gapAxis_X / 8).ToString("F2"));
}
////极差图Y轴范围
double gapAxis_R = Spc_Data_XR.UCL_R - Spc_Data_XR.LCL_R;
//极差最大值
double maxRk = Max(Spc_Data_XR.CL_Rk);
//极差最小值
double minRk = Min(Spc_Data_XR.CL_Rk);
if (maxRk > Spc_Data_XR.UCL_R)
{
chart1.ChartAreas["ChartArea_R"].AxisY.Maximum = Convert.ToDouble((maxRk + gapAxis_R / 8).ToString("F2"));
}
else
{
chart1.ChartAreas["ChartArea_R"].AxisY.Maximum = Convert.ToDouble((Spc_Data_XR.UCL_R + gapAxis_R / 8).ToString("F2"));
}
if (minRk < Spc_Data_XR.LCL_R)
{
chart1.ChartAreas["ChartArea_R"].AxisY.Minimum = Convert.ToDouble((minRk - gapAxis_R / 8).ToString("F2"));
}
else
{
chart1.ChartAreas["ChartArea_R"].AxisY.Minimum = Convert.ToDouble((Spc_Data_XR.LCL_R - gapAxis_R / 8).ToString("F2"));
}
// Set axis title
chart1.ChartAreas["ChartArea_X"].AxisY.Title = "均值图";
chart1.ChartAreas["ChartArea_R"].AxisY.Title = "极差图";
chart1.ChartAreas["ChartArea_X"].AxisY.TitleFont = new Font("Microsoft Sans Serif", 8);
chart1.ChartAreas["ChartArea_R"].AxisY.TitleFont = new Font("Microsoft Sans Serif", 8);
// Set Strip line item
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[0].IntervalOffset = Spc_Data_XR.LCL_X;
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[0].StripWidth = Spc_Data_XR.UCL_X - Spc_Data_XR.LCL_X;
// Set Strip line item
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[1].IntervalOffset = Spc_Data_XR.CL_X;
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[1].Text = "CL=" + Spc_Data_XR.CL_X.ToString("F2");
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[2].IntervalOffset = Spc_Data_XR.UCL_X;
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[2].Text = "UCL=" + Spc_Data_XR.UCL_X.ToString("F2");
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[3].IntervalOffset = Spc_Data_XR.LCL_X;
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[3].Text = "LCL=" + Spc_Data_XR.LCL_X.ToString("F2");
// Set Strip line item
chart1.ChartAreas["ChartArea_R"].AxisY.StripLines[0].IntervalOffset = Spc_Data_XR.LCL_R;
chart1.ChartAreas["ChartArea_R"].AxisY.StripLines[0].StripWidth = Spc_Data_XR.UCL_R - Spc_Data_XR.LCL_R;
// Set Strip line item
chart1.ChartAreas["ChartArea_R"].AxisY.StripLines[1].IntervalOffset = Spc_Data_XR.CL_R;
chart1.ChartAreas["ChartArea_R"].AxisY.StripLines[1].Text = "CL=" + Spc_Data_XR.CL_R.ToString("F2");
chart1.ChartAreas["ChartArea_R"].AxisY.StripLines[2].IntervalOffset = Spc_Data_XR.UCL_R;
chart1.ChartAreas["ChartArea_R"].AxisY.StripLines[2].Text = "UCL=" + Spc_Data_XR.UCL_R.ToString("F2");
chart1.ChartAreas["ChartArea_R"].AxisY.StripLines[3].IntervalOffset = Spc_Data_XR.LCL_R;
chart1.ChartAreas["ChartArea_R"].AxisY.StripLines[3].Text = "LCL=" + Spc_Data_XR.LCL_R.ToString("F2");
}
/// <summary>
/// 均值标准差图
/// </summary>
/// <param name="X"></param>
/// <param name="n"></param>
/// <param name="chart1"></param>
public static void ChartQualityData_XS(double[] X, int n, Chart chart1)
{
//计算XS控制图的数据
ASPNet_Drawing.CSpc_Data_XS Spc_Data_XS = ASPNet_Drawing.Spc_Data.XS(X, n);
for (int i = 0; i < Spc_Data_XS.CL_Xk.Length; i++)
{
//X
chart1.Series["Series_X"].Points.AddXY(i + 1, Spc_Data_XS.CL_Xk[i]);
//S
chart1.Series["Series_S"].Points.AddXY(i + 1, Spc_Data_XS.CL_Sk[i]);
}
chart1.Series["Series_X"].ToolTip = "测量值:= #VALY";
chart1.Series["Series_S"].ToolTip = "测量值:= #VALY";
////均值图Y轴范围
double gapAxis_X = Spc_Data_XS.UCL_X - Spc_Data_XS.LCL_X;
//均值的最大值
double maxXk = Max(Spc_Data_XS.CL_Xk);
//均值的最小值
double minXk = Min(Spc_Data_XS.CL_Xk);
if (maxXk > Spc_Data_XS.UCL_X)
{
chart1.ChartAreas["ChartArea_X"].AxisY.Maximum = Convert.ToDouble((maxXk + gapAxis_X / 8).ToString("F2"));
}
else
{
chart1.ChartAreas["ChartArea_X"].AxisY.Maximum = Convert.ToDouble((Spc_Data_XS.UCL_X + gapAxis_X / 8).ToString("F2"));
}
if (minXk < Spc_Data_XS.LCL_X)
{
chart1.ChartAreas["ChartArea_X"].AxisY.Minimum = Convert.ToDouble((minXk - gapAxis_X / 8).ToString("F2"));
}
else
{
chart1.ChartAreas["ChartArea_X"].AxisY.Minimum = Convert.ToDouble((Spc_Data_XS.LCL_X - gapAxis_X / 8).ToString("F2"));
}
////标准差图Y轴范围
double gapAxis_R = Spc_Data_XS.UCL_S - Spc_Data_XS.LCL_S;
//标准差最大值
double maxRk = Max(Spc_Data_XS.CL_Sk);
//标准差最小值
double minRk = Min(Spc_Data_XS.CL_Sk);
if (maxRk > Spc_Data_XS.UCL_S)
{
chart1.ChartAreas["ChartArea_S"].AxisY.Maximum = Convert.ToDouble((maxRk + gapAxis_R / 8).ToString("F2"));
}
else
{
chart1.ChartAreas["ChartArea_S"].AxisY.Maximum = Convert.ToDouble((Spc_Data_XS.UCL_S + gapAxis_R / 8).ToString("F2"));
}
if (minRk < Spc_Data_XS.LCL_S)
{
chart1.ChartAreas["ChartArea_S"].AxisY.Minimum = Convert.ToDouble((minRk - gapAxis_R / 8).ToString("F2"));
}
else
{
chart1.ChartAreas["ChartArea_S"].AxisY.Minimum = Convert.ToDouble((Spc_Data_XS.LCL_S - gapAxis_R / 8).ToString("F2"));
}
// Set axis title
chart1.ChartAreas["ChartArea_X"].AxisY.Title = "均值图";
chart1.ChartAreas["ChartArea_S"].AxisY.Title = "标准差图";
chart1.ChartAreas["ChartArea_X"].AxisY.TitleFont = new Font("Microsoft Sans Serif", 8);
chart1.ChartAreas["ChartArea_S"].AxisY.TitleFont = new Font("Microsoft Sans Serif", 8);
// Set Strip line item
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[0].IntervalOffset = Spc_Data_XS.LCL_X;
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[0].StripWidth = Spc_Data_XS.UCL_X - Spc_Data_XS.LCL_X;
// Set Strip line item
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[1].IntervalOffset = Spc_Data_XS.CL_X;
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[1].Text = "CL=" + Spc_Data_XS.CL_X.ToString("F2");
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[2].IntervalOffset = Spc_Data_XS.UCL_X;
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[2].Text = "UCL=" + Spc_Data_XS.UCL_X.ToString("F2");
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[3].IntervalOffset = Spc_Data_XS.LCL_X;
chart1.ChartAreas["ChartArea_X"].AxisY.StripLines[3].Text = "LCL=" + Spc_Data_XS.LCL_X.ToString("F2");
// Set Strip line item
chart1.ChartAreas["ChartArea_S"].AxisY.StripLines[0].IntervalOffset = Spc_Data_XS.LCL_S;
chart1.ChartAreas["ChartArea_S"].AxisY.StripLines[0].StripWidth = Spc_Data_XS.UCL_S - Spc_Data_XS.LCL_S;
// Set Strip line item
chart1.ChartAreas["ChartArea_S"].AxisY.StripLines[1].IntervalOffset = Spc_Data_XS.CL_S;
chart1.ChartAreas["ChartArea_S"].AxisY.StripLines[1].Text = "CL=" + Spc_Data_XS.CL_S.ToString("F2");
chart1.ChartAreas["ChartArea_S"].AxisY.StripLines[2].IntervalOffset = Spc_Data_XS.UCL_S;
chart1.ChartAreas["ChartArea_S"].AxisY.StripLines[2].Text = "UCL=" + Spc_Data_XS.UCL_S.ToString("F2");
chart1.ChartAreas["ChartArea_S"].AxisY.StripLines[3].IntervalOffset = Spc_Data_XS.LCL_S;
chart1.ChartAreas["ChartArea_S"].AxisY.StripLines[3].Text = "LCL=" + Spc_Data_XS.LCL_S.ToString("F2");
}
///// <summary>
///// 故障率 lvzhen
///// </summary>
///// <param name="dt"></param>
///// <param name="chart1"></param>
//public static void ChartFaultPercent(DataTable dt, Chart chart1)
//{
// if (dt.Rows.Count == 0)
// return;
// foreach (DataRow row in dt.Rows)
// {
// string seriesName = row["工位号"].ToString();
// chart1.Series.Add(seriesName);
// chart1.Series[seriesName].ChartType = SeriesChartType.Column;
// chart1.Series[seriesName].BorderWidth = 2;
// chart1.Series[seriesName].ToolTip = "工位号:" + row["工位号"].ToString() + "\n运行时间: " + row["运行时间"].ToString() + "\n故障时间: " + row["故障时间"].ToString() + "\n故障率#VALY";
// for (int colIndex = 3; colIndex < dt.Columns.Count; colIndex++)
// {
// // For each column (column 1 and onward) add the value as a point
// string columnName = dt.Columns[colIndex].ColumnName;
// string YVal = row[columnName].ToString();
// chart1.Series[seriesName].Points.AddXY(columnName, YVal);
// }
// //for (int i = 0; i < 10; i++)
// //{
// // chart1.Series[seriesName].Points.AddXY(dt.Rows[i]["报警编号"], dt.Rows[i]["报警数量"]);
// //}
// //chart1.DataBind();
// }
//}
///// <summary>
///// 故障率 lvzhen
///// </summary>
///// <param name="dt"></param>
///// <param name="chart1"></param>
//public static void ChartFaultPercentTrue(DataTable dt, Chart chart1)
//{
// if (dt.Rows.Count == 0)
// return;
// foreach (DataRow row in dt.Rows)
// {
// string seriesName = row["工位号"].ToString();
// chart1.Series.Add(seriesName);
// chart1.Series[seriesName].ChartType = SeriesChartType.Column;
// chart1.Series[seriesName].BorderWidth = 2;
// chart1.Series[seriesName].ToolTip = "工位号:" + row["工位号"].ToString() + " \n故障率#VALY";
// for (int colIndex = 3; colIndex < dt.Columns.Count; colIndex++)
// {
// // For each column (column 1 and onward) add the value as a point
// string columnName = dt.Columns[colIndex].ColumnName;
// string YVal = row[columnName].ToString();
// chart1.Series[seriesName].Points.AddXY(columnName, YVal);
// }
// //for (int i = 0; i < 10; i++)
// //{
// // chart1.Series[seriesName].Points.AddXY(dt.Rows[i]["报警编号"], dt.Rows[i]["报警数量"]);
// //}
// //chart1.DataBind();
// }
//}
///// <summary>
///// 开机率 lvzhen
///// </summary>
///// <param name="dt"></param>
///// <param name="chart1"></param>
//public static void ChartKaijiProportion(DataTable dt, Chart chart1)
//{
// chart1.Series[0].Points.DataBind(dt.DefaultView, "操作日期", "开机率", "Tooltip=ToolTip");
//}
}

View File

@@ -0,0 +1,88 @@
using System;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Web.UI.DataVisualization.Charting;
using System.Data.SqlClient;
/// <summary>
///DrawChart 的摘要说明
/// </summary>
public partial class DrawChart
{
/// <summary>
/// 故障率 lvzhen
/// </summary>
/// <param name="dt"></param>
/// <param name="chart1"></param>
public static void ChartFaultPercent(DataTable dt, Chart chart1)
{
if (dt.Rows.Count == 0)
return;
foreach (DataRow row in dt.Rows)
{
string seriesName = row["工位号"].ToString();
chart1.Series.Add(seriesName);
chart1.Series[seriesName].ChartType = SeriesChartType.Column;
chart1.Series[seriesName].BorderWidth = 2;
chart1.Series[seriesName].ToolTip = "工位号:" + row["工位号"].ToString() + "\n运行时间: " + row["运行时间"].ToString() + "\n故障时间: " + row["故障时间"].ToString() + "\n故障率#VALY";
for (int colIndex = 3; colIndex < dt.Columns.Count; colIndex++)
{
// For each column (column 1 and onward) add the value as a point
string columnName = dt.Columns[colIndex].ColumnName;
string YVal = row[columnName].ToString();
chart1.Series[seriesName].Points.AddXY(columnName, YVal);
}
//for (int i = 0; i < 10; i++)
//{
// chart1.Series[seriesName].Points.AddXY(dt.Rows[i]["报警编号"], dt.Rows[i]["报警数量"]);
//}
//chart1.DataBind();
}
}
/// <summary>
/// 故障率 lvzhen
/// </summary>
/// <param name="dt"></param>
/// <param name="chart1"></param>
public static void ChartFaultPercentTrue(DataTable dt, Chart chart1)
{
if (dt.Rows.Count == 0)
return;
foreach (DataRow row in dt.Rows)
{
string seriesName = row["工位号"].ToString();
chart1.Series.Add(seriesName);
chart1.Series[seriesName].ChartType = SeriesChartType.Column;
chart1.Series[seriesName].BorderWidth = 2;
chart1.Series[seriesName].ToolTip = "工位号:" + row["工位号"].ToString()+" \n故障率#VALY";
for (int colIndex = 3; colIndex < dt.Columns.Count; colIndex++)
{
// For each column (column 1 and onward) add the value as a point
string columnName = dt.Columns[colIndex].ColumnName;
string YVal = row[columnName].ToString();
chart1.Series[seriesName].Points.AddXY(columnName, YVal);
}
//for (int i = 0; i < 10; i++)
//{
// chart1.Series[seriesName].Points.AddXY(dt.Rows[i]["报警编号"], dt.Rows[i]["报警数量"]);
//}
//chart1.DataBind();
}
}
/// <summary>
/// 开机率 lvzhen
/// </summary>
/// <param name="dt"></param>
/// <param name="chart1"></param>
public static void ChartKaijiProportion(DataTable dt, Chart chart1)
{
chart1.Series[0].Points.DataBind(dt.DefaultView, "操作日期", "开机率", "Tooltip=ToolTip");
}
}

View File

@@ -0,0 +1,300 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Web.UI.DataVisualization.Charting;
using System.Collections;
/// <summary>
///DrawPareto 的摘要说明
/// </summary>
public class DrawPareto
{
public DrawPareto()
{
//
//TODO: 在此处添加构造函数逻辑
//
}
/// <summary>
/// Number of class intervals the data range is devided in.
/// This property only has affect when "SegmentIntervalWidth" is
/// set to double.NaN.
/// </summary>
public int SegmentIntervalNumber = 20;
/// <summary>
/// Histogram class interval width. Setting this value to "double.NaN"
/// will result in automatic width calculation based on the data range
/// and number of required interval specified in "SegmentIntervalNumber".
/// </summary>
public double SegmentIntervalWidth = double.NaN;
/// <summary>
/// Indicates that percent frequency should be shown on the right axis
/// </summary>
public bool ShowPercentOnSecondaryYAxis = true;
public void CreatePareto(
Chart chartControl,
string dataSeriesName,
string histogramSeriesName)
{
// Validate input
if (chartControl == null)
{
throw (new ArgumentNullException("chartControl"));
}
if (chartControl.Series.IndexOf(dataSeriesName) < 0)
{
throw (new ArgumentException("Series with name'" + dataSeriesName + "' was not found.", "dataSeriesName"));
}
// Make data series invisible
chartControl.Series[dataSeriesName].Enabled = false;
// Check if histogram series exsists
Series histogramSeries = null;
if (chartControl.Series.IndexOf(histogramSeriesName) < 0)
{
// Add new series
histogramSeries = chartControl.Series.Add(histogramSeriesName);
// Set new series chart type and other attributes
histogramSeries.ChartType = SeriesChartType.Column;
histogramSeries.BorderColor = Color.Black;
histogramSeries.BorderWidth = 1;
histogramSeries.BorderDashStyle = ChartDashStyle.Solid;
}
else
{
histogramSeries = chartControl.Series[histogramSeriesName];
histogramSeries.Points.Clear();
}
// Get data series minimum and maximum values
double minValue = double.MaxValue;
double maxValue = double.MinValue;
int pointCount = 0;
foreach (DataPoint dataPoint in chartControl.Series[dataSeriesName].Points)
{
// Process only non-empty data points
if (!dataPoint.IsEmpty)
{
if (dataPoint.YValues[0] > maxValue)
{
maxValue = dataPoint.YValues[0];
}
if (dataPoint.YValues[0] < minValue)
{
minValue = dataPoint.YValues[0];
}
++pointCount;
}
}
// Calculate interval width if it's not set
if (double.IsNaN(this.SegmentIntervalWidth))
{
this.SegmentIntervalWidth = (maxValue - minValue) / SegmentIntervalNumber;
this.SegmentIntervalWidth = RoundInterval(this.SegmentIntervalWidth);
}
// Round minimum and maximum values
minValue = Math.Floor(minValue / this.SegmentIntervalWidth) * this.SegmentIntervalWidth;
maxValue = Math.Ceiling(maxValue / this.SegmentIntervalWidth) * this.SegmentIntervalWidth;
// Create histogram series points
double currentPosition = minValue;
for (currentPosition = minValue; currentPosition <= maxValue; currentPosition += this.SegmentIntervalWidth)
{
// Count all points from data series that are in current interval
int count = 0;
foreach (DataPoint dataPoint in chartControl.Series[dataSeriesName].Points)
{
if (!dataPoint.IsEmpty)
{
double endPosition = currentPosition + this.SegmentIntervalWidth;
if (dataPoint.YValues[0] >= currentPosition &&
dataPoint.YValues[0] < endPosition)
{
++count;
}
// Last segment includes point values on both segment boundaries
else if (endPosition >= maxValue)
{
if (dataPoint.YValues[0] >= currentPosition &&
dataPoint.YValues[0] <= endPosition)
{
++count;
}
}
}
}
// Add data point into the histogram series
//histogramSeries.Points.AddXY("", count);
histogramSeries.Points.AddY( count);
}
histogramSeries.Sort(PointSortOrder.Descending);
// Adjust series attributes
histogramSeries["PointWidth"] = "1";
// Adjust chart area
ChartArea chartArea = chartControl.ChartAreas[histogramSeries.ChartArea];
chartArea.AxisY.Title = "频数";
//chartArea.AxisX.Minimum = minValue;
//chartArea.AxisX.Maximum = maxValue;
// Set axis interval based on the histogram class interval
// and do not allow more than 10 labels on the axis.
double axisInterval = this.SegmentIntervalWidth;
while ((maxValue - minValue) / axisInterval > 10.0)
{
axisInterval *= 2.0;
}
chartArea.AxisX.Interval = axisInterval;
// Set chart area secondary Y axis
chartArea.AxisY2.Enabled = AxisEnabled.Auto;
if (this.ShowPercentOnSecondaryYAxis)
{
chartArea.RecalculateAxesScale();
chartArea.AxisY2.Enabled = AxisEnabled.True;
chartArea.AxisY2.LabelStyle.Format = "P0";
chartArea.AxisY2.MajorGrid.Enabled = false;
chartArea.AxisY2.Title = "Percent of Total";
chartArea.AxisY2.Minimum = 0;
chartArea.AxisY2.Maximum = chartArea.AxisY.Maximum / (pointCount / 100.0);
double minStep = (chartArea.AxisY2.Maximum > 20.0) ? 5.0 : 1.0;
chartArea.AxisY2.Interval = Math.Ceiling((chartArea.AxisY2.Maximum / 5.0 / minStep)) * minStep;
}
}
/// <summary>
/// Helper method which rounds specified axsi interval.
/// </summary>
/// <param name="interval">Calculated axis interval.</param>
/// <returns>Rounded axis interval.</returns>
public double RoundInterval(double interval)
{
// If the interval is zero return error
if (interval == 0.0)
{
throw (new ArgumentOutOfRangeException("interval", "Interval can not be zero."));
}
// If the real interval is > 1.0
double step = -1;
double tempValue = interval;
while (tempValue > 1.0)
{
step++;
tempValue = tempValue / 10.0;
if (step > 1000)
{
throw (new InvalidOperationException("Auto interval error due to invalid point values or axis minimum/maximum."));
}
}
// If the real interval is < 1.0
tempValue = interval;
if (tempValue < 1.0)
{
step = 0;
}
while (tempValue < 1.0)
{
step--;
tempValue = tempValue * 10.0;
if (step < -1000)
{
throw (new InvalidOperationException("Auto interval error due to invalid point values or axis minimum/maximum."));
}
}
double tempDiff = interval / Math.Pow(10.0, step);
if (tempDiff < 3.0)
{
tempDiff = 2.0;
}
else if (tempDiff < 7.0)
{
tempDiff = 5.0;
}
else
{
tempDiff = 10.0;
}
// Make a correction of the real interval
return tempDiff * Math.Pow(10.0, step);
}
public void MakeParetoChart(Chart chart, string srcSeriesName, string destSeriesName)
{
// get name of the ChartAre of the source series
string strChartArea = chart.Series[srcSeriesName].ChartArea;
// ensure the source series is a column chart type
chart.Series[srcSeriesName].ChartType = SeriesChartType.Column;
// sort the data in the series to be by values in descending order
chart.DataManipulator.Sort(PointSortOrder.Descending, srcSeriesName);
// find the total of all points in the source series
double total = 0.0;
foreach (DataPoint pt in chart.Series[srcSeriesName].Points)
total += pt.YValues[0];
// set the max value on the primary axis to total
chart.ChartAreas[strChartArea].AxisY.Maximum = total;
// create the destination series and add it to the chart
Series destSeries = new Series(destSeriesName);
chart.Series.Add(destSeries);
// ensure the destination series is a Line or Spline chart type
destSeries.ChartType = SeriesChartType.Line;
destSeries.BorderWidth = 3;
// assign the series to the same chart area as the column chart
destSeries.ChartArea = chart.Series[srcSeriesName].ChartArea;
// assign this series to use the secondary axis and set it maximum to be 100%
destSeries.YAxisType = AxisType.Secondary;
chart.ChartAreas[strChartArea].AxisY2.Maximum = 100;
// locale specific percentage format with no decimals
chart.ChartAreas[strChartArea].AxisY2.LabelStyle.Format = "0.#";
// turn off the end point values of the primary X axis
chart.ChartAreas[strChartArea].AxisX.LabelStyle.IsEndLabelVisible = false;
// for each point in the source series find % of total and assign to series
double percentage = 0.0;
foreach (DataPoint pt in chart.Series[srcSeriesName].Points)
{
percentage += (pt.YValues[0] / total * 100.0);
//Chart1.Series["Default"].Points.AddXY(pt.XValue,Math.Round(percentage, 2));
destSeries.Points.Add(Math.Round(percentage, 2));
}
}
}

View File

@@ -0,0 +1,512 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections;
using System.Data;
using ASPNet_Drawing;
/// <summary>
///SpcCaculator 的摘要说明
/// </summary>
public class SpcCaculator
{
/// <summary>
/// SPC系数表
///(0)样本大小 (1)A (2)A2 (3)A3 (4)C4 (5)1/C4 (6)B3 (7)B4 (8)B5 (9)B6 (10)d2 (11)1/d2 (12)d3 (13)D1 (14)D2 (15)D3 (16)D4 (17)M3 (18)M3A2
/// </summary>
static public double[,] SPC_coefficient = { {2,2.121,1.880,2.659,0.798,1.253,0,3.267,0,2.606,1.128,0.887,0.853,0,3.686,0,3.267,1.000,1.880},
{3,1.732,1.023,1.954,0.886,1.128,0,2.568,0,2.276,1.693,0.591,0.888,0,4.358,0,2.574,1.160,1.187},
{4,1.500,0.729,1.628,0.921,1.085,0,2.266,0,2.088,2.059,0.486,0.880,0,4.698,0,2.282,1.092,0.796},
{5,1.342,0.572,1.427,0.940,1.064,0,2.089,0,1.964,2.326,0.430,0.864,0,4.918,0,2.114,1.198,0.691},
{6,1.225,0.483,1.287,0.952,1.051,0.030,1.970,0.029,1.874,2.534,0.395,0.848,0,5.078,0,2.004,1.135,0.549},
{7,1.134,0.419,1.182,0.959,1.042,0.118,1.882,0.113,1.806,2.704,0.370,0.833,0.204,5.204,0.076,1.924,1.214,0.509},
{8,1.061,0.373,1.099,0.965,1.036,0.185,1.815,0.179,1.751,2.847,0.351,0.820,0.388,5.306,0.136,1.864,1.160,0.432},
{9,1.00,0.377,1.032,0.969,1.032,0.29,1.761,0.232,1.707,2.970,0.337,0.808,0.547,5.393,0.184,1.816,1.223,0.412},
{10,0.949,0.308,0.975,0.973,1.028,0.284,1.716,0.276,1.669,3.078,0.325,0.797,0.687,5.469,0.223,1.777,1.176,0.363},
{11,0.905,0.285,0.927,0.975,1.025,0.321,1.679,0.313,1.637,3.173,0.315,0.787,0.811,5.535,0.256,1.744,0,0},
{12,0.886,0.266,0.886,0.978,1.023,0.354,1.646,0.346,1.610,3.258,0.307,0.778,0.922,5.594,0.283,1.717,0,0},
{13,0.832,0.249,0.850,0.979,1.021,0.382,1.618,0.374,1.585,3.336,0.300,0.770,1.025,5.647,0.307,1.693,0,0},
{14,0.802,0.235,0.817,0.981,1.019,0.406,1.594,0.399,1.563,3.407,0.294,0.763,1.118,5.696,0.328,1.672,0,0},
{15,0.775,0.223,0.789,0.982,1.018,0.428,1.157,0.421,1.544,3.472,0.288,0.756,1.203,5.741,0.347,1.653,0,0},
{16,0.750,0.212,0.763,0.984,1.017,0.448,1.552,0.440,1.526,3.532,0.283,0.750,1.282,5.782,0.363,1.637,0,0},
{17,0.728,0.203,0.739,0.985,1.016,0.466,1.534,0.458,1.511,3.588,0.279,0.744,1.356,5.820,0.378,1.622,0,0},
{18,0.707,0.194,0.718,0.985,1.015,0.482,1.518,0.475,1.496,3.640,0.275,0.739,1.424,5.856,0.391,1.608,0,0},
{19,0.688,0.187,0.698,0.986,1.014,0.497,1.503,0.490,1.483,3.689,0.271,0.734,1.487,5.891,0.403,1.597,0,0},
{20,0.671,0.180,0.680,0.987,1.013,0.510,1.490,0.504,1.470,3.735,0.268,0.729,1.549,5.921,0.415,1.585,0,0},
{21,0.655,0.173,0.663,0.988,1.013,0.253,1.477,0.516,1.459,3.778,0.265,0.724,1.605,5.951,0.425,1.575,0,0},
{22,0.640,0.167,0.647,0.988,1.012,0.534,1.466,0.528,1.448,3.819,0.262,0.720,1.659,5.979,0.434,1.566,0,0},
{23,0.626,0.126,0.633,0.989,1.011,0.545,1.455,0.539,1.438,3.858,0.259,0.716,1.710,6.006,0.443,1.557,0,0},
{24,0.612,0.157,0.619,0989,1.011,0.555,1.445,0.549,1.429,3.895,0.257,0.712,1.759,6.031,0.451,1.548,0,0},
{25,0.600,0.153,0.606,0.990,1.011,0.565,1.435,0.559,1.420,3.931,0.254,0.708,1.806,6.056,0.459,1.541,0,0} };
static double QU_k = 0.99865;
static double QL_k = 0.00135;
/// <summary>
/// 计算SPC主要参数
/// 输入:"X"被分析数据组Usl理论上限Lsl理论下限。
/// 输出x平均值"s"均方差;"QU"百分比上限;"QL"百分比下限;"cp"工序能力;"cpk"工序能力指数
/// </summary>
/// <param name="X">被分析数据组</param>
/// <param name="Usl">理论上限</param>
/// <param name="Lsl">理论下限</param>
/// <param name="x">平均值</param>
/// <param name="s">均方差</param>
/// <param name="QU">百分比上限</param>
/// <param name="QL">百分比下限</param>
/// <param name="cp">工序能力</param>
/// <param name="cpk">工序能力指数</param>
public static void SpcValue(double[] X, ref double Usl, ref double Lsl, out double x, out double s,
out double QU, out double QL, out double cp, out double cpk, out double[] sx, out double[] sy)
{
x = AVERAGE(X);
s = STDEV(X);
if (Usl == Lsl)
{
Usl = x + 4.0 * s;
Lsl = x - 4.0 * s;
}
QU_QL(X, out QU, out QL);
cp = Cp(QU, QL, Usl, Lsl);
cpk = Cpk(x, QU, QL, Usl, Lsl);
sxy(s, x, out sx, out sy);
}
/// <summary>
/// 计算SPC主要参数
/// 输入:"X"被分析数据组Usl理论上限Lsl理论下限。
/// 输出x平均值"s"均方差;"QU"百分比上限;"QL"百分比下限;"cp"工序能力;"cpk"工序能力指数
/// </summary>
/// <param name="X">被分析数据组</param>
/// <param name="Usl">理论上限</param>
/// <param name="Lsl">理论下限</param>
/// <param name="x">平均值</param>
/// <param name="s">均方差</param>
/// <param name="QU">百分比上限</param>
/// <param name="QL">百分比下限</param>
/// <param name="cp">工序能力</param>
/// <param name="cpk">工序能力指数</param>
public static void SpcValue(int n,double[] X, ref double Usl, ref double Lsl, out double x, out double s,
out double QU, out double QL, out double cp, out double cpk, out double[] sx, out double[] sy)
{
x = AVERAGE(X);
s = STDEV(X);
if (Usl == Lsl)
{
Usl = x + 4.0 * s;
Lsl = x - 4.0 * s;
}
QU_QL(X, out QU, out QL);
cp = Cp(QU, QL, Usl, Lsl);
cpk = Cpk(x, QU, QL, Usl, Lsl);
sxy(s, x, out sx, out sy);
double X2 = Spc_Data.Average(X, n);
double S2 = Spc_Data.StandardDeviation_S2(X, n);
double R2 = Spc_Data.Range_R2(X, n);
double xiGamaC4;
double xiGamaD2;
double c4 = (double)Spc_Data.Spc_Param.Tables[Xml_Spc_Param.Table_Name].Rows[n - 2][Xml_Spc_Param.Param_C4];
double d2 = (double)Spc_Data.Spc_Param.Tables[Xml_Spc_Param.Table_Name].Rows[n - 2][Xml_Spc_Param.Param_L_D1];
xiGamaC4 = S2 / c4;
xiGamaD2 = R2 / d2;
double USL = Usl;
double LSL = Lsl;
double T = USL - LSL;
double CP = T / (6 * xiGamaD2);
double M = (USL + LSL) / 2.0;
double M1 = M - X2;
M1 = Math.Abs(M1);
double CPK = CP - M1 / (3 * xiGamaD2);
cp = CP;
cpk = CPK;
}
/// <summary>
/// 均方差
/// </summary>
/// <param name="X">被分析数据组</param>
/// <returns>均方差</returns>
public static double STDEV(double[] X)
{
if (X.Length < 2)
return 0;
double s = 0;
//平均值
double x;
x = AVERAGE(X);
for (int i = 0; i < X.Length; i++)
{
s = s + (X[i] - x) * (X[i] - x);
}
s = Math.Sqrt(s / (double)(X.Length - 1));
return s;
}
/// <summary>
/// 平均值
/// </summary>
/// <param name="X">被分析数据组</param>
/// <returns>平均值</returns>
public static double AVERAGE(double[] X)
{
return X.Average();
}
/// <summary>
/// 排序
/// </summary>
/// <param name="X"></param>
/// <returns></returns>
public static double[] Sort(double[] X)
{
ArrayList temp = new ArrayList(X);
temp.Sort();
return X = (double[])temp.ToArray(typeof(double));
}
/// <summary>
/// 已知表格行数为m各行的数值分别记为 ,其中 表示第 行的数值,
/// 将这 个数值由小到大排列,记排列后的数值为 ,其中 表示 个数值经排列之后第k个数值。
/// 给定上下标线数值0.99865和0.00135。计算Q上和Q下的方法为
///a = m - 1* 0.99865
///取a的整数部分为i小数部分为j。
///Q上 = 1 j* xi+1+ j * xi+2
///同理:
///b = m - 1* 0.00135
///取b的整数部分为i小数部分为j。
///Q下 = 1 j* xi+1+ j * xi+2
/// </summary>
/// <param name="X">被分析数据组</param>
/// <param name="QU">百分比上限</param>
/// <param name="QL">百分比下限</param>
public static void QU_QL(double[] X, out double QU, out double QL)
{
QU = 0;
QL = 0;
double QU_n;
int QU_n_i;
double QU_n_j;
double QL_n;
int QL_n_i;
double QL_n_j;
X = Sort(X);
QU_n = (double)(X.Length - 1) * QU_k;
QU_n_i = (int)QU_n;
QU_n_j = QU_n - QU_n_i;
//Q上 = 1 j* xi+1+ j * xi+2
QU = (1 - QU_n_j) * X[QU_n_i] + QU_n_j * X[QU_n_i + 1];
QL_n = (double)(X.Length - 1) * QL_k;
QL_n_i = (int)QL_n;
QL_n_j = QL_n - QL_n_i;
//Q下 = 1 j* xi+1+ j * xi+2
QL = (1 - QL_n_j) * X[QL_n_i] + QL_n_j * X[QL_n_i + 1];
return;
}
/// <summary>
/// 工序能力
/// </summary>
/// <param name="X">被分析数据组</param>
/// <param name="Usl">理论上限</param>
/// <param name="Lsl">理论下限</param>
/// <returns>工序能力</returns>
public static double Cp(double[] X, double Usl, double Lsl)
{
double QU;
double QL;
double cp = 0;
QU_QL(X, out QU, out QL);
cp = (Usl - Lsl) / (QU - QL);
return cp;
}
/// <summary>
/// 工序能力
/// </summary>
/// <param name="QU">百分比上限</param>
/// <param name="QL">百分比下限</param>
/// <param name="Usl">理论上限</param>
/// <param name="Lsl">理论下限</param>
/// <returns></returns>
public static double Cp(double QU, double QL, double Usl, double Lsl)
{
double cp = 0;
cp = (Usl - Lsl) / (QU - QL);
return cp;
}
/// <summary>
/// 工序能力指数
/// </summary>
/// <param name="[] X">被分析数据组</param>
/// <param name="Usl">理论上限</param>
/// <param name="Lsl">理论下限</param>
/// <returns></returns>
public static double Cpk(double[] X, double Usl, double Lsl)
{
double cpk;
double cpkU;
double cpkL;
double QU;
double QL;
double cp = 0;
//均方差
double s;
//均值
double x;
x = AVERAGE(X);
QU_QL(X, out QU, out QL);
cp = (Usl - Lsl) / (QU - QL);
cpkU = (Usl - x) / (QU - x);
cpkL = (Lsl - x) / (QL - x);
cpk = Math.Min(cpkU, cpkL);
return cpk;
}
/// <summary>
/// 工序能力指数
/// </summary>
/// <param name="x">平均值</param>
/// <param name="QU">百分比上限</param>
/// <param name="QL">百分比下限</param>
/// <param name="Usl">理论上限</param>
/// <param name="Lsl">理论下限</param>
/// <returns></returns>
public static double Cpk(double x, double QU, double QL, double Usl, double Lsl)
{
double cpk;
double cpkU;
double cpkL;
double cp = 0;
cp = Cp(QU, QL, Usl, Lsl);
cpkU = (Usl - x) / (QU - x);
cpkL = (x - Lsl) / (x - QL);
cpk = Math.Min(cpkU, cpkL);
return cpk;
}
/// <summary>
/// 计算正态分布的x坐标y坐标
/// </summary>
/// <param name="s">均方差</param>
/// <param name="x">平均值</param>
public static void sxy(double s, double x, out double[] sx, out double[] sy)
{
double S2;
double X2;
X2 = x;
S2 = s;
sx = new double[11];
sy = new double[11];
double tempmaxdouble = 1.0 / (s * Math.Sqrt(2.0 * Math.PI));
sx[0] = X2 - 4.0 * S2;
sx[1] = X2 - 3.0 * S2;
sx[2] = X2 - 2.0 * S2;
sx[3] = X2 - 1.0 * S2;
sx[4] = X2 - 0.5 * S2;
sx[5] = X2;
sx[6] = X2 + 0.5 * S2;
sx[7] = X2 + 1.0 * S2;
sx[8] = X2 + 2.0 * S2;
sx[9] = X2 + 3.0 * S2;
sx[10] = X2 + 4.0 * S2;
sy[0] = tempmaxdouble * Math.Exp(-16.0F / 2.0F);
sy[1] = tempmaxdouble * Math.Exp(-9.0F / 2.0F);
sy[2] = tempmaxdouble * Math.Exp(-4.0F / 2.0F);
sy[3] = tempmaxdouble * Math.Exp(-1.0F / 2.0F);
sy[4] = tempmaxdouble * Math.Exp(-0.25F / 2.0F);
sy[5] = tempmaxdouble;
sy[6] = tempmaxdouble * Math.Exp(-0.25F / 2.0F);
sy[7] = tempmaxdouble * Math.Exp(-1.0F / 2.0F);
sy[8] = tempmaxdouble * Math.Exp(-4.0F / 2.0F);
sy[9] = tempmaxdouble * Math.Exp(-9.0F / 2.0F);
sy[10] = tempmaxdouble * Math.Exp(-16.0F / 2.0F);
double sy_sum = 0;
for (int i = 0; i < sy.Length; i++)
{
sy_sum = sy_sum + sy[i];
}
for (int i = 0; i < sy.Length; i++)
{
sy[i] = sy[i] / sy_sum;
}
}
/// <summary>
/// 根据查询的数据,获得理论上限,理论下限
/// </summary>
/// <param name="dl"></param>
/// <param name="Usl">理论上限</param>
/// <param name="Lsl">理论下限</param>
public static void GetUslLsl(DataTable dt, out double Usl, out double Lsl)
{
Usl = 0;
Lsl = 0;
if (dt != null)
{
if (dt.Rows.Count > 0)
{
try
{
//Usl = Convert.ToDouble(dt.Rows[0]["上限值"]);
//Lsl = Convert.ToDouble(dt.Rows[0]["下限值"]);
Usl = 100;
Lsl = 100;
}
catch
{
Usl = 0;
Lsl = 0;
}
}
}
}
}
/// <summary>
/// 测试数据
/// </summary>
public class Spc_Data_TestData
{
/// <summary>
/// 子组大小。单个子组观测值的个数
/// </summary>
static public int n = 5;
/// <summary>
/// 子组个数
/// </summary>
static public int k = 30;
/// <summary>
/// 特征值上限
/// </summary>
static public double USL = 1.7;
/// <summary>
/// 特征值下限
/// </summary>
static public double LSL = 1.5;
/// <summary>
/// 特征值上限
/// </summary>
static public double USL1 = 1.0;
/// <summary>
/// 特征值下限
/// </summary>
static public double LSL1 = 0.9;
/// <summary>
/// 特征值上限
/// </summary>
static public double USL2 = 1.15;
/// <summary>
/// 特征值下限
/// </summary>
static public double LSL2 = 1.10;
/// <summary>
/// 特征值上限
/// </summary>
static public double USL3 = 129.01;
/// <summary>
/// 特征值下限
/// </summary>
static public double LSL3 = 129;
static public double[] X3 =
{
129.006,129.006,129.006,129.005,129.006,
129.006,129.005,129.005,129.005,129.005,
129.005,129.006,129.007,129.006,129.005,
129.005,129.005,129.006,129.005,129.006,
129.006,129.006,129.007,129.006,129.005,
129.007,129.006,129.005,129.005,129.006,
129.006,129.007,129.005,129.005,129.005,
129.007,129.006,129.006,129.007,129.005,
129.007,129.005,129.005,129.006,129.007,
129.006,129.007,129.005,129.005,129.006
};
static public double[] X2 =
{
1.141,1.130,1.131,1.127,1.137,
1.140,1.137,1.130,1.135,1.125,
1.133,1.133,1.131,1.128,1.127,
1.122,1.131,1.131,1.125,1.123,
1.131,1.128,1.117,1.133,1.136,
1.123,1.128,1.135,1.127,1.130,
1.138,1.126,1.130,1.133,1.133,
1.130,1.127,1.128,1.127,1.128,
1.122,1.142,1.128,1.135,1.133,
1.142,1.127,1.133,1.135,1.135
};
static public double[] X1 =
{ 0.941,0.942,0.947,0.939,0.942,0.943,
0.942,0.950,0.943,0.948,0.941,0.953,
0.944,0.943,0.941,0.933,0.942,0.941,
0.942,0.942,0.942,0.947,0.938,0.941,
0.947,0.943,0.943,0.948,0.938,0.946,
0.946,0.943,0.945,0.946,0.942,0.951,
0.951,0.938,0.938,0.952,0.947,0.945,
0.951,0.948,0.946,0.947,0.947,0.947,
0.953,0.956
};
static public double[] X =
{ 1.55,1.58,1.61,1.60,1.60,//1
1.58,1.63,1.63,1.62,1.63,//2
1.62,1.63,1.62,1.59,1.58,//3
1.58,1.60,1.61,1.62,1.63,//4
1.58,1.64,1.63,1.62,1.62,//5
1.62,1.62,1.63,1.61,1.57,//6
1.64,1.62,1.61,1.60,1.58,//7
1.57,1.59,1.61,1.62,1.63,//8
1.58,1.61,1.60,1.62,1.63,//9
1.60,1.61,1.64,1.64,1.63,//10
1.58,1.60,1.62,1.63,1.65,//11
1.62,1.58,1.59,1.57,1.58,//12
1.57,1.57,1.58,1.59,1.64,//13
1.61,1.64,1.62,1.60,1.59,//14
1.65,1.62,1.62,1.60,1.58,//15
1.57,1.59,1.57,1.59,1.62,//16
1.56,1.57,1.57,1.61,1.62,//17
1.56,1.58,1.59,1.60,1.62,//18
1.58,1.60,1.60,1.62,1.63,//19
1.58,1.59,1.60,1.63,1.62,//20
1.58,1.59,1.62,1.63,1.64,//21
1.58,1.59,1.62,1.63,1.61,//22
1.58,1.59,1.60,1.61,1.63,//23
1.57,1.59,1.61,1.61,1.62,//24
1.58,1.58,1.60,1.61,1.63,//25
1.62,1.58,1.58,1.58,1.57,//26
1.63,1.59,1.57,1.58,1.57,//27
1.58,1.62,1.61,1.63,1.61,//28
1.58,1.57,1.59,1.60,1.62,//29
1.62,1.60,1.60,1.57,1.57 //30
};
}

View File

Binary file not shown.