Skip to content

An introduction to custom SVG charting using MVC and Razor

Published by Concentra

Discover analytics solutions from Concentra


Concentra’s analytics and business intelligence teams turn information into insight to give you the edge from your data. Learn more.

SVG (Scalable Vector Graphics) is becoming increasingly popular for displaying graphics on the web, and there are already quite a few JavaScript libraries available to use (Highcharts, Raphaël, GoogleCharts).

However, the combination of complex charts and slow client machines means that using front end code to render graphics can be slow. To combat performance issues, we can render SVG documents through the back end using features of ASP.NET MVC.

This blog post will cover a basic implementation of SVG rendering using MVC and the Razor view engine. It will also cover the structuring of an SVG document for charting and non-SVG compatability.

Implementation

Using MVC, we can generate our data objects from the database (or any other data source) transform them into our view model and provide the values to our SVG view.

Displaying SVG in your MVC application is as simple as embedding the SVG tags directly in your razor views.

However, you may find embedding your SVG content along with your regular HTML elements will result in very messy views. This is where partial views come in handy. Using partial views, we can separate our SVG content into their own views and even split off common SVG blocks into smaller partial views.

Below shows an example of a partial view being used to render a SVG circle element.


Figure 1.  Partial V
iew using ASP.NET MVC

 

Further extending this idea, we can create our own custom HtmlHelpers to return SVG markup based on defined methods and parameters:

We can then use the helper in our view by calling:

@Html.SvgHelper.SvgCircle(20, 20, 10)

Which produces our SVG circle element:



The resulting effect of using these extensions is a cleaner, clearer SVG Razor view with reusable elements.

Structuring the SVG document

Now that we have our helpers and partial views, it’s time to start structuring our SVG. An important note about SVG is that it uses a painters model (i.e. elements which appear later in the document are displayed on top of previous ones). This means that you will need to consider the order in which your elements appear in the document.

After declaring our document type and root SVG () node, we can start drawing our elements. Let’s start by splitting up the components which make up our basic chart:

SVG provides a grouping element () which we can use to group sub elements together to form our chart components. Using groups also allow us to apply transformation and effects on multiple elements nested within the group.

In the case of our chart, we may want to apply a grouping to a series along with its points so that any effects are applied to both elements. The example below shows a line and a point grouped so that we can apply a CSS hover effect on the line when the users mouse overs the group:


Figure 2. An SVG line and circle element in a group (dashed outline)

 

 

It is important to note that when an element is added to a group, the group will expand and “wrap” all child elements. This can have unwanted effects when you style your graphic with hover events, etc.

We can now put together our SVG chart, keeping in mind the painters model, so that groups which appear at the back are rendered first and groups we want to see on top are rendered last.

First we render the background grid lines, then the relevant labels. Next, we draw the line groups and styles (e.g. shadow elements behind the line elements). Finally, we render the points to sit on the lines. Below shows a graphical view of the structure of our SVG document:

Figure 3. SVG chart document hierarchy

 

 

Using the above structure, we can see the progression of layers of our chart structure.


 Figure 4. Progression of chart layers

 

 

Compatibility

Because SVG is not compatible with IE8 and lower, we need to create a non-SVG view for clients running older browsers. The typical way this is handled in SVG libraries is too render the VML (Vector Markup Language) equivalent of the chart. This means you essentially have to code two versions of your graphic, one in SVG and one in VML.

Another solution is to use a flash rendering engine such as SVGWeb. This tool converts your SVG object into flash, retaining most of the functionality. However, this is making the assumption that all users have flash installed. It also means that we are required to load an additional plugin, slowing down the total render time of the graphic.

The solution we chose was to render the SVG graphic as an image using backend code. This allows us to keep one version of the SVG and render a near identical image version to non-SVG compatible browsers. Using the same pixel coordinates of the SVG, we can then create an image map to layer over the image to provide functionality such as tooltips and hover styling.

Although we lose some interactivity (such as CSS hover styles and animation) we retain the same SVG object without having to rewrite or translate our SVG to VML. Additional interactivity can be achieved through external scripts using the image map and our original SVG coordinates.

 
 Figure 5. Completed SVG chart

 

 
*The header image used in this blog is credited to Highcharts

Discover analytics solutions from Concentra


Concentra’s analytics and business intelligence teams turn information into insight to give you the edge from your data. Learn more.