Creating a HTML5 Chart Helper Extension for ASP.NET MVC 4

Posted by: Sumit Maitra , on 7/17/2012, in Category ASP.NET MVC
Views: 72686
Abstract: In this article we will see how to build an HTML Helper Extension in ASP.NET MVC that renders a HTML 5 bar chart. The data for the chart can come from the server or be updated from the client side.

With the introduction of ASP.NET MVC, the traditional ‘Control’ model of GUI component development went away. Instead it was replaced with the more Web 2.0 style JavaScript and jQuery plugin extensibility model. Nevertheless, adding incremental features to existing HTML components was always required and towards this end Microsoft introduced the HtmlHelper and helper extensions. Helper extensions are .NET extension methods that return a string. Typically, this string is formatted HTML content.

In our sample today we create an extension that renders a bar chart on HTML5 Canvas. It can be bound to a data source from the server side or be assigned data source from the client side.

The charting code is taken from our free ‘DNC Magazine’ article and expanded to accept a dynamic data source.

 

Building a Html Helper Extension

Html Helper extensions are easy to build. Just follow the steps below to create our helper skeleton.

Step 1: We start with an MVC project and pick the Blank template.

Note we could pick a class library project template too and add package references as follows (via the Nuget package manager as follows)

a. PM> install-package Microsoft.AspNet.Mvc

b. Add reference to System.Web.dll from the ‘Add References’ dialog for the project

Step 2: Add a static class called ChartExtensions. Extension methods, by design, have to be defined in Static classes.

Step 3: Next add a static method Chart whose first parameters is this HtmlHelper and subsequent parameters are values required for rendering the chart.

chart-extensions-1

a. The dataSource is a list of integer arrays. For the example we have assumed a two dimensional array would be provided as a data source. We can make it more sophisticated by making it an array of objects and binding to different properties of the object.

b. xTitle: The text to be displayed on the x-axis.

c. yTitle: The text to be displayed on the y-axis.

Step 4: Next we setup two methods, one to convert the dataSource to JSON and the other to generate the required HTML.

genereate-datasource-setup-html

a. The GetDataSourceFromIntArray method uses the System.Web.Helpers’ Json static class to convert the input data source into a Json String. This string is assigned to a variable called arrDataSource and the whole string is returned.

b. The SetupHtml method implements the rendering logic

Step 5: Using TagBuilder to build the Html: ASP.NET provides us with the TagBuilder class that has helper methods to help create HTML elements easily. We use the TagBuilder to create our HTML layout as follows

<div>
<canvas …> … </canvas>
<script …> … </script>
<noscript> … </noscript>
</div>

 

The actual code is as follows

setup-html-method

a. As seen above, the TagBuilder object has an Attributes collection to which we can add the HTML attributes we need. To set text between the opening tag and closing tag, we use the SetInnerText. However unlike an XmlTextWriter, we can’t nest tags. To nest tags we simply assign the string representation of the TagBuilder to the InnerHtml of the parent TagBuilder. So the ‘container’ Tag Builder has the <div> that encapsulates the Canvas and the Script tags.

b. We have created a 400x600 canvas area. The chartName parameter is used for the id of the canvas element.

c. For now we have an empty SetupScript method. This method will eventually build the JavaScript required to render the bar graph.

d. The <noscript> tag holds the message to display when JavaScript is not enabled on the browser.

e. Point to note is the HtmlString object that is returned. The HtmlString is a special object that indicates to the Razor view engine that it should not Html Encode this string any further. If we use string instead of HtmlString, the Razor engine automatically Html Encodes the string and we see the markup as text instead of rendered Html.

Step 6: The SetupScript method: The setup script method has the JavaScript that actually renders the chart on the canvas. The original code is borrowed (with permission) from this project. A demo for it is available here. We have to make the following changes so that it accepts any data source instead of the fixed data source assigned to it in the demo. We have also updated the code to use the strings passed in for x-axis and y-axis labels. Beyond this the animation and rendering code is pretty much the same.

a. The variable initialization change

variable-initialization-changes

Earlier we had a hard-coded array of strings that was rendered on the canvas. Now we have the Json string that is created from the data source that was passed to the helper.

b. Changes to the barChart() method to set data source on the client side.

bar-chart-method-change

In the barChart method we earlier had no parameters and the elementId was hard-coded, now we use the value that’s passed into the helper.

We also pass a data parameter that is assigned to the data source of the graph.

c. Changes in drawMarkers() method to use the values passed into the helper for the x-axis and y-axis label

changes-to-draw-markers

d. Changes to handle two-dimensional array of points instead of one-dimensional array of comma separated strings.

changes-for-new-data-type

In the original code ,the data source is an array of strings. Each element in the array has two comma separated values, represent the year (at index-0) and number of hits (at index-1). We have updated our data source to be a two-dimensional array and hence we don’t need to do a string split to get the value. We directly access the value using appropriate indexes. This change is at three places in the code. One of them is shown above.

With these changes in place our Chart, HtmlHelper is ready to be tested in an ASP.NET Web Application

Integrating the Custom Helper in a MVC Web Application

With our Helper all set, we add an MVC Web Application to our solution and call it DotNetCurry.HtmlHelpers.WebHarness. We use the Internet template that gives us a default Index.cshtml to put our Helper in. The following steps guide us through the integration effort

Step 1: Add Reference to the HtmlHelper project.

Step 2: Add a Model class in the Models folder.

two-dimensional-data-view-model

This is our view model that will hold the data to be rendered in the Graph.

Step 3: Update the HomeController to create and pass sample data model.

home-controller-updated

