Graphs and Charts in ASP.NET
I've come across a lot of people/companies/sites etc offering graphing and charting products for ASP.NET - all of them have been over $100, some were even approaching $1000 which is obviously a total piss take if you just want a really simple little graph or chart for something! Also, these expensive products may not even give you exactly what you want!What I'm going to talk about here is using the .NET Framework (and in particular the System.Drawing and System.Drawing.Imaging namespaces) to generate dynamic graphs or charts - I'm not going to give you a detailed step-by-step guide because frankly I cant be bothered and what you want will vary, so I'm going to talk about the general procedure - I'm assuming you are familiar with all the mundane stuff like creating SolidBrush objects and all that. Anyway here is an example of the sort of graphs I've been making this way:
To get started, create a new aspx file, say graph.aspx. Stick the following in it:
< %@ Page Language="c#" Debug="true" trace="true"%>
< %@ Import Namespace = "System.Drawing" %>
< %@ Import Namespace = "System.Drawing.Imaging" %>
<script Runat = "Server">
void Page_Load() { }
</script>
We are going to use this aspx file as the 'image' of the graph so we only need to use the Page_Load() function.
Ok so no we are going to want to create the objects that lets us 'draw' things - these are the Bitmap and Graphic objects:
Bitmap bmpObj = new Bitmap(400,400);
Graphics grpObj = Graphics.FromImage(bmpObj);
SolidBrush brshObj = new SolidBursh(Color.White);
Rectangle rectObj = new Rectangle(0,0,bmpObj.Width,bmpObj.Height);
grpObj.FillRectangle(brshObj,rectObj);
Here I am creating a 'blank' (i.e. white) bitmap object 400 pixels high and 400 wide, then creating a Graphics object from that Bitmap. This Graphics object grpObj will allow us to do all of the drawing functions on the Bitmap object.
Ok so now we have the Bitmap we can do all sorts of wonderful things to it, such as draw text, draw lines, draw (filled) rectangles - can you see where I'm going with this?! As you have no doubt realised, the graph is just made up by going through a series of grpObj.FillRectangle() calls for each bar, then a small smattering of lines and text to make up the rest of the stuff we expect on a graph such as the axes etc. Easy! So for example if you are taking data out of a database you can just do a foreach (DataRow Row in MyResultTable.Rows) {…} etc, drawing out a bar for each row you get - just make sure you remember to move the point on the x axes you draw at along each time though! If you are wondering how I did the pretty curve in the above example image then thats pretty easy - I just kept an array of PointF objects for each of the results and then just pass it to the Graphic object's DrawCurve() function - it really is that easy.
One thing that you should keep in mind though is that the coordinate system starts at the top left of the image, rather than the bottom left as you are probably used to if you have ever drawn a graph on paper, with the origin at the bottom left of the page. You can just use some simple code to get around this problem by calculating the correct coordinates for this top left based system, but I just use a really simple method because I'm feeling pretty lazy:
bmpObj.RotateFlip(RotateFlipType.RotateNoneFlipY);
This will just flip the image along the Y axis, so we can just merrily draw in all of the bars and axes etc using the top left origin as if the origin was at the bottom left without having to bother with trying to alter the coordinate points or anything, and then just flip it over! So now we have a graph with the origin looking like it starts at the bottom left. Obviously if you're going to use this flipping method you're going to flip your writing too, so just put your writing on after you've flipped it.
Finally you may be wondering how you actually send the graph as an image and not as a web page. This is actually really simple once you know how. All you need to do is read the Bitmap object into a stream, set the Response object's output type, then write the stream to the Response.OutputStream. Here is an example for sending the image back as a PNG image (which is a good comprimise for low colour count graphs such as the one above), with the following code as the last thing in the Page_Load() function:
System.IO.MemoryStream memStream = new System.IO.MemoryStream();
bmpObj.Save(memStream,ImageFormat.Png);
Response.Clear();
Response.ContentType = "image/png";
memStream.WriteTo(Response.OutputStream);
Response.End();
// Aways good practice to Dispose of objects when we're done!
bmpObj.Dispose();
grpObj.Dispose();
We can then simply just have an HTML image tag as usual, expect pointing to our aspx file, e.g. <img src='graph.aspx' /> (note that you can also put stuff in the querystring here too so you can easily pass some variables to your graph). Putting an aspx page as the source for an image file looks kinda odd, but remember that we're sending back data in PNG format as the Response here so the browser just displays the data like it would for any other image. As well as bar charts, the Graphics object features a DrawPie() method which allows you to draw different Pie Chart sections, so you can do Pie Charts too!
If you are going to be getting a lot of visitors you may wish to save the completed image off to a file and then serve the file for the next 30 mins or something instead of regenerating it each time. You'll need to do some more trickery to get that to work, but I'll leave that up to you.
Back
23.02.2006.
Wow! You Rock Man..
Rakesh Chandran
02.03.2007
,llpp
ggh
11.05.2007
This in deed looks like a good article for my requirement.. But this did not give a complete info for newbies like me..
Can you be complete with your solution