Using XtraChart ASP.NET control in an ASP.NET MVC project

The problem

These days I am building an ASP.NET MVC project that requires charting. The problem is that there are no native ASP.NET MVC charting controls out there. The only one I am aware of is the one from Syncfusion . The problem with it is that it is in a beta and I didn’t have time to test it out. BTW, Syncfusion is the only 3rd party control provider (in beta though) for ASP.NET MVC AFAIK.

The solution

Anyway, back to my problem – charting in ASP.NET MVC. It is quite obvious that I have to use an ASP.NET control for the job. And since I already own and I am used to XtraCharts I’ve decided to give it a try (alternatives include use of Microsoft’s free ASP.NET Chart Control (which works in ASP.NET MVC for sure) and other ASP.NET charting controls might work as well). And guess what: XtraCharts works without many problems. As an image provider that is – I don’t need callbacks nor I think they are supported in this scenario.

Creating a test project

There are couple of extra steps necessary to use XtraCharts in ASP.NET MVC project. Here are steps necessary to create a test project.

Requirements: XtraCharts v9.1.

1. Drop a WebChartControl toolbox item (residing in DX.9.1.: Data Toolbox’ tab) on the Index view (I tested with the view (aspx) but it should work with partial view (ascx) as well). You’ll get this code:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Register Assembly="DevExpress.XtraCharts.v9.1.Web, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.XtraCharts.Web" TagPrefix="dxchartsui" %>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h2><%
   1: = Html.Encode(ViewData["Message"]) 































































%></h2>































































<p>































































To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.































































</p>































































<dxchartsui:WebChartControl ID="WebChartControl1" runat="server">































































</dxchartsui:WebChartControl>































































</asp:Content>
































It might happen that all the necessary assemblies won’t be referenced automatically. In this case add manually these (v9.1.x) assemblies:

  1. DevExpress.Web
  2. DevExpress.Charts.Core
  3. DevExpress.XtraCharts

2. Adjust WebChartControl’s settings either directly or through designer (yes, you can use its designer!). I’ll create a 3D pie chart with a single series bound to Name/Value pair. Disable both EnableCallbacks and EnableViewState.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Register Assembly="DevExpress.XtraCharts.v9.1.Web, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.XtraCharts.Web" TagPrefix="dxchartsui" %>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h2><%
   1: = Html.Encode(ViewData["Message"]) 































































%></h2>































































<p>































































To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.































































</p>































































<dxchartsui:WebChartControl ID="someChart" runat="server" EnableViewState="false" EnableCallbacks="false"































































DiagramTypeName="SimpleDiagram3D" Height="200px" Width="300px">































































<SeriesSerializable>































































<series argumentdatamember="Name" labeltypename="Pie3DSeriesLabel" name="Series 1"































































pointoptionstypename="PiePointOptions" seriesviewtypename="Pie3DSeriesView" valuedatamembersserializable="Value">































































<view hiddenserializablestring="to be serialized"></view>































































<label hiddenserializablestring="to be serialized" linevisible="True" overlappingoptionstypename="OverlappingOptions">































































<fillstyle filloptionstypename="SolidFillOptions">































































<options hiddenserializablestring="to be serialized"></options>































































</fillstyle>































































</label>































































<pointoptions hiddenserializablestring="to be serialized"></pointoptions>































































<legendpointoptions hiddenserializablestring="to be serialized"></legendpointoptions>































































</series>































































</SeriesSerializable>































































<SeriesTemplate LabelTypeName="Pie3DSeriesLabel" PointOptionsTypeName="PiePointOptions"































































SeriesViewTypeName="Pie3DSeriesView">































































<View HiddenSerializableString="to be serialized">































































</View>































































<Label HiddenSerializableString="to be serialized" LineVisible="True" OverlappingOptionsTypeName="OverlappingOptions">































































<FillStyle FillOptionsTypeName="SolidFillOptions">































































<Options HiddenSerializableString="to be serialized"></Options>































































</FillStyle>































































</Label>































































<PointOptions HiddenSerializableString="to be serialized">































































</PointOptions>































































<LegendPointOptions HiddenSerializableString="to be serialized">































































</LegendPointOptions>































































</SeriesTemplate>































































<Diagram RotationMatrixSerializable="1;0;0;0;0;0.5;-0.866025403784439;0;0;0.866025403784439;0.5;0;0;0;0;1">































































</Diagram>































































<FillStyle FillOptionsTypeName="SolidFillOptions">































































<Options HiddenSerializableString="to be serialized"></Options>































































</FillStyle>































































</dxchartsui:WebChartControl>































































</asp:Content>
































































3. Add the following registration on the top of the page:

<%@ Register Assembly="DevExpress.XtraCharts.v9.1, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.XtraCharts" TagPrefix="dx" %>

and change nodes of type <series> to type <dx:series>. Otherwise you’ll have a naming conflict.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Register Assembly="DevExpress.XtraCharts.v9.1.Web, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.XtraCharts.Web" TagPrefix="dxchartsui" %>
<%@ Register Assembly="DevExpress.XtraCharts.v9.1, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.XtraCharts" TagPrefix="dx" %>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h2><%
   1: = Html.Encode(ViewData["Message"]) 































































%></h2>































































<p>































































To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.































































</p>































































<dxchartsui:WebChartControl ID="someChart" runat="server" EnableViewState="false" EnableCallbacks="false"































































DiagramTypeName="SimpleDiagram3D" Height="200px" Width="300px">































































<SeriesSerializable>































































