Click here to Skip to main content
15,881,248 members
Articles / Multimedia / GDI+
Article

Drawing a Dynamic Chart in C#

Rate me:
Please Sign up or sign in to vote.
2.67/5 (50 votes)
8 Feb 20053 min read 327.2K   15.6K   67   19
This article describes how to design a dynamic chart in C#.

Introduction

We are going to design a dynamic chart using the Graphics class built into the .NET framework. It will be a dynamic chart because the data will be passed to the chart through an external .ocx file. The chart will read the data in this external file, and then draw the chart according to the data it has been given.

Data Page

Image 1

The data is entered on this page. I have entered default data so that you don't have to enter anything into the textboxes, however if you wish to enter data, then you can see how this dynamically affects the chart.

Chart

Image 2

I have designed the chart to "autoscale". This means that the chart will determine the largest integer sent to it, and then adjust the scale on its "X" axis accordingly. We do this because we want the chart to fall within the limits of the scale. In other words we don't want the chart appear so small at the bottom that it cannot be interpreted properly, and we don't want the chart to overflow the limits of the scale. The maximum integer accepted by this chart is 1,000. We have scales of "0 - 10", "0 - 50", "0 - 100", "0 - 250", "0 - 500", and "0 - 1000". The "Y" axis of the chart is set to read the months of the year. We therefore need 12 rectangles, so that there will be a "bar" for each month.

I derived formulas for calculating the Y position of each scale. The bottom of the chart's Y value is 600, so the top of our rectangle will be a ratio determined by the scale subtracted from 600. For example, when our scale is "0 - 1000", the Y position of the top of our rectangle is determined by the formula:

Chart1 = 600 - (5 * Qso1)/ 10;

The X position of the rectangle is set according to the width of the chart, the number of months in a year (for this chart), and the width of each rectangle:

X Position = 
  Bar Chart No * ((Chart Width)/(No of Rectangles) - (Rectangle Width)/2)

I sort the data passed to the chart, in ascending order, to determine what the largest value of data is that has been passed to the chart. After I call this sorting method, these values are reassigned to another array (int [] d ). The last integer in this array is the largest integer. Determining this largest integer is the only purpose of this array, and it does not affect how the data is drawn. This array only affects which scale is to be used.

The values that have been passed are assigned to a rectangle position on the screen, and the monthly figures are represented in the chart. This integer is drawn at the top of the bar to clarify its value.

Sample code

