Home

GDI+ Example: Yearly Sales

 

Introduction

A rectangle chart is one that displays a series of rectangles that each represents a value. There are two types of rectangular charts: vertical or horizontal. With a vertical chart, the rectangles are oriented up and all have the same width. That's the type we will draw here. Because the values are typically different, each rectangle of a vertical chart may have a different height, depending on the values.

Practical LearningPractical Learning: Using a Hatch Brush

  1. Start a new Windows Forms Application named YearlySales2
  2. Design the form as follows:
     
    Company Yearly Sales
     
    Control Name Text
    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
    TextBox TextBox txtCurrentQtr3 8500
    TextBox TextBox txtCurrentQtr4 16800
    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
    TextBox TextBox txtPreviousQtr3 12500
    TextBox TextBox txtPreviousQtr4 15800
    Button Button Generate btnGenerate
    Label Label   _________ Legend _________
    Label Label   This Year's Sales
    Label Label   Last Year's Sales
  3. Right-click the form and click View Code
  4. Under the other using namespace lines, type:

    using namespace System::Drawing::Drawing2D;
  5. Declare two variables as follows:
     
    private:
    		/// <summary>
    		/// Required designer variable.
    		/// </summary>
    		System::ComponentModel::Container * components;
    		Graphics ^graphDrawingArea;
    		Bitmap   ^ bmpDrawingArea;
  6. Return to the form and double-click an unoccupied area of its body
  7. Implement the event as follows:
     
    System::Void Form1_Load(System::Object^  sender,
    			System::EventArgs^  e)
    {
        bmpDrawingArea   = gcnew Bitmap(Width, Height);
        graphDrawingArea = Graphics::FromImage(bmpDrawingArea);
    }
  8. Return to the form and click an empty area on it. In the Properties window, click the Events button Events
  9. Double-click the Paint field and implement its event as follows:
     
    System::Void Form1_Paint(System::Object^  sender, 
    			 System::Windows::Forms::PaintEventArgs^  e)
    {
        e->Graphics->DrawImage(bmpDrawingArea, 0, 0);
    }
  10. Return to the form and double-click the Generate button
  11. Implement the event as follows:
     
    System::Void btnGenerate_Click(System::Object ^  sender,
    				 System::EventArgs ^  e)
    {
        // Retrieve the values of the current year's sales
        int curQtr1 = int::Parse(txtCurrentQtr1->Text) / 100;
        int curQtr2 = int::Parse(txtCurrentQtr2->Text) / 100;
        int curQtr3 = int::Parse(txtCurrentQtr3->Text) / 100;
        int curQtr4 = int::Parse(txtCurrentQtr4->Text) / 100;
    
        // Create an array of Rectangle objects for the current year
        array<Rectangle> ^ rectCurrentYear  = {
    		 Rectangle(this->txtCurrentQtr1->Left+20,
    			   380-curQtr1, 40, curQtr1),
                     Rectangle(this->txtCurrentQtr2->Left+20,
    			   380-curQtr2, 40, curQtr2),
    		 Rectangle(this->txtCurrentQtr3->Left+20,
    			   380-curQtr3, 40, curQtr3),
    		 Rectangle(this->txtCurrentQtr4->Left+20,
    			   380-curQtr4, 40, curQtr4) };
    
        // Retrieve the values of last year's sales
        int prvQtr1 = int::Parse(txtPreviousQtr1->Text) / 100;
        int prvQtr2 = int::Parse(txtPreviousQtr2->Text) / 100;
        int prvQtr3 = int::Parse(txtPreviousQtr3->Text) / 100;
        int prvQtr4 = int::Parse(txtPreviousQtr4->Text) / 100;
    
        // Create an array of Rectangle objects for the previous year
        array<Rectangle> ^ rectPreviousYear = {
    		Rectangle(this->txtPreviousQtr1->Left+30,
    			  380-prvQtr1, 40, prvQtr1),
     		Rectangle(this->txtPreviousQtr2->Left+30,
    			  380-prvQtr2, 40, prvQtr2),
    	        Rectangle(this->txtPreviousQtr3->Left+30,
    			  380-prvQtr3, 40, prvQtr3),
    		Rectangle(this->txtPreviousQtr4->Left+30,
    			  380-prvQtr4, 40, prvQtr4) };
    
        // In case the user has changed the values, erase the previous chart
        graphDrawingArea->Clear(this->BackColor);
    
        HatchBrush ^ brushDiagCross  =
    	 gcnew HatchBrush(HatchStyle::DiagonalCross,
    			  Color::White, Color::Blue);
        HatchBrush ^ brushDotDiamond =
    	 gcnew 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(gcnew Pen(Color::Blue),
    				     rectPreviousYear);
        // Draw the chart for the current year in front
        graphDrawingArea->FillRectangles(brushDotDiamond,
    				     rectCurrentYear);
        graphDrawingArea->DrawRectangles(gcnew 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(gcnew 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(gcnew Pen(Color::Blue),
    				    this->lblLastYear->Left-30,
    				    this->lblLastYear->Top, 20, 14);
    
        graphDrawingArea->DrawRectangle(gcnew Pen(Color::Black),
    				    25, 380, Width - 220, 1);
        Invalidate();
    }
  12. Return to the form. Double-click the Close button and implement its Click event as follows:
     
    System::Void btnClose_Click(System::Object ^  sender,
    			 System::EventArgs ^  e)
    {
        Close();
    }
  13. Execute the application and test the form
     
     Yearly Sales
  14. After using it, close the form
  15. Change the Paint event of the form as follows:
     
    System::Void btnGenerate_Click(System::Object ^  sender,
    				 System::EventArgs ^  e)
    {
        // Retrieve the values of the current year's sales
        int curQtr1 = int::Parse(txtCurrentQtr1->Text) / 100;
        int curQtr2 = int::Parse(txtCurrentQtr2->Text) / 100;
        int curQtr3 = int::Parse(txtCurrentQtr3->Text) / 100;
        int curQtr4 = int::Parse(txtCurrentQtr4->Text) / 100;
    
        // Create an array of Rectangle objects for the current year
        array<Rectangle> ^ rectCurrentYear  = {
    		 Rectangle(this->txtCurrentQtr1->Left+20,
    			   380-curQtr1, 40, curQtr1),
                     Rectangle(this->txtCurrentQtr2->Left+20,
    			   380-curQtr2, 40, curQtr2),
    		 Rectangle(this->txtCurrentQtr3->Left+20,
    			   380-curQtr3, 40, curQtr3),
    		 Rectangle(this->txtCurrentQtr4->Left+20,
    			   380-curQtr4, 40, curQtr4) };
    
        // Retrieve the values of last year's sales
        int prvQtr1 = int::Parse(txtPreviousQtr1->Text) / 100;
        int prvQtr2 = int::Parse(txtPreviousQtr2->Text) / 100;
        int prvQtr3 = int::Parse(txtPreviousQtr3->Text) / 100;
        int prvQtr4 = int::Parse(txtPreviousQtr4->Text) / 100;
    
        // Create an array of Rectangle objects for the previous year
        array<Rectangle> ^ rectPreviousYear = {
    		Rectangle(this->txtPreviousQtr1->Left+30,
    			  380-prvQtr1, 40, prvQtr1),
     		Rectangle(this->txtPreviousQtr2->Left+30,
    			  380-prvQtr2, 40, prvQtr2),
    	        Rectangle(this->txtPreviousQtr3->Left+30,
    			  380-prvQtr3, 40, prvQtr3),
    		Rectangle(this->txtPreviousQtr4->Left+30,
    			  380-prvQtr4, 40, prvQtr4) };
    
        // In case the user has changed the values, erase the previous chart
        graphDrawingArea->Clear(this->BackColor);
    
        Rectangle rect(10, 190, 300, 210);
        LinearGradientBrush ^ linGradBrush =
    		gcnew LinearGradientBrush(rect,
    					  Color::FromArgb(204, 102, 0),
    					  Color::AntiqueWhite,
    				          LinearGradientMode::Vertical);
        graphDrawingArea->FillRectangle(linGradBrush, rect);
        graphDrawingArea->DrawRectangle(gcnew Pen(Color::Black), rect);
    
        HatchBrush ^ brushDiagCross  =
    	 gcnew HatchBrush(HatchStyle::DiagonalCross,
    			  Color::White, Color::Blue);
        HatchBrush ^ brushDotDiamond =
    	 gcnew 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(gcnew Pen(Color::Blue),
    				     rectPreviousYear);
        // Draw the chart for the current year in front
        graphDrawingArea->FillRectangles(brushDotDiamond,
    				     rectCurrentYear);
        graphDrawingArea->DrawRectangles(gcnew 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(gcnew 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(gcnew Pen(Color::Blue),
    				    this->lblLastYear->Left-30,
    				    this->lblLastYear->Top, 20, 14);
    
        graphDrawingArea->DrawRectangle(gcnew Pen(Color::Black),
    				    25, 380, Width - 220, 1);
        Invalidate();
    }
  16. Execute the application to test it:
     
  17. After using the form, close it
 

Home Copyright © 2007-2012 FunctionX