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.