Click here to Skip to main content
15,868,141 members
Articles / Programming Languages / C#

Rotating a Microsoft 3D Chart

Rate me:
Please Sign up or sign in to vote.
4.78/5 (6 votes)
12 Feb 2013CPOL6 min read 41.8K   2.6K   27   8
Adding scrollbars to the Microsoft Chart Control.

Image 1

Introduction

Sometimes it's the sizzle that sells an idea rather than the idea itself. On a recent consulting project, bidders were asked to supply a simple program that would give the prospective client some idea of what the project results would look like. All they asked for was a simple program that would display the supplied data series in a way that was useful to the management. For me, using a 3D chart instead of a simple 2D chart was the sizzle for the client. Making the chart rotatable in 3D just added some aroma to the sizzle.

Figure 1 shows a demo use of the chart class used in this article. The class is built on Microsoft's Chart control, which is integrated into Visual Studio. While the language I used is C#, the basic chart class is available for all of the Visual Studio languages. The code is pretty straightforward, so I don't think you would have any difficulty converting it to some other language.

Background

While 3D charts are built into the Chart control, adding the scrollbars makes the chart a little more interesting. If the user drags the vertical scrollbar control, the graph's inclination angle is changed. The scrolling is surprisingly smooth. The horizontal scrollbar rotates the graph through 180 degrees. While also smooth, there are some minor hiccups at 45 and 90 degrees as the graph's perspective changes. There are roughly a bazillion properties and methods for the basic Microsoft chart control, and my class only uses a few of them. You can extend the class by adding more properties and methods as you see fit.

Using the code

The following code fragment is from Calculate button's click even in the demo program shown in Figure 1. (I have omitted the numeric checks here, but they are in the demo source code.)

C#
try
{
  myChart = new cls3DChart(width, height, x, y);

  myChart.SeriesSize = 10;              // The number of data points per plot
  myChart.NumberOfSeries = 2;           // The number of data plots
  myChart.CurrentSeriesName = "Probability";

  GenerateTestData(myChart.SeriesSize); // Fake some data

  this.Controls.Add(myChart);           // Add control to this form
  myChart.InitializeChart();            // Finish up the control
  myChart.SetSeriesData(series);        // Add data to chart

  GenerateTestData(myChart.SeriesSize); // Do it again...
  myChart.SeriesColor = Color.IndianRed;
  myChart.CurrentSeriesName = "Data";
  myChart.SetSeriesData(series);
}
catch (Exception ex)
{
  MessageBox.Show("Something went terribly wrong: " + ex.Message);
}
Listing 1. Part of the Calculate button click event.

The declaration of myChart appears earlier in the class using class scope. The definition of myChart is deferred until the click event is sensed because we need the size and coordinates passed into the "cls3DChart"'s constructor. In that class, the Microsoft chart control is placed on a panel control. At runtime, the "width" and "height" arguments determine the size of the panel and the chart control. The "x" and "y" coordinates are used to pin the upper-left corner of the control on whatever form you may be using to host the chart. The code then sets a few of the chart's property members and then generates some random numbers by a call to GenerateTestData(). (The function simply generates a series of random numbers and stores them in an array named series. The source code for this method is also in the demo file.)

The code then adds the newly-defined control (myChart) to the form via the Add(myChart) method call. Most of the work is done with the call to InitializeChart(), the code for which appears in Listing 2.

Note that the file holding the cls3DChart code was added to the project using the "Add User Control" option from the "Project" menu. This gives you a "form" surface on which to draw the new control.

C#
public void InitializeChart()
{
    chartMain.ChartAreas[0].Area3DStyle.Enable3D = true;          // Turn on 3D
    chartMain.ChartAreas[0].Area3DStyle.PointDepth = chartDepth;  // How deep is the chart

    Axis axisY = chartMain.ChartAreas[0].AxisY;                   // Set up for the axis data
    Axis axisX = chartMain.ChartAreas[0].AxisX;
    axisY.Interval = yInterval;
    axisX.Interval = xInterval;
 
                                                                  // Do all the scrollbar stuff
    myVScrollBar.Scroll += new ScrollEventHandler(this.myVScrollBar_Scroll);
    myHScrollBar.Scroll += new ScrollEventHandler(this.myHScrollBar_Scroll);

    myVScrollBar.Height = height;
    myVScrollBar.Width = scrollBarWidth;

    myHScrollBar.Height = scrollBarWidth;
    myHScrollBar.Width = width;

    myHScrollBar.Location = new System.Drawing.Point(0, height);  // Where to pin scrollbars
    myVScrollBar.Location = new System.Drawing.Point(width, 0);


    myVScrollBar.SetBounds(width, 0, scrollBarWidth, height);     // How big are they...
    myHScrollBar.SetBounds(0, height, width, scrollBarWidth);
    
    myVScrollBar.Maximum = 90;   // Set limits and starting values, these could be properties
    myVScrollBar.Minimum = -90;
    myVScrollBar.SmallChange = smallDeltaY;   // How far when dragging
    myVScrollBar.LargeChange = largeDeltaY;   // How far when clicking
    myVScrollBar.Value = -15;                 // Starting angle

    myHScrollBar.Maximum = 180;               // Same stuff for horizontal scrollbar
    myHScrollBar.Minimum = 0;
    myHScrollBar.SmallChange = smallDeltaX;
    myHScrollBar.LargeChange = largeDeltaX;
    myHScrollBar.Value = 15;

    panel1.Controls.Add(myVScrollBar);    // Place the bars on the panel, at chart edges
    panel1.Controls.Add(myHScrollBar);
}
Listing 2. Initializing the control.

