Charts in ASP.Net MVC 2 With Drill-Down!

I have seen several posts on how to use the ASP.Net chart controls with MVC and they all involved some sort of hybrid web forms approach.  I have a simple solution which is 100% MVC.  Here is a summary of the process:

  • Create an action to render the chart.
  • Create an action to render the image map.
  • Use a normal IMG tag to render the chart image.
  • Use Html.RenderAction to render the image map.

The most simple implementation without drill-down would look something like this:

public ActionResult Chart(int? id) {     Chart chart = new Chart();     // Get data for id and add chart area, series, points, etc. to chart     MemoryStream ms = new MemoryStream();     chart.SaveImage(ms, ChartImageFormat.Png);     return File(ms.ToArray(), "image/png"); }

Then in your view you would do something like this:

<img src="<%= Url.Action("Chart", new { id = Model.Id }) %>" />

That takes care of the chart, but what about drill-down?  To render a chart with drill-down you will need to render both the image tag and the image map in your view.  This means that you need to use the same chart two times:  once to render the map and then to render the image.  If the chart is simple, you can call the code to create the chart twice, but a more robust solution is to cache the chart.

One important note on GetHtmlImageMap:  You MUST call Chart.SaveImage prior to calling Chart.GetHtmlImageMap as indicated in the MSDN reference for the chart control.

Here is the code to create the image map and cache the chart:

public ActionResult ChartMap(int? id, string name) {     Chart chart = new Chart();     // Get data for id and add chart area, series, points, etc. to chart     // Make sure to use Url.Action for any drill-down URLs     MemoryStream ms = new MemoryStream();     chart.SaveImage(ms, ChartImageFormat.Png);     Session["Chart"] = ms.ToArray();     return Content(chart.GetHtmlImageMap(name)); }

Then the code to render the cached chart becomes as follows:

public ActionResult Chart(int? id) {     byte[] data = Session["Chart"] as byte[];     return File(data, "img/png"); }

Then this is the code for your view:

        <img src="<%= Url.Action("Chart", new { id = Model.Id }) %>" usemap="#MyMap" />
        <% Html.RenderAction("ChartMap", new { id = Model.Id, name = "MyMap" }); %>

In a future post, I will outline using a HTML Helper extension to simplify this.

This article is part of the GWB Archives. Original Author: Doug Lampe

New on Geeks with Blogs

  • We Won The One Award I Actually Care About

    Full Scale made the Inc. 5000 for the fifth year straight, the 12th listing across my three companies. Here is why the one award you cannot buy is worth stopping for.

  • Your Customers Build the Features Now

    I let a tool I liked sit dead for a year rather than build the features I wanted. An MCP server meant I never had to, and your customers can do the same to your product.

  • Get the Size of a Directory in Linux the Easy Way

    du -sh for the quick answer, ncdu for the cleanup, df for the disk itself: every command for checking directory size in Linux, plus why du and df never agree.

  • Vim Search and Replace: The Ultimate Guide

    One :%s command replaces every match in a file before a find dialog would even open. The Vim substitute patterns worth the muscle memory: flags, ranges, capture groups, and multi-file edits.