다음을 통해 공유


C# Winform: Pareto Chart

 

Introduction

https://code.msdn.microsoft.com/site/view/file/145125/1/1.gif

The main aim of this article is to create a simple Pareto Chart Control.There are few Third party Pareto charts available and also Pareto chart can be made using MS Chart controls. My aim is to create a simple Pareto Chart User control. As a result, yes I have created a Pareto Chart user control using C#.Net. First, we start with what is Pareto chart. In my Pareto Chart control user can add X-axis Plot data from minimum 3 Plot data to maximum 10 Plot Data. This can be changed as per your requirement from my source code. With little source code modification, you can also change to Line Chart , Histogram Chart and Bar Chart.

Pareto Chart

Pareto Chart is a combination of both Bar graph and Line graph. In Pareto chart X-Axis we will plot the Data Names. In Left Y-Axis we will plot the Data Frequency and in Right side Y-Axis we will plot the Data Cumulative Frequency Percentage. A Pareto chart is used to graphically summarize and display the relative importance of the differences between groups of data.

The rules of Pareto chart are to start displaying highest to lowest Frequency data as bar graph. Display the Cumulative Frequency Percentage data as a Line Graph.

here we can see a Sample data.

S.No  Name  Freq  *** Freq  *** 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

The Above sample data has been used in my program to display the result of the Pareto chart. From the above data we can see.

**Fre(Frequency) **:

Frequency is the Total Count of data of the each sample .For example sample Pareto has 53 data count and Pareto has 45 and etc.

Frequency = Total Count of Each Data

*** Freq (Cumulative Frequency) :

Cumulative Frequency is previous frequency plus Current frequency. For example first frequency is 53 so the Cumulative Frequency will be as 53.Next Frequency is 45 so the Cumulative Frequency will be 45+53=98 and etc.

Cumulative Frequency =previous Frequency + Current Frequency (for first data previous frequency will be  as zero).

*** per % (Cumulative Frequency Percentage):

Cumulative Frequency Percentage will be calculated by Cumulative Frequency divided by Sum of Frequency and multiplied by 100. For Example Sum of Frequency is 275.First Cumulative Frequency is 53 so 53/275*100=19.27.

**Cumulative Frequency percentage =SUM of Frequency / Current Cumulative Frequency *100 

From the below image we can see the sample Excel file which has the above sample data with result and my Pareto Control Chart with result.

https://code.msdn.microsoft.com/site/view/file/145126/1/SHANUPareto2.JPG

Creating chart

Now we start with our Code:

I have created a Pareto Chart as a User Control so that it can be used easily in all projects.

In this article I have attached zip file named as SHANUParetoChart.zip which contains:

1) "ShanuParetoChart_CTL" Folder (This folder contains the Pareto Chart User control Source code.

Note: I will pass the data to the user control as DataTable. The user can fallow the same method or change my code as per your requirement.

The DataTable format is first Column as Serial No. The Second Column as Data Name and third Column as Frequency. For my sample i will pass the total Data count for every sample as Frequency. The DataTable I have created like this.

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" Folder (This folder contains the Demo program which includes the paretoChart user control with Random data sample using Timer control).

*

Description

1) First we will start with the User Control .To Create a user control.

  1. Create a new Windows Control Library project.
  2. Set the Name of Project and Click OK (here my user control name is ShanuParetoChart_CTL).
  3. Add all the controls which is needed.
  4. In code behind declare all the public variables and Public property variables.
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.In Picturebox Paint Method I call a Method to draw the Pareto chart.i have used .NET GDI+ to Draw both Bar and Line Graph in Pareto chart with the Datatable result.In paint method i check for the Datatable Data and store the Frequency ,Cumulative Frequency and Cumulative Frequency Percentage to a Array.

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

In "drawpareto" function check all data and draw -X axis,Y-Axis with both frequency and Cumulative frequency percentage.read all Sample frequency data and draw a bar graph using Draw and fill rectangle method.

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 Persentage 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()); 
  } 
 }

 Same like above function check for all Cumulative frequency percentage data and draw a line graph using the drawline and fillpie methods.

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

 I have added a user-friendly feature as to save my Pareto chart as Image.The user can save the Pareto chart as Image by double click on Pareto chart control or by right click and save.

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.After completion save, Build and run the project.

2) Now we create a Windows application and add test our "ShanuParetoChart_CTL" User Control.

  1. Create a new Windows project.
  2. Open your form and then from** Toolbox > right click > choose items > **browse select your user control dll and add.
  3. ** **Drag the User Control to your windows form.
  4. Create DataTable and pass Datatable to our user Control.
public void  loadGridColums() 
 { 
  dt.Columns.Add("No"); 
  dt.Columns.Add("Names"); 
  dt.Columns.Add("Frequency"); 
  dt.Columns["Frequency"].DataType = Type.GetType("System.Int32"); 
 }

5. In my demo program I have used the Timer for the random sample data. I have used the "button1" as Toggle button. When first time clicked Enabled and Start the Timer and same button clicked again Stop the Timer. When timer is Start I have generated a random no and pass the different data to user control and check for the chart result.

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

The main aim of this article is to create a simple user-friendly Pareto chart Control which will be useful for many users to use and work for free in their projects. I hope my Pareto chart control will be useful for many users from now on.

If you want to know more about Pareto Chart kindly refer this web site.This site has simple way of explaining about Pareto chart.

Download

You can download the Source Code from this link Download Source Code