The code is fairly straightforward, setting the vertical and horizontal scrollbar objects' properties. Note that the location of the scrollbars is tied to the panel control. In other words, if the chart control and panel control are 400 pixels wide and 300 pixels high, the statements:

C#
myHScrollBar.Location = new System.Drawing.Point(0, height);  // Where to pin scrollbars
myVScrollBar.Location = new System.Drawing.Point(width, 0);

place the upper-left corner of the horizontal scrollbar at coordinates 0,300 and the vertical scrollbar at 400, 0. These coordinates place the scrollbars just on the edge of the panel control. The calls to:

C#
myVScrollBar.SetBounds(width, 0, scrollBarWidth, height);     // How big are they...
myHScrollBar.SetBounds(0, height, width, scrollBarWidth);

simply define the size of the scrollbars. The rest of the code sets various properties to values that I used for the client demo. You can add properties and property methods to the class for those properties you think you may need to change at runtime for your purposes. The statements:

C#
panel1.Controls.Add(myVScrollBar);    // Place the bars on the panel, at chart edges
panel1.Controls.Add(myHScrollBar);

add the two scrollbars to the panel control.

The code in Listing 3 shows how the new event handlers are written.

C#
private void AddMyScrollEventHandlers()
{
    // Event handlers
    myVScrollBar.Scroll += new ScrollEventHandler(this.myVScrollBar_Scroll);
    myHScrollBar.Scroll += new ScrollEventHandler(this.myHScrollBar_Scroll);
}

// Create the Scroll event handler.
private void myVScrollBar_Scroll(Object sender,ScrollEventArgs e)
{
    if (myVScrollBar.Value > inclineValue)
    {
      chartMain.ChartAreas[0].Area3DStyle.Inclination = (int)myVScrollBar.Value;
      inclineValue += (int)myVScrollBar.SmallChange;
    }
    else
    {
      chartMain.ChartAreas[0].Area3DStyle.Inclination = (int)myVScrollBar.Value;
      inclineValue -= (int)myVScrollBar.SmallChange;
    }
}
Listing 3. Event handler code.

Only the vertical scroll event is shown since the horizontal control works much the same way. When a scroll event is sensed, the value of the vertical scrollbar is compared to the inclineValue property, which I have defined to be -15 by default. (If the initial value were set to 0, it would be a "straight-on" view of the graph and a little less interesting.) The range of values for the scrollbar is plus and minus 90 degrees. With the initial value of the scrollbar at -15, the graph is initially tilted downwards by 15 degrees. If the users clicks above the scrollbar or drags it upwards, the vertical scroll event is fired and the event handler is called. If you trace the logic, you can see that increasing the value moves the scrollbar upward and moves the chart accordingly. If you look at the class code, you'll see virtually the same code for the horizontal scrollbar.

The data is placed on the chart by calling the SetSeriesData() method in the chart class. The code appears in Listing 4.

C#
public void SetSeriesData(double[] sentData)
{
    int i;
    Series series = new Series();

    series.Name = currentSeriesName;
    series.Color = seriesColor;
    series.ChartType = SeriesChartType.Column;    // Could make this a changable property

    for (i = 0; i < seriesSize; i++)
    {
      series.Points.Add(sentData[i]);
    }
    chartMain.Series.Add(series);
    currentSeries++;
}
Listing 4. Adding data to the chart.

The method begins by defining a new data Series named "series". Note that there are numerous properties available as part of the Series class, but we're only using the Name, Color, and ChartType properties. While I have made the name of the data series and its corresponding color properties of the chart class, I have hard-coded the type to be a Column chart. You could make this a property if you need to make it changeable at runtime. The number of data points to be added to the series is set by seriesSize, which you can see near the top of Listing 1 has been set to 10. The code then just iterates through the data and adds it to the chart via the chartMain.Series.Add() method call. That's pretty much all there is to it.

During the process of writing the code for the control, it amazed me how scattered the information on the Microsoft Chart control is. It was also difficult to find demo code for the 3D version of the control that used scrollbars. (I couldn't find one.) At least the demo code here brings it all together in one place. If you single-step through the code, you'll be able to figure out how all the pieces-parts fit together. If you find bugs or make enhancements, I hope you'll share those with the rest of us.

History

  • Initial code written Feb. 3, 2013.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Retired Jack Purdum Associates
United States United States
Dr. Purdum is a retired professor from Purdue University's College of Technology and author of 17 programming books. He continues to do consulting and writing, and is also interested in programming embedded systems.

Comments and Discussions

 
QuestionThank you that was amazing project Pin
Member 1129342022-Dec-14 18:28
Member 1129342022-Dec-14 18:28 
QuestionResubmitted files Pin
Member-243269611-Feb-13 1:41
Member-243269611-Feb-13 1:41 
SuggestionZip Files Pin
DaveAuld7-Feb-13 3:41
professionalDaveAuld7-Feb-13 3:41 
QuestionUse 7Zip to extract the files Pin
Member-24326966-Feb-13 17:28
Member-24326966-Feb-13 17:28 
QuestionI have a doubt Pin
ErnestoGlez6-Feb-13 7:50
ErnestoGlez6-Feb-13 7:50 
AnswerRe: I have a doubt Pin
Member-24326966-Feb-13 17:25
Member-24326966-Feb-13 17:25 
QuestionI dont extract de file download Pin
ErnestoGlez6-Feb-13 7:46
ErnestoGlez6-Feb-13 7:46 
QuestionUnable to unzip Pin
Nchantim6-Feb-13 4:02
Nchantim6-Feb-13 4:02 

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.