Pie Chart Demo
/*
Code revised from chapter 13
GDI+ Custom Controls with Visual C# 2005
By Iulian Serban, Dragos Brezoi, Tiberiu Radu, Adam Ward
Language English
Paperback 272 pages [191mm x 235mm]
Release date July 2006
ISBN 1904811604
Sample chapter
http://www.packtpub.com/files/1604_CustomControls_SampleChapter.pdf
For More info on GDI+ Custom Control with Microsoft Visual C# book
visit website www.packtpub.com
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Collections;
using System.Drawing.Printing;
namespace PieChartApp
{
public partial class Form1 : Form
{
Color tempSliceColor;
string tempSliceName;
int tempSliceSize;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
pieChart1.AddSlice(new Slice("Mozzarella", 55, Color.FromArgb(255, 128, 128)));
pieChart1.AddSlice(new Slice("Gorgonzola", 15, Color.FromArgb(128, 255, 128)));
pieChart1.AddSlice(new Slice("Parmigiano", 25, Color.FromArgb(128, 128, 255)));
pieChart1.AddSlice(new Slice("Ricotta", 25, Color.FromArgb(255, 128, 255)));
// the first unnamed slice will be automatically named "Slice 0"
pieChart1.AddSlice(new Slice("", 25, Color.FromArgb(255, 255, 128)));
// the seconf unnamed slice will be automatically named "Slice 1"
pieChart1.AddSlice(new Slice("", 25, Color.FromArgb(128, 255, 255)));
// get the "Ricotta" slice
Slice tempSlice = pieChart1.GetSlice("Ricotta");
// if the slice exists i.e. has the name different form ""
if (tempSlice.GetSliceName() != "")
// and name it Ricotta cheese"
tempSlice.SetSliceName("Ricotta cheese");
}
private void button1_Click(object sender, EventArgs e)
{
pieChart1.Print(false);
}
private void pieChart1_Load(object sender, EventArgs e)
{
}
private void addSliceColorButton_Click(object sender, EventArgs e)
{
colorDialog1.ShowDialog();
tempSliceColor = colorDialog1.Color;
addSliceColorButton.BackColor = tempSliceColor;
}
private void addSliceButton_Click(object sender, EventArgs e)
{
if (addSliceNameTextBox.Text.ToString().Length <= 20)
{
tempSliceName = addSliceNameTextBox.Text;
}
else
{
MessageBox.Show("The entered name is not un up to 20 char string");
return;
}
if (ParseNumber(addSliceSizeTextBox.Text))
{
if (addSliceSizeTextBox.Text != "")
tempSliceSize = Int32.Parse(addSliceSizeTextBox.Text.ToString());
if (tempSliceSize == 0)
return;
}
else
{
MessageBox.Show("The entered size is not an up to 8 digit number!");
return;
}
if (tempSliceColor.A == 0)
tempSliceColor = Color.FromArgb(255, 255, 255, 255);
pieChart1.AddSlice(new Slice(tempSliceName, tempSliceSize, tempSliceColor));
pieChart1.Invalidate();
// clean name, size and color
addSliceNameTextBox.Text = "";
addSliceSizeTextBox.Text = "";
tempSliceName = "";
tempSliceColor = Color.FromArgb(255, 255, 255);
tempSliceSize = 0;
colorDialog1.Color = Color.FromArgb(255, 255, 255, 255);
addSliceColorButton.BackColor = Color.FromArgb(236, 233, 216);
}
private void removeSliceButton_Click(object sender, EventArgs e)
{
tempSliceName = removeSliceNameTextBox.Text;
pieChart1.RemoveSlice(tempSliceName);
}
private bool ParseNumber(string userNumber)
{
//create our parser that will do all our work for us
Regex parser = new Regex(@"^\d{0,8}$");
//return the bool result of parser's findings
return parser.IsMatch(userNumber);
}
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.addSliceButton = new System.Windows.Forms.Button();
this.addSliceColorButton = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.addSliceSizeTextBox = new System.Windows.Forms.TextBox();
this.addSliceNameTextBox = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.removeSliceButton = new System.Windows.Forms.Button();
this.removeSliceNameTextBox = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.colorDialog1 = new System.Windows.Forms.ColorDialog();
this.pieChart1 = new PieChartApp.PieChart();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(294, 383);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 1;
this.button1.Text = "Print";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.addSliceButton);
this.groupBox1.Controls.Add(this.addSliceColorButton);
this.groupBox1.Controls.Add(this.label3);
this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Controls.Add(this.addSliceSizeTextBox);
this.groupBox1.Controls.Add(this.addSliceNameTextBox);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Location = new System.Drawing.Point(51, 398);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(200, 139);
this.groupBox1.TabIndex = 2;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Add Slice";
//
// addSliceButton
//
this.addSliceButton.Location = new System.Drawing.Point(52, 110);
this.addSliceButton.Name = "addSliceButton";
this.addSliceButton.Size = new System.Drawing.Size(75, 23);
this.addSliceButton.TabIndex = 6;
this.addSliceButton.Text = "Add Slice";
this.addSliceButton.UseVisualStyleBackColor = true;
this.addSliceButton.Click += new System.EventHandler(this.addSliceButton_Click);
//
// addSliceColorButton
//
this.addSliceColorButton.Location = new System.Drawing.Point(52, 73);
this.addSliceColorButton.Name = "addSliceColorButton";
this.addSliceColorButton.Size = new System.Drawing.Size(75, 23);
this.addSliceColorButton.TabIndex = 5;
this.addSliceColorButton.Text = "Set Color";
this.addSliceColorButton.UseVisualStyleBackColor = true;
this.addSliceColorButton.Click += new System.EventHandler(this.addSliceColorButton_Click);
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(7, 73);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(34, 13);
this.label3.TabIndex = 4;
this.label3.Text = "Color:";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(7, 50);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(30, 13);
this.label2.TabIndex = 3;
this.label2.Text = "Size:";
//
// addSliceSizeTextBox
//
this.addSliceSizeTextBox.Location = new System.Drawing.Point(52, 47);
this.addSliceSizeTextBox.Name = "addSliceSizeTextBox";
this.addSliceSizeTextBox.Size = new System.Drawing.Size(100, 20);
this.addSliceSizeTextBox.TabIndex = 2;
//
// addSliceNameTextBox
//
this.addSliceNameTextBox.Location = new System.Drawing.Point(52, 20);
this.addSliceNameTextBox.Name = "addSliceNameTextBox";
this.addSliceNameTextBox.Size = new System.Drawing.Size(100, 20);
this.addSliceNameTextBox.TabIndex = 1;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(7, 20);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(38, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Name:";
//
// groupBox2
//
this.groupBox2.Controls.Add(this.removeSliceButton);
this.groupBox2.Controls.Add(this.removeSliceNameTextBox);
this.groupBox2.Controls.Add(this.label4);
this.groupBox2.Location = new System.Drawing.Point(423, 398);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(200, 130);
this.groupBox2.TabIndex = 3;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Remove Slice";
//
// removeSliceButton
//
this.removeSliceButton.Location = new System.Drawing.Point(32, 80);
this.removeSliceButton.Name = "removeSliceButton";
this.removeSliceButton.Size = new System.Drawing.Size(124, 23);
this.removeSliceButton.TabIndex = 2;
this.removeSliceButton.Text = "Remove Slice";
this.removeSliceButton.UseVisualStyleBackColor = true;
this.removeSliceButton.Click += new System.EventHandler(this.removeSliceButton_Click);
//
// removeSliceNameTextBox
//
this.removeSliceNameTextBox.Location = new System.Drawing.Point(50, 25);
this.removeSliceNameTextBox.Name = "removeSliceNameTextBox";
this.removeSliceNameTextBox.Size = new System.Drawing.Size(100, 20);
this.removeSliceNameTextBox.TabIndex = 1;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(6, 28);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(38, 13);
this.label4.TabIndex = 0;
this.label4.Text = "Name:";
//
// pieChart1
//
this.pieChart1.Location = new System.Drawing.Point(37, 25);
this.pieChart1.Name = "pieChart1";
this.pieChart1.SetArray = null;
this.pieChart1.Size = new System.Drawing.Size(538, 352);
this.pieChart1.TabIndex = 0;
this.pieChart1.Load += new System.EventHandler(this.pieChart1_Load);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(673, 581);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.button1);
this.Controls.Add(this.pieChart1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private PieChart pieChart1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button addSliceButton;
private System.Windows.Forms.Button addSliceColorButton;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox addSliceSizeTextBox;
private System.Windows.Forms.TextBox addSliceNameTextBox;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.Button removeSliceButton;
private System.Windows.Forms.TextBox removeSliceNameTextBox;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.ColorDialog colorDialog1;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
public partial class PieChart : UserControl
{
int totalCount;
ArrayList mySlices;
PrintDocument pieChartPrintDoc = null;
public PieChart()
{
InitializeComponent();
pieChartPrintDoc = new PrintDocument();
pieChartPrintDoc.PrintPage += new PrintPageEventHandler(_pieChartPrintDoc_PrintPage);
}
public ArrayList SetArray
{
get
{
return mySlices;
}
set
{
if (mySlices != value)
mySlices = value;
Invalidate();
}
}
private void SetValues()
{
totalCount = 0;
if (mySlices != null)
{
foreach (Slice slice in mySlices)
totalCount += slice.GetSliceRange();
}
//mySlicesPercent.Clear();
}
public bool AddSlice(Slice slice)
{
bool isThisSlice = false;
if (mySlices == null)
{
mySlices = new ArrayList();
mySlices.Add(slice);
return true;
}
foreach (Slice sliceTemp in mySlices)
{
if (sliceTemp.GetSliceName() == slice.GetSliceName())
isThisSlice = true;
}
if (isThisSlice == false)
{
mySlices.Add(slice);
Invalidate();
return true;
}
return false;
}
public bool RemoveSlice(string sliceName)
{
bool isThisSliceName = false;
foreach (Slice sliceTemp in mySlices)
{
if (sliceName == sliceTemp.GetSliceName())
{
mySlices.Remove(sliceTemp);
isThisSliceName = true;
break;
}
}
if (isThisSliceName)
Invalidate();
return isThisSliceName;
}
private void PieChart_Paint(object sender, PaintEventArgs e)
{
{
Pen penCircle = Pens.Black;
Pen penLine = Pens.BlanchedAlmond;
SetValues();
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
e.Graphics.DrawEllipse(penCircle, new Rectangle(1, 1, this.Width / 2 - 5, this.Width / 2 - 5));
if (mySlices != null)
{
int actualCount = 0;
// draw each slice
foreach (Slice slice in mySlices)
{
Pen penSlice = new Pen(slice.GetSliceColor());
int actualRangeSlice = slice.GetSliceRange();
int startAngle = (int)((actualCount / (double)totalCount) * 360);
int widthAngle = (int)(((actualRangeSlice) / (double)totalCount) * 360) + 1;
Brush br = new SolidBrush(slice.GetSliceColor());
e.Graphics.FillPie(br, new Rectangle(1, 1, this.Width / 2 - 5, this.Width / 2 - 5), startAngle, widthAngle);
e.Graphics.DrawPie(penCircle, new Rectangle(1, 1, this.Width / 2 - 5, this.Width / 2 - 5), startAngle, widthAngle);
actualCount += slice.GetSliceRange();
}
// draw the text within the legend
string itemName;
int itemFontSize = 64;
Font itemFont = new Font("SansSerif", itemFontSize);
StringFormat itemFormatName = new StringFormat(StringFormatFlags.NoClip);
itemFormatName.Alignment = StringAlignment.Near;
itemFormatName.LineAlignment = StringAlignment.Near;
int verticalPosition = 50;
// check if the text fits the legend
// if not -> modify the font
foreach (Slice slice in mySlices)
{
itemName = " ";
itemName += slice.GetSliceName();
itemName += " - " + string.Format("{0:f}", (double)(slice.GetSliceRange() / (double)totalCount * 100)) + "%";
SizeF itemSize = e.Graphics.MeasureString(itemName, itemFont);
Point position = new Point(this.Width / 2 + 40, verticalPosition);
while ((e.Graphics.MeasureString(itemName, itemFont).Width > (this.Width / 2 - 40)))
{
if (itemFontSize > 4)
itemFont = new Font("SansSerif", itemFontSize--);
else
return;
}
while ((50 + mySlices.Count * (e.Graphics.MeasureString(itemName, itemFont).Height + 5)) > (this.Height))
{
if (itemFontSize > 4)
itemFont = new Font("SansSerif", itemFontSize--);
else
return;
}
}
verticalPosition = 50;
// draw the legend outline
Font legendTitleFont = new Font("SansSerif", itemFontSize + 5);
e.Graphics.DrawString("Legend", legendTitleFont, Brushes.Black, new Point(this.Width / 2 + 20, 10));
int legendHeight = (int)(e.Graphics.MeasureString("Legend", legendTitleFont).Height) * 2;
// draw items text and colored rectangle
foreach (Slice slice in mySlices)
{
itemName = " ";
itemName += slice.GetSliceName();
itemName += " - " + string.Format("{0:f}", (double)(slice.GetSliceRange() / (double)totalCount * 100)) + "%";
SizeF itemSize = e.Graphics.MeasureString(itemName, itemFont);
Point position = new Point(this.Width / 2 + 40, verticalPosition);
e.Graphics.DrawRectangle(Pens.Black, new Rectangle(this.Width / 2 + 20, verticalPosition, 15, (int)itemSize.Height));
e.Graphics.FillRectangle(new SolidBrush(slice.GetSliceColor()), new Rectangle(this.Width / 2 + 20, verticalPosition, 15, (int)itemSize.Height));
e.Graphics.DrawString(itemName, itemFont, Brushes.Black, position, itemFormatName);
verticalPosition += (int)itemSize.Height + 5;
}
// draw the reactangle to include the legend
e.Graphics.DrawRectangle(Pens.Black, new Rectangle(this.Width / 2 + 5, 5, this.Width / 2 - 10, verticalPosition));
string stringName = "";
Font fontName = new Font("SansSerif", 8);
StringFormat formatName = new StringFormat(StringFormatFlags.NoClip);
formatName.Alignment = StringAlignment.Center;
formatName.LineAlignment = StringAlignment.Center;
Point pointName = new Point(this.Width / 8, 0);
double actualAngle = 0;
e.Graphics.TranslateTransform((float)(this.Width / 4.0), (float)(this.Width / 4.0));
// draw the text and percent for each slice
foreach (Slice slice in mySlices)
{
Pen penSlice = new Pen(slice.GetSliceColor());
double actualRangeSlice = slice.GetSliceRange();
double rotateAngle = ((((actualRangeSlice) / (double)totalCount) * 360)) / 2.0;
Brush br = new SolidBrush(Color.FromArgb(0, 0, 0));
e.Graphics.RotateTransform((float)(rotateAngle + actualAngle));
stringName = "";
stringName = string.Format("{0:f}", (double)(slice.GetSliceRange() / (double)totalCount * 100));
stringName += "% " + slice.GetSliceName();
if (e.Graphics.MeasureString(stringName, fontName).Width < (Width / 4))
e.Graphics.DrawString(stringName, fontName, br, pointName, formatName);
actualAngle = rotateAngle;
}
}
e.Graphics.Dispose();
}
}
public Slice GetSlice(string sliceName)
{
foreach (Slice sliceTemp in mySlices)
{
if (sliceName == sliceTemp.GetSliceName())
{
return sliceTemp;
}
}
// if there is no slice by a given name this function
// will return a null text, zero range, white slice
return new Slice("", 0, Color.FromArgb(255, 255, 255));
}
public void Print(bool hardcopy)
{
//create a PrintDialog based on the PrintDocument
PrintDialog pdlg = new PrintDialog();
pdlg.Document = pieChartPrintDoc;
//show the PrintDialog
if (pdlg.ShowDialog() == DialogResult.OK)
{
//create a PageSetupDialog based on the PrintDocument and PrintDialog
PageSetupDialog psd = new PageSetupDialog();
psd.EnableMetric = true; //Ensure all dialog measurements are in metric
psd.Document = pdlg.Document;
psd.PageSettings.Landscape = true; //Ensure landscape view
//show the PageSetupDialog
if (psd.ShowDialog() == DialogResult.OK)
{
//apply the settings of both dialogs
pieChartPrintDoc.DefaultPageSettings = psd.PageSettings;
//decide what action to take
if (hardcopy)
{
//actually print hardcopy
pieChartPrintDoc.Print();
}
else
{
//preview onscreen instead
PrintPreviewDialog prvw = new PrintPreviewDialog();
prvw.Document = pieChartPrintDoc;
prvw.ShowDialog();
}
}
}
}
private void _pieChartPrintDoc_PrintPage(object sender, PrintPageEventArgs e)
{
Pen penCircle = Pens.Black;
Pen penLine = Pens.BlanchedAlmond;
e.Graphics.Clip = new Region(e.MarginBounds);
Single x = e.MarginBounds.Left;
Single y = e.MarginBounds.Top;
int leftMargin = (int)x;
int topMargin = (int)y;
RectangleF mainTextArea = RectangleF.FromLTRB(x, y, e.MarginBounds.Right, e.MarginBounds.Bottom);
e.HasMorePages = false;
if ((this.Height > mainTextArea.Height) || (this.Width > mainTextArea.Width))
{
MessageBox.Show("The control doesn't fit in the page. Resize the control then try again printing");
return;
}
Pen contourPen = new Pen(Color.FromArgb(0, 0, 0), 2);
e.Graphics.DrawRectangle(contourPen, leftMargin, topMargin, this.Width, this.Height);
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
e.Graphics.DrawEllipse(penCircle, new Rectangle(leftMargin + 1, topMargin + 1, this.Width / 2 - 5, this.Width / 2 - 5));
if (mySlices != null)
{
int actualCount = 0;
// draw each slice
foreach (Slice slice in mySlices)
{
Pen penSlice = new Pen(slice.GetSliceColor());
int actualRangeSlice = slice.GetSliceRange();
int startAngle = (int)((actualCount / (double)totalCount) * 360);
int widthAngle = (int)(((actualRangeSlice) / (double)totalCount) * 360) + 1;
Brush br = new SolidBrush(slice.GetSliceColor());
e.Graphics.FillPie(br, new Rectangle(leftMargin + 1, topMargin + 1, this.Width / 2 - 5, this.Width / 2 - 5), startAngle, widthAngle);
e.Graphics.DrawPie(penCircle, new Rectangle(leftMargin + 1, topMargin + 1, this.Width / 2 - 5, this.Width / 2 - 5), startAngle, widthAngle);
actualCount += slice.GetSliceRange();
}
// draw the text within the legend
string itemName;
int itemFontSize = 64;
Font itemFont = new Font("SansSerif", itemFontSize);
StringFormat itemFormatName = new StringFormat(StringFormatFlags.NoClip);
itemFormatName.Alignment = StringAlignment.Near;
itemFormatName.LineAlignment = StringAlignment.Near;
int verticalPosition = 50;
// check if the text fits the legend
// if not -> modify the font
foreach (Slice slice in mySlices)
{
itemName = " ";
itemName += slice.GetSliceName();
itemName += " - " + string.Format("{0:f}", (double)(slice.GetSliceRange() / (double)totalCount * 100)) + "%";
SizeF itemSize = e.Graphics.MeasureString(itemName, itemFont);
Point position = new Point(this.Width / 2 + 40 + leftMargin, verticalPosition + topMargin);
while ((e.Graphics.MeasureString(itemName, itemFont).Width > (this.Width / 2 - 40)))
{
if (itemFontSize > 4)
itemFont = new Font("SansSerif", itemFontSize--);
else
return;
}
while ((50 + mySlices.Count * (e.Graphics.MeasureString(itemName, itemFont).Height + 5)) > (this.Height))
{
if (itemFontSize > 4)
itemFont = new Font("SansSerif", itemFontSize--);
else
return;
}
}
verticalPosition = 50;
// draw the legend title
Font legendTitleFont = new Font("SansSerif", itemFontSize + 5);
e.Graphics.DrawString("Legend", legendTitleFont, Brushes.Black, new Point(leftMargin + this.Width / 2 + 20, topMargin + 10));
int legendHeight = (int)(e.Graphics.MeasureString("Legend", legendTitleFont).Height) * 2 + topMargin;
// draw items text and colored rectangle
foreach (Slice slice in mySlices)
{
itemName = " ";
itemName += slice.GetSliceName();
itemName += " - " + string.Format("{0:f}", (double)(slice.GetSliceRange() / (double)totalCount * 100)) + "%";
SizeF itemSize = e.Graphics.MeasureString(itemName, itemFont);
Point position = new Point(leftMargin + this.Width / 2 + 40, topMargin + verticalPosition);
e.Graphics.DrawRectangle(Pens.Black, new Rectangle(leftMargin + this.Width / 2 + 20, topMargin + verticalPosition, 15, (int)itemSize.Height));
e.Graphics.FillRectangle(new SolidBrush(slice.GetSliceColor()), new Rectangle(leftMargin + this.Width / 2 + 20, topMargin + verticalPosition, 15, (int)itemSize.Height));
e.Graphics.DrawString(itemName, itemFont, Brushes.Black, position, itemFormatName);
verticalPosition += (int)itemSize.Height + 5;
}
// draw the legend outline
e.Graphics.DrawRectangle(Pens.Black, new Rectangle(leftMargin + this.Width / 2 + 5, topMargin + 5, this.Width / 2 - 10, verticalPosition));
string stringName = "";
Font fontName = new Font("SansSerif", 8);
StringFormat formatName = new StringFormat(StringFormatFlags.NoClip);
formatName.Alignment = StringAlignment.Center;
formatName.LineAlignment = StringAlignment.Center;
Point pointName = new Point(this.Width / 8, 0);
double actualAngle = 0;
e.Graphics.TranslateTransform((float)(this.Width / 4.0 + leftMargin), (float)(this.Width / 4.0 + topMargin));
// draw the text and percent for each slice
foreach (Slice slice in mySlices)
{
Pen penSlice = new Pen(slice.GetSliceColor());
double actualRangeSlice = slice.GetSliceRange();
double rotateAngle = ((((actualRangeSlice) / (double)totalCount) * 360)) / 2.0;
Brush br = new SolidBrush(Color.FromArgb(0, 0, 0));
e.Graphics.RotateTransform((float)(rotateAngle + actualAngle));
stringName = "";
stringName = string.Format("{0:f}", (double)(slice.GetSliceRange() / (double)totalCount * 100));
stringName += "% " + slice.GetSliceName();
if (e.Graphics.MeasureString(stringName, fontName).Width < (Width / 4))
e.Graphics.DrawString(stringName, fontName, br, pointName, formatName);
actualAngle = rotateAngle;
}
}
}
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// PieChart
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "PieChart";
this.Paint += new System.Windows.Forms.PaintEventHandler(this.PieChart_Paint);
this.ResumeLayout(false);
}
#endregion
}
public class Slice
{
private string sliceName;
private int sliceRange;
private Color sliceColor;
// countNoName is static to know in all instances of the
// slice class what is this count
private static int countNoName = 0;
private Slice()
{
}
public Slice(string name, int range, Color color)
{
if (name == "")
{
sliceName = "Slice " + countNoName.ToString();
countNoName++;
}
else
sliceName = name;
if (range < 0)
range = 0;
else
sliceRange = range;
sliceColor = color;
}
public string GetSliceName()
{
return sliceName;
}
public int GetSliceRange()
{
return sliceRange;
}
public Color GetSliceColor()
{
return sliceColor;
}
public void SetSliceName(string name)
{
if (name == "")
{
sliceName = "Slice " + countNoName.ToString();
countNoName++;
}
else
sliceName = name;
}
public void SetSliceRange(int range)
{
if (range < 0)
range = 0;
else
sliceRange = range;
}
public void SetSliceColor(Color color)
{
sliceColor = color;
}
}
}
Related examples in the same category