Anyone of us could
have met the need to be able to create a chart within a web page or a pdf. This
article will explain how to build a chart using MSChart and save the output to a
stream of bytes, this stream will be redirected to a generic handler, so we'll
not use a webform. The same procedure can be used to display the chart in a pdf
file, for example using iTextSharp.
In this project we'll use Northwind database and Entity Data Model and to
retrieve data from table orders, we want to display the orders by shipping
country.
So we create a new ASP.NET empty project called "WebChartStream", add our
database into App_Data and an Entity Model with Orders table mapped in it.
Now is the time to write the class which will build the chart, so we add a new
class called " ChartStream".
We need some imports, the System.Web.UI.DataVisualization.Charting is the
MsChart reference while System.IO will be used to build the MemoryStream:
Imports
System.IO
Imports
System.Web
Imports
System.Web.UI.DataVisualization.Charting
The private fields of the
class
Private c3d As ChartArea3DStyle
Private db As NORTHWNDEntities
Private serie As Series
Private mchart As Chart
Variable c3d will be used to transform our chart in 3D visualization mode.
The main function of the class is
Public Function ToBytesStream() As Byte()
the output of this function is a steam of bytes, will use this stream to print
our chart within the generic handler.
The LINQ to Entity query will select the Orders data grouped and ordered by
ShipCountry field:
db = New NORTHWNDEntities
Dim query
= From c In db.Orders
_
Group c By c.ShipCountry Into g
= Group _
Select New With {.Country
= ShipCountry, .Orders = g}
Now we can create an instance of chart class and set title, size and the quality
of the image, then we add a new chart area.
mchart = New Chart
With mchart
'
Set size of chart
.Width = 600
.Height = 400
'
Set image quality
.RenderType = RenderType.ImageTag
.AntiAliasing = AntiAliasingStyles.All
.TextAntiAliasingQuality = TextAntiAliasingQuality.High
'
Add title of the cart
.Titles.Add("Orders
by Countries")
.Titles(0).Font = New System.Drawing.Font("Arial",
16.0F)
'
Add area
.ChartAreas.Add("orders")
The 3D view is made creating a ChartArea3DStyle object and setting the desired
light style in it:
'
Set 3D style
Dim c3d As New ChartArea3DStyle(.ChartAreas(0))
c3d.Enable3D = True
c3d.LightStyle = LightStyle.Realistic
Then we need some settings like Axis X and Y title, font size and type, etc., as
you can see in the attached source files so we can omit this obvious part in
this article.
The next interesting step is to add values to X and Y series, this is made
through looping LINQ query and adding X and Y points to serie:
serie = New Series
'
Setting series style
serie.IsValueShownAsLabel = True
serie.ChartType = SeriesChartType.Column
serie.Color = Drawing.Color.MediumPurple
'
Set X and Y values
For Each item In query
serie.Points.AddXY(Convert.ToString(item.Country),Convert.ToDouble(item.Orders.Count))
serie.IsValueShownAsLabel = True
Next
'
Add series to chart
mchart.Series.Add(serie)
Finally we can store the chart into a png image and save it into a MemoryStream,
then return the stream buffer to the function:
' Save chart image into a memory
stream of bytes and return it as byte's array
Using stream As New MemoryStream
mchart.SaveImage(stream, ChartImageFormat.Png)
Return stream.GetBuffer
End Using
Now that our class is ready to work we can add a new page in which the chart
will be printed, will do this adding a new Generic Handler named
GenericHandler.ashx.
The code within the generic handler is very easy, in the ProcessRequest context
parameter we'll pass our stream of bytes and then we'll print it to the output
through BinaryWrite method:
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim chart As New ChartStream
context.Response.ContentType = "image/png"
context.Response.BinaryWrite(chart.ToBytesStream)
End Sub
Finally we can see our completed work and view the chart into the web page, run
the attached project, click on GenericHandler.ashx link and view the result:
Another useful way to use this class is to print the chart within an iTextSharp
pdf document, here a little example of how to use with it:
First we need to create an iTextSharp image and then fill it with our stream:
Dim img As iTextSharp.text.Image
img = iTextSharp.text.Image.GetInstance(chart.ToBytesStream)
Then we can add the image to a cell in a table and add the table to our
document:
Dim table As New PdfPTable(1)
cell = New PdfPCell(img)
table.AddCell(cell)
doc.Add(table)
Now we are ready to print our pdf document.