一年多的“潛伏”也算是深資“特務”了,長時間看別人的博客,自己卻沒有寫點東東,對不起那些園中勞碌的人。今天終於可以“洗牌”了做正常勞苦大眾。那也得感謝是項目交付期,有了“空擋”可以寫點什么,讓大家拍磚。
今天主講是的繪制正態分布圖形所用的質量指標公式的,不注重講MSChart圖形控件的用法,MSChart圖形控件博園中有很多實例。正態分布圖形所用的質量指標如下:USL(下規格線簡稱:下限)、USL(上限)、SIGMA(西格瑪)、XBAR(平均值)、SAMPLE DATA(樣本數據)、Zoom Multiple(縮放倍數)、Most Precision(最大精度)。
- Most Precision:最大精度,即小數點后面的位數長度。
View Code
1 /// <summary> 2 /// 獲取數據序列的最大精度 (即小數點后面的位數長度) 3 /// </summary> 4 /// <param name="sampleData">樣本數據</param> 5 /// <returns></returns> 6 public static int GetMostPrecision(List<decimal> sampleData) 7 { 8 if (sampleData == null || sampleData.Count == 0) 9 { 10 return 0; 11 } 12 13 int mostPrecision = 0; 14 int tempValue = 0; 15 16 foreach (decimal value in sampleData) 17 { 18 string data = Math.Abs(value).ToString(); 19 int dateLength = data.Length; 20 int dotIndex = data.IndexOf("."); 21 22 if (dotIndex > 0) 23 { 24 tempValue = dateLength - (dotIndex + 1); 25 } 26 27 if (tempValue > mostPrecision) //取更大的精度 28 { 29 mostPrecision = tempValue; 30 } 31 } 32 33 return mostPrecision; 34 }
- Zoom Multiple:縮放倍數,為了增加圖形邊沿線的平滑度。
View Code
1 /// <summary> 2 /// 縮放倍數 3 /// </summary> 4 /// <param name="mostPrecision"></param> 5 /// <returns></returns> 6 private static decimal ZoomMultiple(ref int mostPrecision) 7 { 8 decimal zoomMultiple = (decimal)Math.Pow(10, mostPrecision - 1); 9 10 if (mostPrecision <= 2) //保證精度大於二的數據序列圖形的平滑 11 { 12 mostPrecision = 4; 13 zoomMultiple = 100; 14 } 15 16 return zoomMultiple; 17 }
- SAMPLE DATA:樣本數據是概率運算里的一個概念。隨機抽取的部分用於計算出性能優良的數量。
- XBAR:這個大家好理解,也很好計算。即是所有樣本數據之和的平均值。
View Code
1 double xbar = Math.Round(sampleData.Average(), mostPrecision);
- SIGMA:是一個希臘字母σ的中文譯音,在統計學中,代表標准偏差,用來對過程變異進行測量。
View Code
1 /// <summary> 2 /// 計算Sigma 3 /// </summary> 4 /// <param name="sampleData">樣本數據</param> 5 /// <param name="xbar">平均值</param> 6 /// <returns></returns> 7 public static double CalculateSigma(List<decimal> sampleData, double xbar) 8 { 9 double sigma = 0; 10 int sampleCount = sampleData.Count; 11 double powSum = 0; 12 13 if (sampleData == null || sampleCount <= 2 14 ) //樣本個數大於2計算才有意思 15 { 16 return sigma; 17 } 18 19 foreach (double value in sampleData) 20 { 21 powSum += Math.Pow(value - xbar, 2); //樣本值減去均值2的次冪相加。 22 } 23 24 sigma = Math.Sqrt(powSum / (sampleCount - 1)); 25 26 return sigma; 27 }
- USL和LSL一般是抽樣人員事先設置好的,也可以用公式得到:
View Code
1 double usl = xbar + 3 * sigma;//均值加3sigma 2 double lsl = xbar - 3 * sigma;//均值減3sigma
上面是正態分布圖所用到的指標計算公式或方法,公式的解析詳情http://zhidao.baidu.com/question/86348249.html?an=0&si=5下面該介紹正態分布的公式或方法,至於MSChart樣式設置略講,如有需要聯系我kingzheng@yeah.net
首先清除圖表Series集合上的數據點:
1 chart.Series[serieIndex].Points.Clear();
X軸正、負界限以及正態公式系數:
1 int positiveLimit = (int)((xbar + 6 * sigma) * zoomMultiple); //X軸的正界限 2 int minusLimit = (int)((xbar - 6 * sigma) * zoomMultiple); //X軸的負界限 3 double coefficient = Math.Round(1 / Math.Sqrt(2 * Math.PI) / sigma, mostPrecision); //系數;如果計算需要精確,就不要四舍五入;建議:為了提高運算效率要四舍五入。
根據公式生成正態圖形所需要的數據點:
1 List<double> xValues = new List<double>(); 2 List<double> yValues = new List<double>(); 3 4 for (int x = minusLimit; x <= positiveLimit; x++) 5 { 6 //x軸縮小zoomMultiple倍x每隔1/zoomMultiple變化曲線變平滑 7 double xValue = x / zoomMultiple; 8 double yValue = coefficient * Math.Exp(Math.Pow((xValue - xbar), 2) / (-2 * Math.Pow(sigma, 2))); 9 xValue = Math.Round(xValue, mostPrecision); 10 yValue = Math.Round(yValue, mostPrecision); 11 if (yValue > 0.0001)//可設為yValue > 0 12 { 13 xValues.Add(xValue); 14 yValues.Add(yValue); 15 } 16 } 17 18 //為MSChart綁定數據值 19 chart.Series[serieIndex].Points.DataBindXY(xValues, yValues);
為了確保圖形顯示完全,調整X和Y軸的最大值和最小值刻度:
1 if (yValues.Count > 0) 2 { 3 yAxisMax = 0; 4 return; 5 6 } 7 //將Y軸最大值放大倍作為 8 double yMax = Math.Round(yValues.Max() * 1.1, args.MostPrecision); 9 double xMin = xValues.Min(); 10 double xMax = xValues.Max(); 11 double yMin = yValues.Min(); 12 yAxisMax = yValues.Max(); 13 14 if (xMin > lsl) 15 { 16 xMin = lsl; 17 } 18 if (xMax < usl) 19 { 20 xMax = usl; 21 } 22 //設置軸值x軸加減極大極小值的1/zoomMultiple倍是為了圖形能全部繪制出來 23 chart.ChartAreas[0].AxisX.Minimum = (double)Math.Round(xMin - xMin * 1 / zoomMultiple, mostPrecision); 24 chart.ChartAreas[0].AxisX.Maximum = (double)Math.Round(xMax + xMax * 1 / zoomMultiple, mostPrecision); 25 chart.ChartAreas[0].AxisY.Minimum = (double)Math.Round(yMin, mostPrecision); 26 chart.ChartAreas[0].AxisY.Maximum = (double)Math.Round(yMax, mostPrecision);
分別添加XBAR、USL、LSL閾值限函數如下:

1 /// <summary> 2 /// 添加閾值線 3 /// </summary> 4 /// <param name="chartArea">圖形Area</param> 5 /// <param name="lineName">在線顯示的名子</param> 6 /// <param name="lineOffset">線在圖上的位置</param> 7 /// <param name="lineWidth">線寬</param> 8 /// <param name="lineColor">線的顏色</param> 9 public void AddStripLine(ChartArea chartArea, string lineName, double lineOffset, double lineWidth, Color lineColor) 10 { 11 StripLine stripLine = new StripLine 12 { 13 BackColor = lineColor, 14 StripWidth = lineWidth, 15 BackHatchStyle = ChartHatchStyle.DarkVertical, 16 Text = lineName, 17 TextAlignment = StringAlignment.Far, 18 TextLineAlignment = StringAlignment.Center, 19 IntervalOffset = lineOffset 20 }; 21 22 chartArea.AxisY.StripLines.Add(stripLine); 23 }
最后是根據樣本值重置X軸的最大和最小刻度

1 /// <summary> 2 /// 根據sampleData的最大和最小值重設X軸的最大和最小刻度 3 /// </summary> 4 /// <param name="queueValue"></param> 5 public static void ResetAxisBySampleData(List<decimal> sampleData, Chart chart) 6 { 7 if (sampleData == null || sampleData.Count <= 0) 8 { 9 SwapValue(chart); 10 return; 11 } 12 13 double max = (double) sampleData.Max(); 14 double min = (double) sampleData.Min(); 15 double xMax = chart.ChartAreas[0].AxisX.Maximum; 16 double xMin = chart.ChartAreas[0].AxisX.Minimum; 17 18 if (xMin > xMax) 19 { 20 chart.ChartAreas[0].AxisX.Minimum = min; 21 chart.ChartAreas[0].AxisX.Maximum = max; 22 } 23 }
以上是正態分布圖所用到的指標和函數,正態直方圖所用到的指標和函數下次再講,時間倉促,寫的不細。如有不明的請發郵件,我們一起探討。Mail:kingzheng@yeah.net 如要轉發,請注明出處!!