<dx:series argumentdatamember="Name" labeltypename="Pie3DSeriesLabel" name="Series 1"































































pointoptionstypename="PiePointOptions" seriesviewtypename="Pie3DSeriesView" valuedatamembersserializable="Value">































































<view hiddenserializablestring="to be serialized"></view>































































<label hiddenserializablestring="to be serialized" linevisible="True" overlappingoptionstypename="OverlappingOptions">































































<fillstyle filloptionstypename="SolidFillOptions">































































<options hiddenserializablestring="to be serialized"></options>































































</fillstyle>































































</label>































































<pointoptions hiddenserializablestring="to be serialized"></pointoptions>































































<legendpointoptions hiddenserializablestring="to be serialized"></legendpointoptions>































































</dx:series>































































</SeriesSerializable>































































<SeriesTemplate LabelTypeName="Pie3DSeriesLabel" PointOptionsTypeName="PiePointOptions"































































SeriesViewTypeName="Pie3DSeriesView">































































<View HiddenSerializableString="to be serialized">































































</View>































































<Label HiddenSerializableString="to be serialized" LineVisible="True" OverlappingOptionsTypeName="OverlappingOptions">































































<FillStyle FillOptionsTypeName="SolidFillOptions">































































<Options HiddenSerializableString="to be serialized"></Options>































































</FillStyle>































































</Label>































































<PointOptions HiddenSerializableString="to be serialized">































































</PointOptions>































































<LegendPointOptions HiddenSerializableString="to be serialized">































































</LegendPointOptions>































































</SeriesTemplate>































































<Diagram RotationMatrixSerializable="1;0;0;0;0;0.5;-0.866025403784439;0;0;0.866025403784439;0.5;0;0;0;0;1">































































</Diagram>































































<FillStyle FillOptionsTypeName="SolidFillOptions">































































<Options HiddenSerializableString="to be serialized"></Options>































































</FillStyle>































































</dxchartsui:WebChartControl>































































</asp:Content>
































































4. Under Models folder create RhData class that will hold data:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcApplication10.Models
{
public class RhData
{
public string Name { get; set; }
public int Value { get; set; }
}
}

5. Add class Index.aspx.cs next to Index.aspx file. This will serve as codebehind file. Also add Page_Load method, create and bind data to chart right in there. Note that you have to declare chart instance field as well since the designer won’t do it for you.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication10.Models;
namespace MvcApplication10.Views.Home
{
public class Index: ViewPage
{
protected global::DevExpress.XtraCharts.Web.WebChartControl someChart;
protected void Page_Load(object sender, EventArgs e)
{
List<RhData> data = new List<RhData>();
data.Add(new RhData { Name = "One", Value = 1 });
data.Add(new RhData { Name = "Two", Value = 2 });
someChart.DataSource = data;
someChart.DataBind();
}
}
}

Note: The proper MVC to provide data way would be through the model, however for the sake of simplicity I took this shortcut. The binding itself has to be done in Page_Load event.

6. Wire up the code behind class to the view by adding CodeBehind attribute and modifying Inherits one.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="MvcApplication10.Views.Home.Index" CodeBehind="Index.aspx.cs" %>

 

 

The result

If everything goes well you should see such output.

demo

This will do just fine until there is an MvcXtraChart control I guess.

XtraChartsMvc.zip (241.46 kb) (Updated) Note: Built with DevExpress v9.1.3.0. If you use other version then you should run DX' ProjectConverter tool or just do a search and replace of "9.1.3.0" with your version.

Shout it


Comments (6) -

  • Eric

    5/24/2009 3:08:23 PM | Reply

    Great write up! I was just going to pass one thing on that you may like as well - it was written up by Nic Roche over at Code Project:

    www.codeproject.com/.../...tControlFileResult.aspx

    In which you can create the chart using a FileResult and just export the file as a img. And that way you could implement it using a img tag in your view

  • Sri

    6/5/2009 2:33:11 AM | Reply

    It is very good. Do you example for XtraChart in asp.net mvc which datasource for the chart from linq to sql?

  • Sri

    6/5/2009 2:35:30 AM | Reply

    I mean ....Do you have example linq to sql as datasource XtraChart....Smile

  • Miha Markic

    6/5/2009 7:18:26 AM | Reply

    Hi Sri,

    No problem, below is an example of modified Page_Load method. It takes first four customers with most orders.
    NorthwindDataContext dc = new NorthwindDataContext();
    var query = (from c in dc.Customers
                 orderby c.Orders.Count descending
                 select new
                 {
                     Name = c.ContactName,
                     Value = c.Orders.Count
                 }).Take(4);
    someChart.DataSource = query.ToList();
    someChart.DataBind();

  • Miha

    6/8/2009 7:09:53 AM | Reply

    You could also use the Google Chart API with a wrapper method or two. I find it an interesting alternative to server-side chart generation: http://code.google.com/apis/chart/

    And extension methods would come handy for generating the URLs for chart embedding.

  • Miha Markic

    6/8/2009 5:42:26 PM | Reply

    Hi Miha,

    Yes, that's an option but there are problems with it.
    1. You have to rely Google. This is ok for non-pro apps but not for professional.
    2. You are sending (possibly delicate) data to Google (as if Google hasn't enough data on you Smile)
    3. Google charts are limited, at least for now.

    These are my (out of my head) observations. I am not saying that using Google charts (or any such product) is always bad. I am merely saying that one has to take into considerations all aspects when deciding for such service - it certainly has place in some applications.

Pingbacks and trackbacks (1)+

Loading