2016-09-21
Now that we have the Chart control configured in Web.Config,
we can set up our object.
I'd like to start by showing a relatively basic bar chart
to get you up and running. I'll show you how to add some
bells and whistles in another document.
CODE FORWARD
I like to keep the code forward as plain as possible,
preferring to handle the heavier configuration in the
compiled codebehind.
The basic chart object has two elements with the control
tag -- series and chart area. Each of these elements
contains a web control (asp:Series and asp:ChartArea).
Included below the chart control is a Label control,
called lblStatus, which is used for reporting exception
messages back to the screen (see Catch blocks in code
that follows).
Notice that the Series web control points to the ID of the
ChartArea control.
DATASOURCE
My datasource for this is an XML doc, pared down to exactly
what I want to show.
9/19/2016
1
. . .
Two columns -- dates and counts. No big whoop.
CODE BEHIND
(1) Load the Dataset
We have our data, so it's time to load it into a dataset.
For text content I typically use a slightly different
datareader, but because the table structure is important,
I went this route:
Private Function LoadDataSet() As DataSet
Dim ds As New DataSet
Dim nt As New NameTable()
Dim objIntCount As Object = nt.Add("intCount")
Dim objCompletedDate As Object = nt.Add("completedDate")
Dim settings As New XmlReaderSettings
'disable parsing dtd's -- reduce attack surface vs. XML bombing
settings.DtdProcessing = DtdProcessing.Ignore
'add the nametable
settings.NameTable = nt
'create a reader object and point it to the xml doc
Dim rdr As XmlReader = XmlReader.Create(Server.MapPath("~/xml/graph.xml"), settings)
Try
'import the reader's data into the dataset
ds.ReadXml(rdr, XmlReadMode.InferSchema)
Catch ex As Exception
'build the status message, hide the chart and panel.
lblStatus.Text = ex.Message
lblStatus.ForeColor = Color.Red
lblStatus.Visible = True
Chart1.Visible = False
Finally
'close the reader
If Not rdr.ReadState = ReadState.Closed Then
rdr.Close()
End If
End Try
Return ds
End Function
I'll later consume this as a DataView.
In my Catch block, I capture the message and display it in a
Label control called lblStatus, and hide the chart control.
(2) Yes, I'm Still Harping about XML Bombing
An XML bomb is an XML document crafted in such a way that it
could overload the parser on the server by causing it to
create an "exception"-ally large object, generally through
recursion (see what I did there?). This amounts to a denial-
of-service attack on your Web server.
in the settings object, be sure you set that DtdProcessing
property to ignore.
(3) Configure the Chart
Access the chart object by its ID in the codebehind and
set these values:
'create a dataview from the dataset
Dim dvDataView As New DataView(DsDataSet.Tables(0))
With Chart1
'basic dimensions
.Height = 350
.Width = 700
'borders
.BorderlineDashStyle = ChartDashStyle.Solid
.BorderlineColor = Color.DarkGray
.BorderlineWidth = 2
'color
.Palette = ChartColorPalette.EarthTones
.ForeColor = Color.DarkGray
With .Series.Item("Series1")
'values
.XValueType = ChartValueType.Date
.YValueType = ChartValueType.Int32
.YValueMembers = "itemCount"
.XValueMember = "completedDate"
.XAxisType = AxisType.Primary
'chart type
.ChartType = SeriesChartType.Column
End With
'image goop. The handler is in Web.Config
.ImageStorageMode = ImageStorageMode.UseHttpHandler
.ImageType = ChartImageType.Png
'databinding
.DataSource = dvDataView
.DataBind()
'make sure we can see it!
.Visible = True
End With
Yes, you CAN nest With...End statements. Who knew?
So, there's method to my madness in these property assignments.
The first two properties I assign are basic image size properties.
Followed by decorations (color, border and so on.)
Next, I handle all of the series configurations -- setting the
data types and data members for the axes. Next come a couple of
image storage properties -- one directing use of the handler in
our Web.Config, and the next specifying what type of image to
generate.
Once all of these other settings are made, I specify the data
source and bind the chart object to it using the simple DataBind()
method. Lastly, I make surethe completed chart is visible.
This chart isn't using any custom event handlers. It's a straightforward
model, driven by the normal flow of Web Form events. In my next post,
I'll show you a more involved column chart with a few extras that will
use an event handler.
That should be it for now! Contact me using the site's contact form if
you have questions. Feel free to use the code in your projects. A shout
out in your project would be thoughtful. Also, drop me a line and let me
know how you might have tweaked things to better suit your needs.
Finally, I wouldn't profess to be THE expert on matters represented in
my code -- so drop me a line if you have constructive suggestions, too.
I'd like to hear from you!
Best,
halfgk
Copyright 2016 halfgk.com