.NET charting with ZedGraph

When trying to create graphs from within a .NET program there are many routes, most of which are commercial products.
Recently I found myself needing a free .NET graph package which also had to meet the following requirements:

  • Free
  • Works in ASP.NET
  • Able to plot multiple graph types, including bar, line and pie
  • Useful help system to aid with integration

Whilst searching I came across ZedGraph, an free and open-source .NET graphing package.
It is both an Windows Forms UserControl and ASP web-accessible control which can be used to create the required bar, line and pie graphs and many other graph types, including some I hadn’t even heard of.

I used it by creating a ASPX page which could be passed multiple parameters and would render the result as an raw image which would be displayed on the calling page.

Firstly you would create the calling page which would contain the following image link on it:

<img src="graph.aspx" />

As with normal HTML you could add a height, width, alt, etc. attribute to the img tag but this is the bare minimum required to function.

Secondly the GRAPH.ASPX itself needs to be created, this is created as a code-behind file, the .ASPX file will contain the following code:

<%@ Page Language="c#" Inherits="ZG1.graph" CodeFile="mygraph.aspx.cs" %>

<%@ Register TagPrefix="zgw" Namespace="ZedGraph.Web" Assembly="ZedGraph.Web" %>
<ZGW:ZEDGRAPHWEB id="ZedGraphWeb1" runat="server" Width="500" Height="375" RenderMode="RawImage" />

Obviously if this was a VB.NET page then the first line would be different, notice that the size of the returned image is fixed to 500 wide an 375 high.

Lastly the in the .ASPX.VB file the actual rendering of the graph takes place:

using System;
using System.Drawing;
using ZedGraph;
using ZedGraph.Web;

namespace ZG1
{ /// <summary> /// Summary description for graph. /// </summary> public partial class graph : System.Web.UI.Page {

/// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.ZedGraphWeb1.RenderGraph += new ZedGraph.Web.ZedGraphWebControlEventHandler(this.OnRenderGraph); }
/// <summary>
/// This method is where you generate your graph.
/// </summary>
/// <param name="masterPane">You are provided with a MasterPane instance that /// contains one GraphPane by default (accessible via masterPane[0]).</param> /// <param name="g">A graphics instance so you can easily make the call to AxisChange()</param> private void OnRenderGraph(ZedGraphWeb zgw, System.Drawing.Graphics g, ZedGraph.MasterPane masterPane) { // Get the GraphPane so we can work with it GraphPane myPane = masterPane[0]; myPane.Title.Text = "Sales By Region"; myPane.XAxis.Title.Text = "Region"; myPane.YAxis.Title.Text = "Gross Sales, $Thousands"; PointPairList list = new PointPairList(); PointPairList list2 = new PointPairList(); PointPairList list3 = new PointPairList(); Random rand = new Random(); for ( double x=0; x<5; x+=1.0 ) { double y = rand.NextDouble() * 1000; double y2 = rand.NextDouble() * 1000; double y3 = rand.NextDouble() * 1000; list.Add( x, y ); list2.Add( x, y2 ); list3.Add( x, y3 ); } BarItem myCurve = myPane.AddBar( "Blue Team", list, Color.Blue ); BarItem myCurve2 = myPane.AddBar( "Red Team", list2, Color.Red ); BarItem myCurve3 = myPane.AddBar( "Green Team", list3, Color.Green ); myPane.XAxis.MajorTic.IsBetweenLabels = true; string[] labels = { "Africa", "Americas", "Asia", "Europe", "Australia" }; myPane.XAxis.Scale.TextLabels = labels; myPane.XAxis.Type = AxisType.Text; myPane.Fill = new Fill(Color.White, Color.FromArgb(200, 200, 255), 45.0f); myPane.Chart.Fill = new Fill(Color.White, Color.LightGoldenrodYellow, 45.0f); masterPane.AxisChange(g); } }

There are a couple of things to note in the code above, firstly the adding of the event handler within the InitialiseComponent subroutine,

this is required so the rendering routine is called when required. Secondly the rendering is not done within the Page_Load routine as you would might expect, instead it is within the routine passed to the event handler.

If you need any further help then you can always try the ZedGraph wiki (external link).

Leave a Reply

Your email address will not be published. Required fields are marked *