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

Pareto Chart C#

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (28投票s)

2015年1月24日

CPOL

5分钟阅读

viewsIcon

83597

downloadIcon

6014

使用 C# 的 Pareto Chart 控件

如果您喜欢我的文章和 Pareto Chart 控件,请留下评论,别忘了为我的文章投票。希望这个控件能帮到您。

引言

本文的主要目的是创建一个简单的 Pareto Chart 控件。市面上有一些第三方 Pareto Chart,也可以使用 MS Chart 控件制作 Pareto Chart。我的目标是创建一个简单的 Pareto Chart 用户控件。因此,是的,我使用 C#.NET 创建了一个 Pareto Chart 用户控件。首先,我们从 Pareto Chart 是什么开始。在我的 Pareto Chart 控件中,用户可以添加 X 轴绘图数据,最少 3 个,最多 10 个。您可以根据自己的需求修改我的源代码。通过少量源代码修改,您还可以将其更改为折线图、直方图和条形图。

Pareto Chart (帕累托图)

Pareto Chart 是条形图和折线图的组合。在 Pareto Chart 的 X 轴上,我们将绘制数据名称。在左侧 Y 轴上,我们将绘制数据频率,在右侧 Y 轴上,我们将绘制数据累积频率百分比。Pareto Chart 用于图形化地总结和显示不同数据组之间的相对重要性。

Pareto Chart 的规则是将最高到最低频率的数据作为条形图显示。将累积频率百分比数据显示为折线图。

这里,我们可以看到一个示例数据

S.No	Name	Freq	Cum Freq	Cum Per %
1	Pareto1	53	53	      19.27272727
2	pareto2	45	98	      35.63636364
3	pareto3	43	141	      51.27272727
4	pareto4	37	178	      64.72727273
5	pareto5	35	213	      77.45454545
6	pareto6	27	240	      87.27272727
7	pareto7	23	263	      95.63636364
8	pareto8	12	275	      100
	Sum	275	

上面的示例数据已在我的程序中使用以显示 Pareto Chart 的结果。从上面的数据中,我们可以看到。

Fre (频率)

频率是每个样本数据的总计数。例如,样本 pareto1 有 53 个数据计数,pareto2 有 45 个,依此类推。

频率 = 每个数据的总计数

Cum Freq (累积频率)

累积频率是前一个频率加上当前频率。例如,第一个频率是 53,所以累积频率将是 53。下一个频率是 45,所以累积频率将是 45+53=98,依此类推。

累积频率 = 前一个频率 + 当前频率 (对于第一个数据,前一个频率将为零)。

Cum per % (累积频率百分比)

累积频率百分比将通过累积频率除以频率总和再乘以 100 来计算。例如,频率总和是 275。第一个累积频率是 53,所以 53/275*100=19.27。

累积频率百分比 = 频率总和 / 当前累积频率 *100

从下图中,我们可以看到包含上述示例数据和结果的示例 Excel 文件,以及我的 Pareto Control Chart 和结果。

现在我们开始编写代码

我创建了一个 Pareto Chart 作为用户控件,以便可以在所有项目中轻松使用。

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

  1. "ShanuParetoChart_CTL" 文件夹 (此文件夹包含 Pareto Chart 用户控件的源代码)。

    注意:我将数据作为 DataTable 传递给用户控件。用户可以遵循相同的方法,或根据您的要求更改我的代码。

    DataTable 的格式是第一列为序号,第二列为数据名称,第三列为频率。对于我的示例,我将为每个样本传递总数据计数作为频率。我创建的 DataTable 如下所示

     DataTable dt = new DataTable();
     dt.Columns.Add("No");
                dt.Columns.Add("Names");
                dt.Columns.Add("Frequency");
                dt.Columns["Frequency"].DataType = Type.GetType("System.Int32");
  2. "SHANUParetoChart_DEMO" 文件夹 (此文件夹包含演示程序,其中包含带有使用 Timer 控件的随机数据样本的 paretoChart 用户控件)。

