|
Introduction
The following example demonstrates how to generate bar-charts for any business information available on a web page. This uses the classes which are provided in the .NET System.Drawing namespace to generate the chart.
Bar chart created in the below example illustrates the profit of a company for each month from January through December.
Generating the Bar chart
Data which is to be displayed on X axis and Y axis is stored in ArrayLists, and then the data is read from these ArrayLists for creating the required bar chart.
First, the ArrayLists are populated as follows:
Dim aMonths As ArrayList = New ArrayList()
aProfits As ArrayList = New ArrayList()
aMonths.Add("January")
aMonths.Add("February")
aMonths.Add("March")
aMonths.Add("April")
aMonths.Add("May")
aMonths.Add("June")
aMonths.Add("July")
aMonths.Add("August")
aMonths.Add("September")
aMonths.Add("October")
aMonths.Add("November")
aMonths.Add("December")
aProfits.Add(240500)
aProfits.Add(220950)
aProfits.Add(283500)
aProfits.Add(340000)
aProfits.Add(325750)
aProfits.Add(123456)
aProfits.Add(235621)
aProfits.Add(345235)
aProfits.Add(290451)
aProfits.Add(152345)
aProfits.Add(653456)
aProfits.Add(785620)
Once the data is populated, the chart can be generated by calling the method DrawBarGraph:
DrawBarGraph("Profits!", aMonths, aProfits)
DrawBarGraph is defined as follows:
Sub DrawBarGraph(ByVal strTitle As String, _
ByVal aX As ArrayList, ByVal aY As ArrayList)
Const iColWidth As Integer = 60, iColSpace As Integer = 25, _
iMaxHeight As Integer = 400, iHeightSpace As Integer = 25, _
iXLegendSpace As Integer = 30, iTitleSpace As Integer = 50
Dim iMaxWidth As Integer = (iColWidth + iColSpace) * aX.Count + iColSpace, _
iMaxColHeight As Integer = 0, _
iTotalHeight As Integer = iMaxHeight + iXLegendSpace + iTitleSpace
Dim objBitmap As Bitmap = New Bitmap(iMaxWidth, iTotalHeight)
Dim objGraphics As Graphics = Graphics.FromImage(objBitmap)
objGraphics.FillRectangle(New SolidBrush(Color.White), _
0, 0, iMaxWidth, iTotalHeight)
objGraphics.FillRectangle(New SolidBrush(Color.Ivory), _
0, 0, iMaxWidth, iMaxHeight)
Dim iValue As Integer
For Each iValue In aY
If iValue > iMaxColHeight Then iMaxColHeight = iValue
Next
Dim iBarX As Integer = iColSpace, iCurrentHeight As Integer
Dim objBrush As SolidBrush = New SolidBrush(Color.FromArgb(70, 20, 20))
Dim fontLegend As Font = New Font("Arial", 11), _
fontValues As Font = New Font("Arial", 8), _
fontTitle As Font = New Font("Arial", 24)
Dim iLoop As Integer
For iLoop = 0 To aX.Count - 1
iCurrentHeight = ((Convert.ToDouble(aY(iLoop)) / _
Convert.ToDouble(iMaxColHeight)) * _
Convert.ToDouble(iMaxHeight - iHeightSpace))
objGraphics.FillRectangle(objBrush, iBarX, _
iMaxHeight - iCurrentHeight, iColWidth, iCurrentHeight)
objGraphics.DrawString(aX(iLoop), fontLegend, _
objBrush, iBarX, iMaxHeight)
objGraphics.DrawString(Format(aY(iLoop), "#,###"), _
fontValues, objBrush, iBarX, iMaxHeight - iCurrentHeight - 15)
iBarX += (iColSpace + iColWidth)
Next
objGraphics.DrawString(strTitle, fontTitle, objBrush, _
(iMaxWidth / 2) - strTitle.Length * 6, iMaxHeight + iXLegendSpace)
objBitmap.Save(Response.OutputStream, ImageFormat.Gif)
objGraphics.Dispose()
objBitmap.Dispose()
End Sub
This code will generate the bar chart and display it on the screen. Also, if required, the bar chart can be saved as an image, just uncomment the line below in the above code:
objBitmap.Save("C:\inetpub\wwwroot\graph.gif", ImageFormat.GIF)
| You must Sign In to use this message board. |
|
| | Msgs 1 to 17 of 17 (Total in Forum: 17) (Refresh) | FirstPrevNext |
|
 |
