Home

.NET Examples: 2-Column Chart

 

Introduction

This exercise applies the concepts reviewed for drawing shapes. In this case, we will draw some rectangles to product a (vertical) column chart.

Practical LearningPractical Learning: Drawing a Series of Rectangles

  1. Start a new Windows Forms Application named YearlySales1
  2. Set the form's Icon to Drive:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Graphics\icons\Office\GRAPH08.ICO
  3. Design the form as follows:
     
    Form Design
     
    Control Name Text Other Properties
    GroupBox GroupBox   Current Year's Sales  
    Label Label   1st Qtr  
    Label Label   2nd Qtr  
    Label Label   3rd Qtr  
    Label Label   4th Qtr  
    TextBox TextBox txtCurrentQtr1 1200  
    TextBox TextBox txtCurrentQtr2 14500 TextAlign: Right
    TextBox TextBox txtCurrentQtr3 8500 TextAlign: Right
    TextBox TextBox txtCurrentQtr4 16800 TextAlign: Right
    Button Button Close btnClose  
    GroupBox GroupBox   Previous Year's Sales  
    Label Label   1st Qtr  
    Label Label   2nd Qtr  
    Label Label   3rd Qtr  
    Label Label   4th Qtr  
    TextBox TextBox txtPreviousQtr1 10000  
    TextBox TextBox txtPreviousQtr2 11000 TextAlign: Right
    TextBox TextBox txtPreviousQtr3 12500 TextAlign: Right
    TextBox TextBox txtPreviousQtr4 15800 TextAlign: Right
    Button Button Generate btnGenerate  
    Label Label   _________ Legend _________  
    Label Label   This Year's Sales  
    Label Label   Last Year's Sales  
  4. Double-click an unoccupied area on the form and implement its Load event as follows:
     
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;
    
    namespace YearlySales1
    {
    	/// <summary>
    	/// Summary description for Form1.
    	/// </summary>
    	public class Form1 : System.Windows.Forms.Form
    	{
    		/// <summary>
    		/// Required designer variable.
    		/// </summary>
    		private System.ComponentModel.Container components = null;
    		Graphics graphDrawingArea;
    		Bitmap   bmpDrawingArea;
    
    		
    
    		. . . No Change
    		#endregion
    
    		/// <summary>
    		/// The main entry point for the application.
    		/// </summary>
    		[STAThread]
    		static void Main() 
    		{
    			Application.Run(new Form1());
    		}
    
    		private void Form1_Load(object sender, System.EventArgs e)
    		{
    			bmpDrawingArea   = new Bitmap(Width, Height);
    			graphDrawingArea = Graphics.FromImage(bmpDrawingArea);
    		}
    	}
    }
  5. Return to the form and click an empty area on it. In the Properties window, click the Events button Events
  6. Double-click the Paint field and implement its event as follows:
     
    private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    		{
    			e.Graphics.DrawImage(bmpDrawingArea, 0, 0);
    		}
  7. Double-click the Generate button and implement its Click event as follows:
     
    private void btnGenerate_Click(object sender, System.EventArgs e)
    {
    	 // Retrieve the values of the current year's sales
    	 int curQtr1 = int.Parse(this.txtCurrentQtr1.Text) / 100;
    	 int curQtr2 = int.Parse(this.txtCurrentQtr2.Text) / 100;
    	 int curQtr3 = int.Parse(this.txtCurrentQtr3.Text) / 100;
    	 int curQtr4 = int.Parse(this.txtCurrentQtr4.Text) / 100;
    
    	 // Create an array of Rectangle objects for the current year
    	 Rectangle[] rectCurrentYear = { new Rectangle(this.txtCurrentQtr1.Left+20, 350-curQtr1, 40, curQtr1),
    			             new Rectangle(this.txtCurrentQtr2.Left+20, 350-curQtr2, 40, curQtr2),
    			             new Rectangle(this.txtCurrentQtr3.Left+20, 350-curQtr3, 40, curQtr3),
    			             new Rectangle(this.txtCurrentQtr4.Left+20, 350-curQtr4, 40, curQtr4) };
    
    	 // Retrieve the values of last year's sales
    	 int prvQtr1 = int.Parse(this.txtPreviousQtr1.Text) / 100;
    	 int prvQtr2 = int.Parse(this.txtPreviousQtr2.Text) / 100;
    	 int prvQtr3 = int.Parse(this.txtPreviousQtr3.Text) / 100;
    	 int prvQtr4 = int.Parse(this.txtPreviousQtr4.Text) / 100;
    
    	 // Create an array of Rectangle objects for the previous year
    	 Rectangle[] rectPreviousYear = { new Rectangle(this.txtPreviousQtr1.Left+30, 350-prvQtr1, 40, prvQtr1),
     			                  new Rectangle(this.txtPreviousQtr2.Left+30, 350-prvQtr2, 40, prvQtr2),
    	             			      new Rectangle(this.txtPreviousQtr3.Left+30, 350-prvQtr3, 40, prvQtr3),
    			                  new Rectangle(this.txtPreviousQtr4.Left+30, 350-prvQtr4, 40, prvQtr4) };
    			 
    	 // In case the user has changed the values, erase the previous chart
    	 graphDrawingArea.Clear(this.BackColor);
    
    	 // Draw the chart for the previous year first to send it back
    	 graphDrawingArea.DrawRectangles(new Pen(Color.Blue), rectPreviousYear);
    	 // Draw the chart for the current year in front
    	 graphDrawingArea.DrawRectangles(new Pen(Color.Red), rectCurrentYear);
    		
    	 // Draw the small rectangles of the legend
    graphDrawingArea.DrawRectangle(new Pen(Color.Blue), this.lblCurYear.Left-30, this.lblCurYear.Top,  14, 10);
    graphDrawingArea.DrawRectangle(new Pen(Color.Red), this.lblLastYear.Left-30, this.lblLastYear.Top, 14, 10);
    
    	 graphDrawingArea.DrawRectangle(new Pen(Color.Black), 25, 350, Width - 220, 1);
    	 Invalidate();
    }
  8. Return to the form. Double-click the Close button and implement its Click event as follows:
     
    private void btnClose_Click(object sender, System.EventArgs e)
    		{
    			 Close();
    		}
  9. Execute the application and test the form
     
     Column Chart
  10. After using it, close the form
  11. To fill the rectangles with colors, change the implementation of the Click event of the Generate button as follows:
     
    private void btnGenerate_Click(object sender, System.EventArgs e)
    {
    	 // Retrieve the values of the current year's sales
    	 int curQtr1 = int.Parse(this.txtCurrentQtr1.Text) / 100;
    	 int curQtr2 = int.Parse(this.txtCurrentQtr2.Text) / 100;
    	 int curQtr3 = int.Parse(this.txtCurrentQtr3.Text) / 100;
    	 int curQtr4 = int.Parse(this.txtCurrentQtr4.Text) / 100;
    
    			 // Create an array of Rectangle objects for the current year
    	 Rectangle[] rectCurrentYear = { new Rectangle(this.txtCurrentQtr1.Left+20, 350-curQtr1, 40, curQtr1),
    		                             new Rectangle(this.txtCurrentQtr2.Left+20, 350-curQtr2, 40, curQtr2),
    				 new Rectangle(this.txtCurrentQtr3.Left+20, 350-curQtr3, 40, curQtr3),
    				 new Rectangle(this.txtCurrentQtr4.Left+20, 350-curQtr4, 40, curQtr4) };
    
    	 // Retrieve the values of last year's sales
    	 int prvQtr1 = int.Parse(this.txtPreviousQtr1.Text) / 100;
    	 int prvQtr2 = int.Parse(this.txtPreviousQtr2.Text) / 100;
    	 int prvQtr3 = int.Parse(this.txtPreviousQtr3.Text) / 100;
    	 int prvQtr4 = int.Parse(this.txtPreviousQtr4.Text) / 100;
    
    	 // Create an array of Rectangle objects for the previous year
    	 Rectangle[] rectPreviousYear = { new Rectangle(this.txtPreviousQtr1.Left+30, 350-prvQtr1, 40, prvQtr1),
     			                  new Rectangle(this.txtPreviousQtr2.Left+30, 350-prvQtr2, 40, prvQtr2),
    	             			      new Rectangle(this.txtPreviousQtr3.Left+30, 350-prvQtr3, 40, prvQtr3),
    			                  new Rectangle(this.txtPreviousQtr4.Left+30, 350-prvQtr4, 40, prvQtr4) };
    
    	 // In case the user has changed the values, erase the previous chart
    	 graphDrawingArea.Clear(this.BackColor);
    
    	 HatchBrush brushDiagCross  = new HatchBrush(HatchStyle.DiagonalCross, Color.White, Color.Blue);
    	 HatchBrush brushDotDiamond = new HatchBrush(HatchStyle.DottedDiamond, Color.Fuchsia, Color.Brown);
    
    	 // Draw the chart for the previous year first to send it back
    	 graphDrawingArea.FillRectangles(brushDiagCross, rectPreviousYear);
    	 graphDrawingArea.DrawRectangles(new Pen(Color.Blue), rectPreviousYear);
    	 // Draw the chart for the current year in front
    	 graphDrawingArea.FillRectangles(brushDotDiamond, rectCurrentYear);
    	 graphDrawingArea.DrawRectangles(new Pen(Color.Red), rectCurrentYear);
    
    	 // Draw the small rectangles of the legend
    	 graphDrawingArea.FillRectangle(brushDotDiamond, this.lblCurYear.Left-30, this.lblCurYear.Top,  20, 14);
    	 graphDrawingArea.DrawRectangle(new Pen(Color.Red), this.lblCurYear.Left-30, this.lblCurYear.Top,  20, 14);
    	 graphDrawingArea.FillRectangle(brushDiagCross, this.lblLastYear.Left-30, this.lblLastYear.Top, 20, 14);
    	 graphDrawingArea.DrawRectangle(new Pen(Color.Blue), this.lblLastYear.Left-30, this.lblLastYear.Top, 20, 14);
    
    	 graphDrawingArea.DrawRectangle(new Pen(Color.Black), 25, 350, Width - 220, 1);
    	 Invalidate();
    }
  12. Return to the form. Double-click the Close button and implement its Click event as follows:
     
    private void btnClose_Click(object sender, System.EventArgs e)
    {
    	 Close();
    }
  13. Execute the application and test the form
     
     Solid Brush used to fill the rectangles
  14. After using it, close the form
  15. To draw a background behind the chart, change the Click event of the Generate button as follows:
     
    private void btnGenerate_Click(object sender, System.EventArgs e)
    {
    	 // Retrieve the values of the current year's sales
    	 int curQtr1 = int.Parse(this.txtCurrentQtr1.Text) / 100;
    	 int curQtr2 = int.Parse(this.txtCurrentQtr2.Text) / 100;
    	 int curQtr3 = int.Parse(this.txtCurrentQtr3.Text) / 100;
    	 int curQtr4 = int.Parse(this.txtCurrentQtr4.Text) / 100;
    
    			 // Create an array of Rectangle objects for the current year
    	 Rectangle[] rectCurrentYear = { new Rectangle(this.txtCurrentQtr1.Left+20, 350-curQtr1, 40, curQtr1),
    		                             new Rectangle(this.txtCurrentQtr2.Left+20, 350-curQtr2, 40, curQtr2),
    				 new Rectangle(this.txtCurrentQtr3.Left+20, 350-curQtr3, 40, curQtr3),
    				 new Rectangle(this.txtCurrentQtr4.Left+20, 350-curQtr4, 40, curQtr4) };
    
    	 // Retrieve the values of last year's sales
    	 int prvQtr1 = int.Parse(this.txtPreviousQtr1.Text) / 100;
    	 int prvQtr2 = int.Parse(this.txtPreviousQtr2.Text) / 100;
    	 int prvQtr3 = int.Parse(this.txtPreviousQtr3.Text) / 100;
    	 int prvQtr4 = int.Parse(this.txtPreviousQtr4.Text) / 100;
    
    	 // Create an array of Rectangle objects for the previous year
    	 Rectangle[] rectPreviousYear = { new Rectangle(this.txtPreviousQtr1.Left+30, 350-prvQtr1, 40, prvQtr1),
     			                  new Rectangle(this.txtPreviousQtr2.Left+30, 350-prvQtr2, 40, prvQtr2),
    	             			      new Rectangle(this.txtPreviousQtr3.Left+30, 350-prvQtr3, 40, prvQtr3),
    			                  new Rectangle(this.txtPreviousQtr4.Left+30, 350-prvQtr4, 40, prvQtr4) };
    
    	 // In case the user has changed the values, erase the previous chart
    	 graphDrawingArea.Clear(this.BackColor);
    
    	 Rectangle rect = new Rectangle(20, 175, 300, 175);
    	 LinearGradientBrush linGradBrush = new LinearGradientBrush(rect,
    				 Color.FromArgb(204, 102, 0),
    				 Color.AntiqueWhite,
    				 LinearGradientMode.Vertical);
    	 graphDrawingArea.FillRectangle(linGradBrush, rect);
    	 graphDrawingArea.DrawRectangle(new Pen(Color.Black), rect);
    
    	 HatchBrush brushDiagCross  = new HatchBrush(HatchStyle.DiagonalCross, Color.White, Color.Blue);
    	 HatchBrush brushDotDiamond = new HatchBrush(HatchStyle.DottedDiamond, Color.Fuchsia, Color.Brown);
    
    	 // Draw the chart for the previous year first to send it back
    	 graphDrawingArea.FillRectangles(brushDiagCross, rectPreviousYear);
    	 graphDrawingArea.DrawRectangles(new Pen(Color.Blue), rectPreviousYear);
    	 // Draw the chart for the current year in front
    	 graphDrawingArea.FillRectangles(brushDotDiamond, rectCurrentYear);
    	 graphDrawingArea.DrawRectangles(new Pen(Color.Red), rectCurrentYear);
    
    	 // Draw the small rectangles of the legend
    	 graphDrawingArea.FillRectangle(brushDotDiamond, this.lblCurYear.Left-30, this.lblCurYear.Top,  20, 14);
    	 graphDrawingArea.DrawRectangle(new Pen(Color.Red), this.lblCurYear.Left-30, this.lblCurYear.Top,  20, 14);
    	 graphDrawingArea.FillRectangle(brushDiagCross, this.lblLastYear.Left-30, this.lblLastYear.Top, 20, 14);
    	 graphDrawingArea.DrawRectangle(new Pen(Color.Blue), this.lblLastYear.Left-30, this.lblLastYear.Top, 20, 14);
    
    	 graphDrawingArea.DrawRectangle(new Pen(Color.Black), 25, 350, Width - 220, 1);
    	 Invalidate();
    }
  16. Execute the application to test it:
     
    A background for the chart
  17. After using the form, close it
 

Home Copyright © 2004-2010 FunctionX, Inc.