As seen above, we create an instance of our ViewModel class and add some test data into it. We pass this data on to the Index view, where the HtmlHelper will use it.

Step 4: Update the Index.cshtml markup to use the helper

index-cshtml-final

The changes in Index.cshtml highlighted above, from top to bottom are as follows

a. Declare the model to be used in the page.

b. Add using to include the custom HtmlHelper

c. Added the HtmlForm inside which we use our Chart Helper extension. We give it an id=’sampleChart’, pass it the Model.Data and provide the labels for the x and y axes.

d. Finally in the jQuery document ready function, we initialize the chart by calling the barChart() method.

e. Our final effort looks as follows.

final-output

To change the graph change the data set coming from the controller.

That brings us to the end of this tutorial. We round off with some of the improvements possible.

Possible Improvements

1. Update the script to be able to bind to any Json object.

2. Use jQuery plugin syntax so that more than one helper can be created per page.

3. Allow more flexibility like passing parameters for bar colors, size of chart etc.

4. Allow multiple data sources to show comparison side by side.

5. Add more chart types like Pie etc.

Conclusion

Though they sound esoteric HtmlHelper extensions is a rather simple mechanism to inject rich functionality in a componentized way in ASP.NET MVC applications. We converted an existing HTML5 chart, originally created using plain HTML5 and JavaScript into a Chart HtmlHelper with very little code. For large projects, HtmlHelpers are a neat way to encapsulate small pieces of re-usable UI functionality.

The entire source code for this article can be downloaded over here

You can fork the code at https://github.com/dotnetcurry/HtmlHelperLibrary

Give a +1 to this article if you think it was well written. Thanks!
Recommended Articles
Sumit is a .NET consultant and has been working on Microsoft Technologies since his college days. He edits, he codes and he manages content when at work. C# is his first love, but he is often seen flirting with Java and Objective C. You can follow him on twitter at @sumitkm or email him at sumitkm [at] gmail


Page copy protected against web site content infringement by Copyscape


User Feedback
Comment posted by khouri on Wednesday, July 18, 2012 2:23 AM
why are all methods declared static?
Comment posted by Shawn De Rahan on Wednesday, July 18, 2012 2:50 AM
Thanks, this is the first time I understood how to use the HTMLHelpers. Is there an easy way to localize these helpers when needed
Comment posted by Sumit on Wednesday, July 18, 2012 3:10 AM
Khouri,
Html Helper extensions are essentially .NET extension methods. You can refer to this article on details of how extension methods work: http://msdn.microsoft.com/en-us/library/bb383977.aspx

Shawn
SInce we have total control over the HTML generation on the server side we can use standard server side localization techniques to generate the correct HTML.
Hope this helps,

Thanks and Regards,
Sumit.
Comment posted by Suprotim Agarwal on Wednesday, July 18, 2012 3:27 AM
@Shawn Localization can be added by either using an action method or extensions methods. If you choose option 1, then search the web on how to use action filters and dynamically calling the correct view. For option 2, write a HTML extension method that extends Partial and check if a localized view exists. If it does, call Partial using the localized version

Here's some pseudo code

// get the view name say vName
if (localizedViewAvailable)
vName= LocalizedView(helper, vName);
// call partial
return helper.Partial(vName, null, helper.ViewData);

@khouri fyi, you can create a HTML helper method using either a static method, extension method, viewmodels or editor templates.
Comment posted by Shawn De Rahan on Wednesday, July 18, 2012 4:38 AM
wow thanks for clearing my doubts. I will follow up if I get stuck
Comment posted by Suresh on Tuesday, July 24, 2012 9:09 PM
I have an mvc2 app and upgrading to mvc3 but when I use HtmlHelper, it is not recognized in a Razor page. Compile errors. ANy idea?
Comment posted by Sumit on Thursday, July 26, 2012 2:20 AM
Suresh, it's probably to do with references to System.Web. Can you confirm you are referring to the MVC3 version?

Ensure the reference to the System.Web.Mvc in web.config is for the correct version. If that doesn't work add a using in the page itself (see above for sample).

Thanks and Regards,
Sumit.
Comment posted by Aegis Global Software on Tuesday, August 7, 2012 6:08 AM
Hello guys.

Active Server Pages or ASP.net is a proprietary programming language used to create dynamic web content. ASP allows using such databases as Access and SQL to create feature rich websites with incorporated applications that are generally employed in web development.

All your comment for <a href="http://www.aegisisc.com/net-developers.html"><b>Asp.Net Developers</b></a> are welcome.

Thanks in advance.
Comment posted by subramanyam on Monday, November 5, 2012 6:34 AM
Is any possibility to click on each bar to navigate to other page/section??
Comment posted by Dragan Matek on Sunday, February 10, 2013 4:16 AM
You can use www.jqchart.com. jqChart offers pure HTML5 jQuery Charts. They have server wrappers for ASP.NET Web Forms and MVC.

jqChart ASP.NET MVC Samples - http://www.jqchart.com/aspnetmvc/chart
jqChart ASP.NET Web Forms Samples - http://www.jqchart.com/aspnet/chart
Comment posted by Dave on Monday, August 5, 2013 7:22 AM
ShieldUI provides a very powerful and highly customizable Charting Framework, with pure JavaScript, ASP.NET, ASP.NET MVC and Java Apache Wicket components.
Check the demos at: https://demos.shieldui.com, and the company website: http://www.shieldui.com for more info.
Comment posted by Bhagwant on Saturday, April 26, 2014 9:07 AM
Nice article

Post your comment
Name:  
E-mail: (Will not be displayed)
Comment:
Insert Cancel