Csharp/C Sharp/Components/Chart

Материал из .Net Framework эксперт
Версия от 14:38, 26 мая 2010; Admin (обсуждение | вклад) (1 версия)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Pie Chart Demo

<source lang="csharp"> /* 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.ru/files/1604_CustomControls_SampleChapter.pdf

For More info on GDI+ Custom Control with Microsoft Visual C# book visit website www.packtpub.ru

  • /

using System; using System.Collections.Generic; using System.ruponentModel; 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.ruponentModel.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.ruponentModel.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;
       }
   }        

}

      </source>