|
|
 |
|
|
This is probably more me misunderstanding the full scope of the code than anything, but I copied the code in the example and I get the following error list items on this code line:
objBitmap.Save(Response.OutputStream, ImageFormat.Gif)
Name "Response" is not declared Name "ImageFormat" is not declared
If I comment out that line of code then nothing results from running the code (which I tied to a button which runs the array list then the sub DrawBarGraph("Profits!", aMonths, aProfits)).
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
To make some minor 3d effects you can draw a second rectangle slightly below the original bar chart rectangle, this will give it a look of a 3d bar chart..
I tried that out for a 3d pie chart and it was working good, gave it a 3d look.
I was born dumb!!  Programming made me laugh  !!! --sid--
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
hello,
thought ill share it with newbies who have problems compiling this in visual studio 2005,
just change the firstline of your Graphics_barChart.aspx file to the following
<%@ Page Language="vb" AutoEventWireup="false" CodeFile="Graphics_BarChart.aspx.vb" Inherits="Graphics_Example1"%>
also rename your your Graphics_BarChart.vb file to Graphics_BarChart.aspx.vb this is the code behind file.
Thanks
MM
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
I have been able to use your code to implement a chart like I want but I would like to put a close button on the page. Anything that I put on the page seems to be overwritten by the output stream. I tried just saving the image and accessing it in an image control but it does not show up. Anyone know how to do this?
John T.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I think it looks a lot nicer if I center the labels on the bars, so here is the code I used for that in case anyone wants to do the same.
//draw the bottom label SizeF stringSize = objGraphics.MeasureString(Convert.ToString(aX[i]), fontValues); double startX = (double)iBarX + (double)iColWidth / 2 - (double)stringSize.Width / 2; int iStartX = Convert.ToInt32(Math.Round(startX)); objGraphics.DrawString(Convert.ToString(aX[i]), fontLegend, objBrush, iStartX, iMaxHeight);
//draw the top label centered stringSize = objGraphics.MeasureString(Convert.ToString(aY[i]), fontValues); startX = (double)iBarX + (double)iColWidth / 2 - (double)stringSize.Width / 2; iStartX = Convert.ToInt32(Math.Round(startX)); objGraphics.DrawString(Convert.ToString(aY[i]), fontValues, objBrush, iStartX, iMaxHeight - iCurrentHeight - 15);
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
I am developing a project in C# and need to create charts. Would you have a sample of theis code in C#. Also would the bar chart be displayed as part of my project or as a webpage. Also, where you set up the months and values, would it work if i extracted data from a sql server 2000 and did a count of the occurence of a value, and added it to the array list???
Thanks for your help
Laura
|
| Sign In·View Thread·PermaLink | 1.50/5 (2 votes) |
|
|
|
 |