C#
private void bttnStart_Click(object sender, System.EventArgs e)
{
    // Instantiate new StreamReader
    StreamReader streamQso = new StreamReader( riteFileName );
    readQso = streamQso.ReadToEnd();
    streamQso.Close();
    // define trimchars[] and split string
    char[] trimChars = {'\u002c'};
    passQso = Regex.Split( readQso, @",\s*");
                
    Graphics graph = this.CreateGraphics();
    SolidBrush brush = new SolidBrush(Color.Red);
                
    FontStyle style3 = FontStyle.Regular;
    Font arial3 = new Font( new FontFamily( "Arial" ), 12, style3 );
    
    FontStyle style4 = FontStyle.Bold;
    Font arial4 = new Font( new FontFamily( "Arial" ), 40, style4 );
    
    // pass integer values to private integer
    this.Qso1 = Int32.Parse(passQso[0]);
    this.Qso2 = Int32.Parse(passQso[1]);
    this.Qso3 = Int32.Parse(passQso[2]);
    this.Qso4 = Int32.Parse(passQso[3]);
    this.Qso5 = Int32.Parse(passQso[4]);
    this.Qso6 = Int32.Parse(passQso[5]);
    this.Qso7 = Int32.Parse(passQso[6]);
    this.Qso8 = Int32.Parse(passQso[7]);
    this.Qso9 = Int32.Parse(passQso[8]);
    this.Qso10 = Int32.Parse(passQso[9]);
    this.Qso11 = Int32.Parse(passQso[10]);
    this.Qso12 = Int32.Parse(passQso[11]);
    
    // create array for bubblesort
    int[] d = new int[]{Qso1, 
                        Qso2, 
                        Qso3, 
                        Qso4, 
                        Qso5, 
                        Qso6, 
                        Qso7, 
                        Qso8, 
                        Qso9, 
                        Qso10, 
                        Qso11,
                        Qso12};
                
    // call bubblesort
    BubbleSort( d );
                
    // pass largest value
    hold = d[11];
    
    // set scales in chart
    if ( hold <= 10  )
    {
            // When the Chart Scale is 0 to 10
            Chart1 = 600 - (50 * Qso1); 
        Chart2 = 600 - (50* Qso2);
        Chart3 = 600 - (50 * Qso3);
        Chart4 = 600 - (50 * Qso4);
        Chart5 = 600 - (50 * Qso5);
        Chart6 = 600 - (50 * Qso6);
        Chart7 = 600 - (50 * Qso7);
        Chart8 = 600 - (50 * Qso8);
        Chart9 = 600 - (50 * Qso9);
        Chart10 = 600 - (50 * Qso10);
        Chart11 = 600 - (50 * Qso11);
        Chart12 = 600 - (50 * Qso12);
    
        brush.Color = Color.Black;
        graph.DrawString( "10", arial3, brush, 70, 90 );
        graph.DrawString( "9", arial3, brush, 70, 140 );
        graph.DrawString( "8", arial3, brush, 70, 190 ); 
        graph.DrawString( "7", arial3, brush, 70, 240 ); 
        graph.DrawString( "6", arial3, brush, 70, 290 ); 
        graph.DrawString( "5", arial3, brush, 70, 340 );
        graph.DrawString( "4", arial3, brush, 70, 390 );
        graph.DrawString( "3", arial3, brush, 70, 440 );
        graph.DrawString( "2", arial3, brush, 70, 490 );
        graph.DrawString( "1", arial3, brush, 70, 540 );
        graph.DrawString( "0", arial3, brush, 70, 590 );
    
        DrawGraph(graph);
    }
                
    if( hold > 10 )
    {
        if(hold <= 50)
        {
            // When the Chart Scale is 100 to 500
            Chart1 = 600 - 10 * Qso1; 
            Chart2 = 600 - 10 * Qso2;
            Chart3 = 600 - 10 * Qso3;
            Chart4 = 600 - 10 * Qso4;
            Chart5 = 600 - 10 * Qso5;
            Chart6 = 600 - 10 * Qso6;
            Chart7 = 600 - 10 * Qso7;
            Chart8 = 600 - 10 * Qso8;
            Chart9 = 600 - 10 * Qso9;
            Chart10 = 600 - 10 * Qso10;
            Chart11 = 600 - 10 * Qso11;
            Chart12 = 600 - 10 * Qso12;
    
            brush.Color = Color.Black;
            graph.DrawString( "50", arial3, brush, 50, 90 );
            graph.DrawString( "45", arial3, brush, 50, 140 );
            graph.DrawString( "40", arial3, brush, 50, 190 );
            graph.DrawString( "35", arial3, brush, 50, 240 ); 
            graph.DrawString( "30", arial3, brush, 50, 290 ); 
            graph.DrawString( "25", arial3, brush, 50, 340 );
            graph.DrawString( "20", arial3, brush, 50, 390 );
            graph.DrawString( "15", arial3, brush, 50, 440 );
            graph.DrawString( "10", arial3, brush, 50, 490 );
            graph.DrawString( "5", arial3, brush, 50, 540 );
            graph.DrawString( "0", arial3, brush, 50, 590 );
    
            DrawGraph(graph);
        }
    }
}
private void DrawGraph(Graphics graph)
{
    // Draw BarGraph
    graph = this.CreateGraphics();
    SolidBrush brush = new SolidBrush( Color.Blue );
    Rectangle rect1 = new Rectangle(100, Chart1, 50, (600 - Chart1));
    graph.FillRectangle( brush, rect1);
                
    // Write Qso Value
    FontStyle style3 = FontStyle.Regular;
    Font arial3 = new Font( new FontFamily( "Arial" ), 12, style3 );
    brush.Color = Color.Black;
    graph.DrawString( Qso1.ToString(), arial3, brush, 112, (Chart1 - 20 ));
    
    // Draw BarGraph
    SolidBrush brush2 = new SolidBrush(Color.BlanchedAlmond);
    Rectangle rect2 = new Rectangle( 170, Chart2, 50, (600 - Chart2));
    graph.FillRectangle( brush2, rect2 );
    
    // Write Qso Value
    brush.Color = Color.Black;
    graph.DrawString( Qso2.ToString(), arial3, brush, 182, (Chart2 - 20 ));
    
    // Draw BarGraph
    SolidBrush brush3 = new SolidBrush(Color.ForestGreen);
    Rectangle rect3 = new Rectangle( 240, Chart3, 50, (600 - Chart3));
    graph.FillRectangle( brush3, rect3 );
    
    // Write Qso Value
    brush.Color = Color.Black;
    graph.DrawString( Qso3.ToString(), arial3, brush, 252, (Chart3 - 20 ));
    
    // Draw BarGraph
    SolidBrush brush4 = new SolidBrush(Color.Brown);
    Rectangle rect4 = new Rectangle( 310, Chart4, 50, (600 - Chart4));
    graph.FillRectangle( brush4, rect4 );
    
    // Write Qso Value
    brush.Color = Color.Black;
    graph.DrawString( Qso4.ToString(), arial3, brush, 322, (Chart4 - 20 ));
    
    // Draw BarGraph
    SolidBrush brush5 = new SolidBrush(Color.DarkMagenta);
    Rectangle rect5 = new Rectangle( 380, Chart5, 50, (600 - Chart5));
    graph.FillRectangle( brush5, rect5 );
    
    // Write Qso Value
    brush.Color = Color.Black;
    graph.DrawString( Qso5.ToString(), arial3, brush, 392, (Chart5 - 20 ));
    
    // Draw BarGraph
    SolidBrush brush6 = new SolidBrush(Color.BlanchedAlmond);
    Rectangle rect6 = new Rectangle( 450, Chart6, 50, (600 - Chart6));
    graph.FillRectangle( brush6, rect6 );
    
    // Write Qso Value
    brush.Color = Color.Black;
    graph.DrawString( Qso6.ToString(), arial3, brush, 462, (Chart6 - 20 ));
    
    // Draw BarGraph
    SolidBrush brush7 = new SolidBrush(Color.DarkGreen);
    Rectangle rect7 = new Rectangle ( 520, Chart7, 50, (600 - Chart7));
    graph.FillRectangle( brush7, rect7 );
    
    // Write Qso Value
    brush.Color = Color.Black;
    graph.DrawString( Qso7.ToString(), arial3, brush, 532, (Chart7 - 20 ));
    
    // Draw BarGraph
    SolidBrush brush8 = new SolidBrush(Color.Gold);
    Rectangle rect8 = new Rectangle ( 590, Chart8, 50, (600 - Chart8));
    graph.FillRectangle( brush8, rect8 );
    
    // Write Qso Value
    brush.Color = Color.Black;
    graph.DrawString( Qso8.ToString(), arial3, brush, 602, (Chart8 - 20 ));
    
    // Draw BarGraph
    SolidBrush brush9 = new SolidBrush(Color.BlueViolet);
    Rectangle rect9 = new Rectangle( 660, Chart9, 50, (600 - Chart9));
    graph.FillRectangle( brush9, rect9 );
    
    // Write Qso Value
    brush.Color = Color.Black;
    graph.DrawString( Qso9.ToString(), arial3, brush, 672, (Chart9 - 20 ));
    
    // Draw BarGraph
    SolidBrush brush10 = new SolidBrush(Color.Firebrick);
    Rectangle rect10 = new Rectangle( 730, Chart10, 50, (600 - Chart10 ));
    graph.FillRectangle( brush10, rect10 );
    
    // Write Qso Value
    brush.Color = Color.Black;
    graph.DrawString( Qso10.ToString(), arial3, brush, 742, (Chart10 - 20 ));
    
    // Draw BarGraph
    SolidBrush brush11 = new SolidBrush(Color.BlanchedAlmond);
    Rectangle rect11 = new Rectangle( 800, Chart11, 50, (600 - Chart11));
    graph.FillRectangle( brush11, rect11 );
    
    // Write Qso Value
    brush.Color = Color.Black;
    graph.DrawString( Qso11.ToString(), arial3, brush, 812, (Chart11 - 20 ));
    
    // Draw BarGraph
    SolidBrush brush12 = new SolidBrush(Color.DarkOrange);
    Rectangle rect12 = new Rectangle( 870, Chart12, 50, (600 - Chart12));
    graph.FillRectangle( brush12, rect12 );
    
    // Write Qso Value
    brush.Color = Color.Black;
    graph.DrawString( Qso12.ToString(), arial3, brush, 882, (Chart12 - 20 ));
}

