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 an Array.
public void PicBox_Paint(object sender, PaintEventArgs e)
{
int opacity = 58;
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;
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;
e.DrawLine(B1pen, StartXval, historgramHeigt,
historgramWidth, historgramHeigt);
e.DrawLine(B1pen, StartXval, startyval, StartXval, historgramHeigt);
e.DrawLine(B1pen, historgramWidth, startyval,
historgramWidth, historgramHeigt);
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);
Double yValmaxDataVal = intDataValue.Max();
Double yValminDataVal = intDataValue.Min();
Double yValresultMaxMin = yValmaxDataVal - yValminDataVal;
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++)
{
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);
XaxisplotWidth[ival] = XvalPosition;
XvalPosition = XvalPosition + widthcalculation;
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);
}
YaxisplotData[ival] = plotYvals;
plotYvals = plotYvals - yValMeasurementYAxisValue;
YaxisplotHight[ival] = yValXvalPosition;
yValXvalPosition = yValXvalPosition + yValheightcalculation;
}
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;
LinearGradientBrush a6;
(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])
{
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;
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);
}
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);
}
}
drawParetoCurveLine(e);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Same like the above function, I 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;
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;
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;
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] +
((YaxisplotData[yval] -
intCumulativeValuePer[i]) * 2);
if (intCumulativeValuePer[i] <= YaxisplotData[yval - 1] &&
intCumulativeValuePer[i] >
YaxisplotData[yval])
{
Ystartval = Convert.ToInt32(finaldisplayvalue);
smallHeight = Convert.ToInt32(finaldisplayvalue);
}
}
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] +
((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.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
. User can save the Pareto chart as Image
by double clicking 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);
}}
}