Using the Code

  1. 首先,我们将从用户控件开始。要创建用户控件,
    1. 创建一个新的 Windows 控件库项目。
    2. 设置项目名称,然后点击 确定 (此处,我的用户控件名称为 ShanuParetoChart_CTL)。
    3. 添加所有需要的控件。
    4. 在代码隐藏中,声明所有 public 变量和 Public 属性变量。
       private System.Windows.Forms.PictureBox PicBox;
              private System.Windows.Forms.Panel OuterPanel;
              private System.ComponentModel.Container components = null;
              private string m_sPicName = "";
              ContextMenuStrip docmenu = new System.Windows.Forms.ContextMenuStrip();
              ToolStripMenuItem saveimg = new ToolStripMenuItem();
      
              int NoofPlots = 5;
      
              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);       
      
             int[] intDataValue;
              int[] intCumulativeValue;
              Double[] intCumulativeValuePer;
              Double[] XaxisplotWidth;
      
              int First_chartDatarectHeight = 400;
              int First_chartDatarectWidth = 600;
              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);
    5. Picturebox Paint 方法中,我调用一个方法来绘制 Pareto Chart。我使用了 .NET GDI+ 来绘制 Pareto Chart 中的条形图和折线图,以及 Datatable 结果。在 paint 方法中,我检查 Datatable 数据,并将频率、累积频率和累积频率百分比存储到数组中。
         public void PicBox_Paint(object sender, PaintEventArgs e)
              {   
                  int opacity = 58; // 50% opaque (0 = invisible, 255 = fully opaque)
      
                  e.Graphics.DrawString("SHANU Pareto CHART",
                      new Font("Arial", 28),
                      new SolidBrush(Color.FromArgb(opacity, Color.OrangeRed)),
                      20,
                       10);
                  if (dt.Rows.Count <= 2)
                  {
                      return;
                  }
      
                  int NoofTrials = dt.Rows.Count;
                  int NoofParts = dt.Columns.Count - 1;
                  NoofPlots = NoofTrials;
      
                  intDataValue = new int[NoofTrials];
                  intCumulativeValue = new int[NoofTrials];
                  intCumulativeValuePer = new Double[NoofTrials];
                  if (dt.Rows.Count <= 2)
                  {
                      return;
                  }
                  int idataval = 0;
                  dt.DefaultView.Sort = "Frequency DESC";
                  dt = dt.DefaultView.ToTable();
      
                  for (int iRow = 0; iRow < dt.Rows.Count; iRow++)
                  {
                      intDataValue[idataval] = 
                         System.Convert.ToInt32(dt.Rows[iRow][2].ToString());
                      idataval = idataval + 1;
      
                  }
                  int sumofFrequence = intDataValue.Sum();
                  intCumulativeValue[0] = intDataValue[0];
                  intCumulativeValuePer[0] = 
                  Convert.ToDouble(intCumulativeValue[0]) / 
                          Convert.ToDouble(sumofFrequence) * 100;
                  for (int ival = 1; ival < intDataValue.Length; ival++)
                  {
      
                      intCumulativeValue[ival] = intCumulativeValue[ival - 1] + 
                                                 intDataValue[ival];
                      intCumulativeValuePer[ival] = Convert.ToDouble
                                                    (intCumulativeValue[ival]) / 
                                                    Convert.ToDouble(sumofFrequence) * 100;
                  }
      
                  drawPareto(e.Graphics, sumofFrequence);
              }

      在 "drawpareto" 函数中,检查所有数据并绘制 -X 轴、Y 轴(包括频率和累积频率百分比)。读取所有样本频率数据,并使用 DrawFill 矩形方法绘制条形图。

       public void drawPareto(Graphics e, int sumofFrequence)
              {
                  try
                  {
                      First_chartDatarectHeight = PicBox.Height - 20;
                      First_chartDatarectWidth = PicBox.Width - 20;
      
                      // 1) For the Chart Data Display ---------
                      e.DrawRectangle(Pens.Black, 10, 10, 
                      First_chartDatarectWidth, First_chartDatarectHeight);
      
                      int historgramHeigt = First_chartDatarectHeight - 30;
                      int historgramWidth = First_chartDatarectWidth - 20;
                      int StartXval = 80;
                      int startyval = 60;
      
                      // Measurement Horizontal Line
                      e.DrawLine(B1pen, StartXval, historgramHeigt, 
                                 historgramWidth, historgramHeigt);
      
                      //Frequency Vertical line
                      e.DrawLine(B1pen, StartXval, startyval, StartXval, historgramHeigt);
      
                      //Cumulative frequency Percentage Plotting
                      e.DrawLine(B1pen, historgramWidth, startyval, 
                                 historgramWidth, historgramHeigt);
      
                      //  NoofPlots =7;
                      //Draw Xaxis plots
                      int widthcalculation = (historgramWidth) / NoofPlots + 1;
                      if (widthcalculation <= StartXval)
                      {
                          widthcalculation = StartXval;
                      }
                      int XvalPosition = widthcalculation;
      
                      widthcalculation = widthcalculation - 18;
      
                      String[] Xaxisplotdata = new String[NoofPlots];
      
                      XaxisplotWidth = new Double[NoofPlots];
      
                      RectangleF rectF1 = new RectangleF(30, 10, 100, 122);
      
                      // End of Xaxis Plot
      
                      Double yValmaxDataVal = intDataValue.Max();
                      Double yValminDataVal = intDataValue.Min();
                      Double yValresultMaxMin = yValmaxDataVal - yValminDataVal;
      
                      //for plotting the xval data
                      Double yValMeasurementYAxisValue = yValmaxDataVal / NoofPlots;
                      int yValheightcalculation = historgramHeigt / NoofPlots;
                      int yValXvalPosition = yValheightcalculation;
      
                      Double plotYvals = yValmaxDataVal + 4;
      
                      Double[] YaxisplotHight = new Double[NoofPlots];
                      Double[] YaxisplotData = new Double[NoofPlots];
      
                      for (int ival = 0; ival < NoofPlots; ival++)
                      {
                          //Draw Xaxis plots
                          String MeasurementXAxisValue = dt.Rows[ival][1].ToString();
                          Xaxisplotdata[ival] = MeasurementXAxisValue;
                          e.DrawLine(B1pen, XvalPosition, 
                                historgramHeigt, XvalPosition, historgramHeigt + 15);
                          rectF1 = new RectangleF(XvalPosition, 
                                   historgramHeigt + 6, widthcalculation, 34);
                          e.DrawString(MeasurementXAxisValue.ToString(), f10, a2, rectF1);
                          // e.DrawRectangle(Pens.Black, Rectangle.Round(rectF1));
      
                          XaxisplotWidth[ival] = XvalPosition;
                          XvalPosition = XvalPosition + widthcalculation;
      
                          // End of Xaxis Plot
      
                          // Draw Y axis Plot
                          if (ival == NoofPlots - 1)
                          {
                              e.DrawString("0", f10, a2, StartXval - 12, 
                                           yValXvalPosition + 4);
                          }
                          else
                          {
                              e.DrawLine(B1pen, StartXval - 10, 
                              yValXvalPosition, StartXval, yValXvalPosition);
                              e.DrawString(Math.Round(plotYvals, 0).ToString(), 
                              f10, a2, StartXval - 20, yValXvalPosition + 4);
                          }
      
                          //else
                          //{
                          //    plotYvals = plotYvals - yValMeasurementYAxisValue;
                          //}
                          YaxisplotData[ival] = plotYvals;
                          plotYvals = plotYvals - yValMeasurementYAxisValue;
      
                          YaxisplotHight[ival] = yValXvalPosition;
                          yValXvalPosition = yValXvalPosition + yValheightcalculation;
      
                          //End of Yaxis Plot.
                      }
      
                      int widthcalculation_new = historgramWidth / NoofPlots;
      
                      int XvalPosition_Start = Convert.ToInt32(XaxisplotWidth[0]);
      
                      int XvalPosition_new = Convert.ToInt32(XaxisplotWidth[1]) - 
                                             XvalPosition_Start;
      
                      widthcalculation = widthcalculation - 18;
      
                      int Ystartval = 100;
                      int YEndval = 100;
                      //Fill Rectangle
                      LinearGradientBrush a6;// new LinearGradientBrush(new RectangleF
                      (StartXval, Ystartval, widthcalculation_new - StartXval, YEndval), 
                      Color.GreenYellow, Color.Green, LinearGradientMode.Vertical);
      
                      Font f2 = new Font("arial", 12, FontStyle.Bold, GraphicsUnit.Pixel);
                      for (int ival = 0; ival < YaxisplotData.Length - 1; ival++)
                      {
                          for (int yval = 1; yval < YaxisplotData.Length - 1; yval++)
                          {
      
                              Double finaldisplayvalue = YaxisplotHight[yval - 1] + 
                              ((YaxisplotData[yval - 1] - intDataValue[ival]) * 6);
      
      
                              if (intDataValue[ival] <= YaxisplotData[yval - 1] 
                              && intDataValue[ival] > YaxisplotData[yval])
                              {
      
                                  Ystartval = Convert.ToInt32(finaldisplayvalue);
                                  YEndval = historgramHeigt - 
                                            Convert.ToInt32(finaldisplayvalue);
                              }
      
                              else if (intDataValue[ival] <= YaxisplotData[yval - 1] 
                              && intDataValue[ival] < YaxisplotData[yval])
                              {
                                  //  Double finaldisplayvalue = YaxisplotHight[yval - 1] + 
                                  // ((YaxisplotData[yval - 1] - intDataValue[ival]));
      
                                  Ystartval = Convert.ToInt32(finaldisplayvalue);
                                  YEndval = historgramHeigt - 
                                            Convert.ToInt32(finaldisplayvalue);
                              }
                          }
      
                          if (YEndval > 2)
                          {
                          }
                          else
                          {
                              Ystartval = historgramHeigt - 2;
                              YEndval = 2;
                          }
                          a6 = new LinearGradientBrush
                               (new RectangleF(StartXval, Ystartval, 
                          XvalPosition_new, YEndval), Color.LightBlue, 
                          Color.CornflowerBlue, LinearGradientMode.Vertical);
      
                          XvalPosition_Start = Convert.ToInt32(XaxisplotWidth[ival]);
                          e.DrawRectangle(B1pen, XvalPosition_Start, 
                                          Ystartval, XvalPosition_new, YEndval);
                          e.FillRectangle(a6, XvalPosition_Start, 
                            Ystartval - 1, XvalPosition_new - 1, YEndval - 1);
                          e.DrawString(intDataValue[ival].ToString(), 
                            f2, a2, XvalPosition_Start + 10, Ystartval - 20);
      
                          XvalPosition_new = Convert.ToInt32(XaxisplotWidth[ival + 1]) - 
                          XvalPosition_Start;// XvalPosition_Start+
                                             // XvalPosition_new + widthcalculation_new;
      
                          if (ival == YaxisplotData.Length - 2)
                          {
                              for (int yval = 1; yval < YaxisplotData.Length - 1; yval++)
                              {
                                  if (intDataValue[ival + 1] <= YaxisplotData[yval - 1] 
                                  && intDataValue[ival] > YaxisplotData[yval])
                                  {
                                      Double finaldisplayvalue = YaxisplotHight[yval - 1] + 
                                      ((YaxisplotData[yval - 1] - 
                                      intDataValue[ival + 1]) * 6);
      
                                      Ystartval = Convert.ToInt32(finaldisplayvalue);
                                      YEndval = historgramHeigt - 
                                                Convert.ToInt32(finaldisplayvalue);
                                  }
                                  else if (intDataValue[ival + 1] <= 
                                                        YaxisplotData[yval - 1] 
                                  && intDataValue[ival + 1] < YaxisplotData[yval])
                                  {
                                      Double finaldisplayvalue = YaxisplotHight[yval - 1] + 
                                      ((YaxisplotData[yval - 1] - 
                                      intDataValue[ival + 1]) * 6);
      
                                      Ystartval = Convert.ToInt32(finaldisplayvalue);
                                      YEndval = historgramHeigt - 
                                                Convert.ToInt32(finaldisplayvalue);
                                  }
                              }
      
                              if (YEndval > 2)
                              {
                              }
                              else
                              {
                                  Ystartval = historgramHeigt - 2;
                                  YEndval = 2;
                              }
      
                              XvalPosition_Start = 
                                    Convert.ToInt32(XaxisplotWidth[ival + 1]);
      
                              if (XvalPosition_Start + XvalPosition_new > historgramWidth)
                              {
                                  XvalPosition_new = XvalPosition_new - 
                                  (XvalPosition_Start + 
                                   XvalPosition_new - historgramWidth);
                              }
      
                              //  a6 = new LinearGradientBrush(new RectangleF(StartXval, 
                              Ystartval, XvalPosition_new, YEndval), Color.GreenYellow, 
                                         Color.Green, LinearGradientMode.Vertical);
                              e.DrawRectangle(B1pen, XvalPosition_Start, 
                                              Ystartval, XvalPosition_new, YEndval);
                              e.FillRectangle(a6, XvalPosition_Start, Ystartval - 1, 
                                              XvalPosition_new - 1, YEndval - 1);
                              e.DrawString(intDataValue[ival + 1].ToString(), f2, a2, 
                                           XvalPosition_Start + 10, Ystartval - 20);
                          }
                      }
      
                      //Draw Line Curve on pareto Chart
                      drawParetoCurveLine(e);
                  }
                  catch (Exception ex)
                  {
                      MessageBox.Show(ex.ToString());
                  }
              }

      与上面的函数相同,我检查所有累积频率百分比数据,并使用 drawlinefillpie 方法绘制折线图。

        public void drawParetoCurveLine(Graphics e)
              {
                  First_chartDatarectHeight = PicBox.Height - 20;
                  First_chartDatarectWidth = PicBox.Width - 20;
      
                  int historgramHeigt = First_chartDatarectHeight - 30;
                  int historgramWidth = First_chartDatarectWidth - 20;
                  int StartXval = historgramWidth + 12;
                  int startyval = 60;
      
                  Double yValmaxDataVal = 100;
                  Double yValminDataVal = 0;
                  Double yValresultMaxMin = yValmaxDataVal - yValminDataVal;
                  int NoofPlots = 5;
                  Double yValMeasurementYAxisValue = yValmaxDataVal / NoofPlots;
                  int yValheightcalculation = historgramHeigt / NoofPlots;
                  int yValXvalPosition = startyval;// yValheightcalculation;
      
                  Double plotYvals = yValmaxDataVal;
      
                  Double[] YaxisplotHight = new Double[NoofPlots];
                  Double[] YaxisplotData = new Double[NoofPlots];
      
                  for (int ival = 0; ival <= NoofPlots - 1; ival++)
                  {
                      if (ival == NoofPlots)
                      {
                          e.DrawString("0", f10, a2, 
                                        StartXval - 12, yValXvalPosition + 4);
                      }
                      else
                      {
                          e.DrawLine(B1pen, StartXval - 10, yValXvalPosition, 
                                     StartXval, yValXvalPosition);
                          e.DrawString(Math.Round(plotYvals, 0).ToString() + 
                          "%", f10, a2, StartXval - 11, yValXvalPosition + 4);
                      }
      
                      YaxisplotData[ival] = plotYvals;
                      plotYvals = plotYvals - yValMeasurementYAxisValue;
      
                      YaxisplotHight[ival] = yValXvalPosition;
                      yValXvalPosition = yValXvalPosition + yValheightcalculation;
                  }
      
                  SolidBrush brush = new SolidBrush(Color.Aquamarine);
                  Random rnd = new Random();
      
                  NoofPlots = intCumulativeValuePer.Length;
      
                  int widthcalculation_new = historgramWidth / NoofPlots;
      
                  int XvalPosition_Start = Convert.ToInt32(XaxisplotWidth[0]);
      
                  int XvalPosition_new = Convert.ToInt32(XaxisplotWidth[1]) - 
                                         XvalPosition_Start;
      
                  int Ystartval = 100;
                  int YEndval = 100;
                  //Fill Rectangle
                  LinearGradientBrush a6 = new LinearGradientBrush
                                           (new RectangleF(StartXval, Ystartval, 
                  widthcalculation_new - StartXval, YEndval), Color.GreenYellow, 
                  Color.Green, LinearGradientMode.Vertical);
                  brush = new SolidBrush(Color.Aquamarine);
                  Pen pen = new Pen(Color.Gray);
                  Font f2 = new Font("arial", 12, FontStyle.Bold, GraphicsUnit.Pixel);
                  Point p1 = new Point();
                  Point p2 = new Point();
                  int smallLength = 
                      (historgramWidth / (intCumulativeValuePer.Length + 1));
                  Double smallHeight = 0;
                  // int smallX = topX;
                  for (int i = 0; i < intCumulativeValuePer.Length - 1; i++)
                  {
                      brush.Color = Color.FromArgb(rnd.Next(200, 255), rnd.Next(255),
                                    rnd.Next(255), rnd.Next(255));
                      p1 = p2;
      
                      if (i == 0)
                      {
                          p2.X = p2.X + smallLength + 40;
                      }
                      else
                      {
                          p2.X = p2.X + smallLength + 14;
                      }
      
                      smallHeight = YaxisplotHight[YaxisplotHight.Length - 1] + 
                      ((YaxisplotData[YaxisplotHight.Length - 1] - 
                                              intCumulativeValuePer[i]) * 2);
      
      
                      for (int yval = 1; yval < YaxisplotData.Length; yval++)
                      {
      
                          // Double finaldisplayvalue = YaxisplotHight[yval - 1] + 
                          // ((YaxisplotData[yval - 1] - intCumulativeValuePer[i])*10);
      
                          Double finaldisplayvalue = YaxisplotHight[yval] + 
                                                     ((YaxisplotData[yval] - 
                                                     intCumulativeValuePer[i]) * 2);
                          if (intCumulativeValuePer[i] <= YaxisplotData[yval - 1] && 
                                                          intCumulativeValuePer[i] > 
                                                          YaxisplotData[yval])
                          {
                              Ystartval = Convert.ToInt32(finaldisplayvalue);
                              smallHeight = Convert.ToInt32(finaldisplayvalue);
                          }
                      }
                      // smallHeight = historgramHeigt - YaxisplotHight[i]+150;
      
                      p2.Y = Convert.ToInt32(smallHeight);
                      if (p1.X != 0 && p1.Y != 0)
                      {
                          e.DrawLine(pen, p1, p2);
                      }
                      Color pointColor = new Color();
                      pointColor = Color.Green;
      
                      DrawDots(e, p2, pointColor);
                      e.DrawString(Math.Round(intCumulativeValuePer[i], 2).ToString(), 
                                   f2, a2, p2.X, p2.Y - 18);
      
                      if (i == 0)
                      {
                          smallLength = smallLength - 15;
                      }
      
                      if (i == intCumulativeValuePer.Length - 2)
                      {
                          p1.X = p2.X;
                          p1.Y = p2.Y;
                          for (int yval = 1; yval < YaxisplotData.Length; yval++)
                          {
      
                              // Double finaldisplayvalue = YaxisplotHight[yval - 1] + 
                              // ((YaxisplotData[yval - 1] - 
                              // intCumulativeValuePer[i])*10);
      
                              Double finaldisplayvalue = YaxisplotHight[yval] + 
                              ((YaxisplotData[yval] - intCumulativeValuePer[i + 1]) * 3);
                              if (intCumulativeValuePer[i + 1] <= 
                                  YaxisplotData[yval - 1] && 
                                  intCumulativeValuePer[i + 1] > YaxisplotData[yval])
                              {
      
                                  Ystartval = Convert.ToInt32(finaldisplayvalue);
                                  smallHeight = Convert.ToInt32(finaldisplayvalue);
                              }
                          }
                          //    p2.X = p2.X + smallLength - 24;
                          p2.Y = Convert.ToInt32(smallHeight);
                          if (p1.X != 0 && p1.Y != 0)
                          {
                              p2.X = p2.X + smallLength + 14;
                              e.DrawLine(pen, p1, p2);
                          }
                          DrawDots(e, p2, pointColor);
                          e.DrawString(Math.Round(intCumulativeValuePer[i + 1], 2).
                                       ToString(), f2, a2, p2.X, p2.Y - 18);
                      } } }

      我添加了一个用户友好的功能,可以将我的 Pareto Chart 保存为 Image。用户可以通过双击 Pareto Chart 控件或右键单击并选择保存来将 Pareto Chart 保存为 Image

       private void PicBox_DoubleClick(object sender, EventArgs e)
              {
                  saveImages();
              }
      
              private void docmenu_Click(object sender, EventArgs e)
              {
                  saveImages();
              }
      
              public void saveImages()
              {
                  if (dt.Rows.Count <= 0)
                  {
                      return;
                  }
      
                  using (var bitmap = new Bitmap(PicBox.Width, PicBox.Height))
                  {
                      PicBox.DrawToBitmap(bitmap, PicBox.ClientRectangle);
      
      
                      SaveFileDialog dlg = new SaveFileDialog();
                      dlg.FileName = "*";
                      dlg.DefaultExt = "bmp";
                      dlg.ValidateNames = true;
      
                      dlg.Filter = "Bitmap Image (.bmp)|*.bmp|Gif Image (.gif)|*.gif|
                                    JPEG Image (.jpeg)|*.jpeg|Png Image (.png)|*.png";
                      if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                      {
      
                          bitmap.Save(dlg.FileName);
                      }}
              }
    6. 完成保存后,构建并运行项目。
  2. 现在我们创建一个 Windows 应用程序并测试我们的 "ShanuParetoChart_CTL" 用户控件。
    1. 创建一个新的 Windows 项目。
    2. 打开您的窗体,然后在 工具箱 > 右键单击 > 选择项 > 浏览选择您的用户控件 DLL,然后 添加
    3. 将用户控件拖到您的 Windows 窗体上。
    4. 创建 DataTable 并将 Datatable 传递给我们的用户控件。
       public void loadGridColums()
              {
                  dt.Columns.Add("No");
                  dt.Columns.Add("Names");
                  dt.Columns.Add("Frequency");
                  dt.Columns["Frequency"].DataType = Type.GetType("System.Int32");
              }
    5. 在我的演示程序中,我使用了 Timer 来生成随机样本数据。我使用了 "button1" 作为切换按钮。第一次点击时启用并启动 Timer,再次点击同一个按钮时,停止 Timer。当 Timer Start 时,我生成一个随机数并将不同的数据传递给用户控件,并检查图表结果。
         private void frmShanuPaerto_Load(object sender, EventArgs e)
              {
                  loadgrid(1);
                  shanuParetoChart.Bindgrid(dt);   
              }
      
              private void button1_Click(object sender, EventArgs e)
              {
                  if (button1.Text == "Real Time Data ON")
                  {
                      timer1.Enabled = true;
                      timer1.Start();
                      button1.Text = "Real Time Data Off";
                  }
                  else
                  {
                      timer1.Enabled = false;
                      timer1.Stop();
                      button1.Text = "Real Time Data ON";
                  }
              }
      
              private void timer1_Tick(object sender, EventArgs e)
              {
                  loadgrid(2);
                  shanuParetoChart.Bindgrid(dt);   
              }

结论

本文的主要目的是创建一个简单易用的 Pareto chart 控件,该控件可以为许多用户提供帮助,让他们可以在自己的项目中免费使用和工作。

参考链接

历史

  • 2014 年 8 月 1 日:首次发布
  • 2014 年 8 月 5 日:添加了从 framework 4.0 到 2.0 的新降级版本 (有用户要求为 Framework 2.0 提供相同的控件)。
© . All rights reserved.