Technology Blog

Archive for December 14th, 2010

Uncharted Territory

Tuesday, December 14th, 2010

A recent ASP MVC 3 project has required us to create some simple charts. As it’s a .NET 4 project we hoped to use the lovely new charting controls provided by Microsoft. You can read all about them in Scott Guthrie’s blog here and as you can see they look very pretty and appear simple to implement.

NastyPieThat was the theory at least. There is a simple tutorial on how to use the controls in an MVC project here. The problem is that the output looks nothing like the charts in Scott Gu’s blog - far from it in fact with no fancy 3d effects and as a bonus nasty jpeg compression artefacts appear. While eliminating the compression artefacts is straightforward, (pass the write method a parameter of “.png”) gaining control of the styling is far more convoluted process.

The style of the charts is controlled by the chart.theme parameter, with only four themes available. None of them are terribly exciting and there are no obvious methods for customisation. So far so disappointing. Viewing the class definition in Visual Studio reveals that ChartTheme is a static class with each theme being a constant, declared as a string that appears to be XML mark-up. We wondered if it would be possible to extend this class, adding our own new themes along the way. Incredibly, it’s possible to do exactly that by creating a static partial class that mirrors the original with the exception of the tweaks we want to make to the XML.

Vanilla theme from ChartTheme

 public const string Vanilla = @"<Chart Palette=""SemiTransparent""
BorderColor=""#000"" BorderWidth=""2"" BorderlineDashStyle=""Solid"">
    <ChartArea _Template_=""All"" Name=""Default"">
                <MinorGrid Enabled=""False"" />
                <MajorGrid Enabled=""False"" />
                <MajorGrid Enabled=""False"" />
                <MinorGrid Enabled=""False"" />
Of course making those XML tweaks really isn’t easy – there’s a lot there and a trial and error process is always time consuming. Furthermore, guessing missing parameters hasn’t ever really worked well for me in the past and I don’t anticipate psychic coding to bear fruit in the future either.

At this point it seemed sensible to have another look at Scott Gu’s blog. It contains a sample project that demonstrates the features of the chart controls. This gives us a way of generating the xml we need to theme our charts. It also has a sort of WYSIWYG editor for each chart so we can style the chart to our taste. The Chart class includes a SaveXml method that predictably saves the chart to an xml file. Inserting a call to this method generates the xml we need for our partial class.

Strip out all the data, leaving just the formatting information and there you have it – a chart theme you can reuse throughout your MVC project. Here is the code for a tasteful pie chart…

public const string JMW3D = @"

<Chart BackColor=""WhiteSmoke"" BackGradientStyle=""TopBottom""
BackSecondaryColor=""White"" BorderColor=""26, 59, 105""
    <Series ChartArea=""Default"" Font=""Trebuchet MS, 4.25pt,
style=Bold"" ChartType=""Pie""  Name=""Default""
Legend=""Default"" XValueType=""String"" YValueType=""Double""
Color=""220, 65, 140, 240"" BorderColor=""180, 26, 59, 105""
CustomProperties=""DoughnutRadius=60, PieLabelStyle=Disabled,
    <ChartArea Name=""Default"" BackColor=""Transparent""
BackSecondaryColor=""Transparent"" ShadowColor=""Transparent""
BorderColor=""64, 64, 64, 64"" BorderWidth=""0"">
      <AxisY LineColor=""64, 64, 64, 64"">
        <MajorGrid LineColor=""64, 64, 64, 64"" />
        <LabelStyle Font=""Trebuchet MS, 8.25pt, style=Bold"" />
      <AxisX LineColor=""64, 64, 64, 64"">
        <MajorGrid LineColor=""64, 64, 64, 64"" />
        <LabelStyle Font=""Trebuchet MS, 8.25pt, style=Bold"" />
      <Area3DStyle Rotation=""0"" />
    <Legend LegendStyle=""Table"" Name=""Default""
IsTextAutoFit=""true"" BackColor=""Transparent""
Font=""Trebuchet MS, 8.25pt, style=Bold"" Alignment=""Center""
    <Title Font=""Arial, 10.25pt, style=Bold"" ForeColor=""black""
ShadowOffset=""0"" ShadowColor=""32, 0, 0, 0"" Name=""Title1"">
  <BorderSkin SkinStyle=""None"" />

NicePieAnd it’s results:

It’s admittedly one of the most round about methods I have used for doing, well anything. But it works. Feel free to download a sample project file containing a couple of examples in full.




December 2010
« Sep   Jan »