I always wanted to play around with the graphics API included in the .NET framework. So, I decided to create simple application that creates bar graph using the data supplied. In the past, I have used the WebChart control to fulfill my graphics needs. You can check out the article here.
The first task is to create a class that will hold the data from which the graph is plotted. The class is called ExamData class.
public class ExamData
{
private double _score;
private string _name;
public double Score
{
get { return _score; }
set { _score = value; }
}
public string Name
{
get { return _name; }
set { _name = value; }
}
}
The ExamData is a simple class which holds the name and the score of the exam. Now, to populate the List<ExamData> with dummy values:
private List<ExamData> GetData()
{
List<ExamData> data = new List<ExamData>()
{ new ExamData() { Name = "Exam 1", Score = 20 },
new ExamData() { Name = "Exam 2", Score = 98 },
new ExamData() { Name = "Exam 3", Score = 56 },
new ExamData() { Name = "Exam 4", Score = 100},
new ExamData() { Name = "Exam 5", Score = 45},
new ExamData() { Name = "Exam 6", Score = 79},
new ExamData() { Name ="Exam 7", Score = 2}
};
return data;
}
Here is the complete implementation:
public const int SCALE = 100;
public const int CANVAS_HEIGHT = 250;
public const int GRAPH_MARGIN = 80;
public const int BAR_GRAPH_WIDTH = 50;
private int GetGraphCanvasWidth(int noOfElements)
{
return noOfElements* SCALE;
}
private int GetGraphRectangleYAxis(int bitMapHeight, int userData)
{
return (bitMapHeight - 40 - (int)userData);
}
protected void Page_Load(object sender, EventArgs e)
{
PublishGraph();
}
private void PublishGraph()
{
var data = GetData();
Bitmap bitmap = new Bitmap(GetGraphCanvasWidth(data.Count), CANVAS_HEIGHT);
Graphics g = Graphics.FromImage(bitmap);
g.FillRectangle(Brushes.White, 0, 0, GetGraphCanvasWidth(data.Count), CANVAS_HEIGHT);
int margin = 0;
foreach (var item in data)
{
Rectangle r = new Rectangle(new Point() { X = margin, Y = GetGraphRectangleYAxis(bitmap.Height, (int)item.Score) }, new Size(BAR_GRAPH_WIDTH, (int)item.Score));
// This is to create the base line!
Rectangle hr = new Rectangle(new Point() { X = 0, Y = 210 }, new Size(GetGraphCanvasWidth(data.Count), 1));
g.FillRectangle(Brushes.Green, r);
g.FillRectangle(Brushes.Blue, hr);
g.DrawString(item.Score.ToString(), new Font("Verdena", 10), Brushes.Blue, new PointF(r.X, r.Y - 20));
g.DrawString(item.Name, new Font("Verdena", 8), Brushes.Blue, new PointF(r.X, 220));
margin += GRAPH_MARGIN;
}
Response.AddHeader("Content-Type", "image/gif");
bitmap.Save(Response.OutputStream, ImageFormat.Gif);
}
The code is placed in the ImagePage.aspx page. And an image tag is used from the main page to request the ImagePage.aspx as shown below:
<img src="ImagePage.aspx" visible="false" runat="server" id="myimg" />