|
|
Hi,
I've converted this to c# if you're still interested:
public void drawBarGraph(string strTitle, ArrayList aX, ArrayList aY) { int iColWidth = 60; int iColSpace = 25; int iMaxHeight = 400; int iHeightSpace = 25; int iXLegendSpace = 30; int iTitleSpace = 40;
int iMaxWidth = (iColWidth + iColSpace) * aX.Count + iColSpace;
int iMaxColHeight = 0; int iTotalHeight = iMaxHeight + iXLegendSpace + iTitleSpace;
Bitmap objBitmap = new Bitmap(iMaxWidth, iTotalHeight); Graphics objGraphics = Graphics.FromImage(objBitmap);
objGraphics.FillRectangle(new SolidBrush(Color.White),0, 0, iMaxWidth, iTotalHeight); objGraphics.FillRectangle(new SolidBrush(Color.Ivory),0, 0, iMaxWidth, iMaxHeight);
foreach(int iValue in aY) { if (iValue > iMaxColHeight) { iMaxColHeight = iValue; } }
int iBarX = iColSpace; int iCurrentHeight;
SolidBrush objBrush = new SolidBrush(Color.FromArgb(70, 20, 20)); Font fontLegend = new Font("Arial", 8); Font fontValues = new Font("Arial", 8); Font fontTitle = new Font("Arial", 8);
//loop through and draw each bar for(int i=0; i<= aX.Count - 1; i++) { iCurrentHeight = (int)((Convert.ToDouble(aY[i]) / Convert.ToDouble(iMaxColHeight)) * Convert.ToDouble(iMaxHeight - iHeightSpace)); objGraphics.FillRectangle(objBrush, iBarX, iMaxHeight - iCurrentHeight, iColWidth, iCurrentHeight); objGraphics.DrawString(aX[i].ToString(), fontLegend, objBrush, iBarX, iMaxHeight); objGraphics.DrawString(string.Format(aY[i].ToString(), "#,###"), fontValues, objBrush, iBarX, iMaxHeight - iCurrentHeight - 15); iBarX += (iColSpace + iColWidth); } objGraphics.DrawString(strTitle, fontTitle, objBrush, (iMaxWidth / 2) - strTitle.Length * 6, iMaxHeight + iXLegendSpace); //objBitmap.Save("C:\inetpub\wwwroot\graph.gif", ImageFormat.GIF);
objBitmap.Save(Response.OutputStream, ImageFormat.Gif); objGraphics.Dispose(); objBitmap.Dispose();
}
Rgds, Malin
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
Ooops! I've made a mistake:
objGraphics.DrawString(string.Format(aY[i].ToString(), "#,###"), fontValues, objBrush, iBarX, iMaxHeight - iCurrentHeight - 15);
should be:
objGraphics.DrawString(string.Format("{0:#,###}", aY[i]), fontValues, objBrush, iBarX, iMaxHeight - iCurrentHeight - 15);
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
The code does work in Firefox, you just have implemented it correctly. The reason you're seeing the content is because you sent it via the web page when you'd already sent HTML. You can't send a content type image after you've already started sending a web page (with HTML content). What you have to do is comment out the line where the bitmap is being saved to the Respone.OutputStream and uncomment the line where it's saved to a .gif file (I prefer JPG in this case, especially if you use colors that GIF doesn't support). You're web page will need to have permissions to write out to wherever you save it (or delete/overwrite if you're writing it out over and over).
If you're just sending a picture without ANY HTML or text then you can set the content type to image/gif and use the outputstream method. This graph could stand for some formatting brushing up but it does exactly what promised. Good job sharing it!
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
Or you can use an iframe to embed the chart page inside another HTML page:
<html> <head runat="server"> <title>Untitled Page</title> </head> <body> <h3>Chart</h3> <form id="form1" runat="server"> <iframe src="Chart.aspx" height="600" width="100%" frameborder="0" scrolling="no"></iframe> </form> </body> </html>
(In this example, Chart.aspx should contain no HTML code, just the chart-generating codebehind)
It's not the most elegant solution but it works.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
JAS -
There is a problem with your code. I like your sample and it's a great beginner way to build a chart. However, your have some code that is cycling through the arraylist of values to find the max value. Once you find the max value you use that to calculate the distance of the bars for all the values in that array. The problem with that is that you're using it to divide each value by the max value - which in turn will make the value ZERO for every single value except the max value. This also makes ONLY the max bar show up on your chart - the rest are at ZERO.
Resolution?
|
| Sign In·View Thread·PermaLink | 2.80/5 (5 votes) |
|
|
|
 |
|
|
I just want to say thanks for showing me how simple it is to draw a graph. I really did not know that!
- almost all programming can be viewed as an exercise in caching -
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|