Printing this chart

I like to print this chart using Print Scrn. Follow the instructions for Print Scrn function from your computer manufacturer, and use the imaging tool that is supplied to you by that manufacturer. This image ( .jpg, .png) can be resized and cropped accordingly. You can e-mail these files, or print them, and include them in your report. This is a great addition to your presentation layer.

Summary

This simple auto scaling chart is a useful tool in your project. It adds color and gives your program some eye appeal. Have fun with the Graphics in C#. Build your own chart to suit your own needs, and tastes.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
I studied Fortran IV in HighSchool where we had 2 keypunch machines, and access to an IBM 1100 at the Community College. We ran our programs batch, and compiled our programs on paper tape.

Years later when PC's became affordable, I gave programming another shot. This time I studied RPG with the IBM AS-400 computer. I could access the College Computer with Emulator Software( Mocha Soft MW 5250 ) and my home PC.

C++ came later, then VB-6, C#.Net, and Managed C++. I am currently studying VB.Net

Comments and Discussions

 
QuestionI want different color in one bar Pin
dharmik.c2-Jan-14 23:11
dharmik.c2-Jan-14 23:11 
QuestionChart doesn't come up Pin
Mankraften18-Feb-13 3:02
Mankraften18-Feb-13 3:02 
AnswerRe: Chart doesn't come up Pin
nethsu21-Jul-14 9:34
nethsu21-Jul-14 9:34 
GeneralMy vote of 3 Pin
longqi7-Jun-12 21:52
longqi7-Jun-12 21:52 
GeneralMessage Closed Pin
15-Aug-12 1:05
WebMaster15-Aug-12 1:05 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey26-Feb-12 21:19
professionalManoj Kumar Choubey26-Feb-12 21:19 
GeneralMy vote of 5 Pin
rizall22-Dec-10 16:55
rizall22-Dec-10 16:55 
GeneralMy vote of 5 Pin
p.tajik5-Oct-10 6:47
p.tajik5-Oct-10 6:47 
GeneralMy vote of 2 Pin
LimitedAtonement25-Jan-10 4:25
LimitedAtonement25-Jan-10 4:25 
GeneralMy vote of 1 Pin
DKN555551-Apr-09 11:50
DKN555551-Apr-09 11:50 
Questionany help? Pin
angels77723-Nov-07 17:59
angels77723-Nov-07 17:59 
Generalcanot see the graph Pin
angels77722-Nov-07 19:39
angels77722-Nov-07 19:39 
GeneralNice Pin
Pooya Musavi19-Oct-07 8:12
Pooya Musavi19-Oct-07 8:12 
GeneralMissing file Pin
gensee4-Oct-07 1:33
gensee4-Oct-07 1:33 
GeneralRe: Missing file Pin
huynhdangthai8-Jul-10 18:29
huynhdangthai8-Jul-10 18:29 
GeneralRe: Missing file Pin
lugesot21-Mar-11 20:37
lugesot21-Mar-11 20:37 
First,replace all "...GraphData.ocx" to "GraphData.ocx" in the codes, so no folder required to create.
By the way, if your screen is small, maybe you cannot see the buttons in the chart form,
just make its x position smaller, such as 700.
Generalyour attention please Pin
alattar4-Jul-07 20:20
alattar4-Jul-07 20:20 
GeneralThe demo dont work with me. Pin
Tintin9220-Jun-06 23:24
Tintin9220-Jun-06 23:24 
QuestionPatterns? Arrays? Collections? Math? Pin
Corneliu Tusnea8-Feb-05 15:10
Corneliu Tusnea8-Feb-05 15:10 
GeneralDynamic Pin
Eddie de Bear16-Jan-05 18:59
Eddie de Bear16-Jan-05 18:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.