Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Drawing a Dynamic Chart in C#

0.00/5 (No votes)
8 Feb 2005 3  
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

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

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

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