Posts Tagged ‘ User Control ’

Enabling MSChart ImageMap and AJAX functionality

    In a previous post I talked about utilizing MSChart in an SSRS report. In this post we will talk about how to use the image map capabilities of the MSChart control. You will need to create two identical charts, one set with a render type of imagemap, the other set to binarystreaming. The easiest way to do this without having duplicate code is to create a user control containing your chart.

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="graph.ascx.cs" Inherits="graph" %>
<%@ Register Assembly="System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI.DataVisualization.Charting" TagPrefix="asp" %> 
<asp:chart id="mainChart" runat="server" height="296px" width="412px"
    imagetype="Png" palette="BrightPastel" backcolor="LightBlue" rendertype="BinaryStreaming"
    borderdashstyle="Solid" backgradientstyle="TopBottom" borderwidth="2" bordercolor="181, 64, 1">
    <titles>
        <asp:Title ShadowColor="32, 0, 0, 0" Font="Trebuchet MS, 14.25pt, style=Bold" ShadowOffset="3" Text="Binary Streaming" ForeColor="26, 59, 105"></asp:Title>
    </titles>
    <legends>
        <asp:Legend Enabled="True" IsTextAutoFit="True" Name="Default" BackColor="Transparent" Font="Trebuchet MS, 8.25pt, style=Bold" Alignment="Center" Docking="Bottom"></asp:Legend>
    </legends>
    <borderskin skinstyle="Emboss" />
    <series>
        <asp:Series XValueType="String" Name="Targets" ChartType="SplineArea" BorderColor="180, 26, 59, 105" Color="220, 0, 0, 0" YValueType="Double"/>
        <asp:Series XValueType="String" Name="Actuals" ChartType="SplineArea" BorderColor="180, 26, 59, 105" Color="127, 255, 255, 0" YValueType="Double"/>
        <asp:Series XValueType="String" Name="ActualPoints" ChartType="SplineArea" BorderColor="180, 200, 59, 105" Color="127, 65, 140, 240" YValueType="Double"/>
    </series>
    <chartareas>
        <asp:ChartArea Name="MainChartArea" BorderColor="64, 64, 64, 64" BorderDashStyle="Solid" BackSecondaryColor="White" BackColor="OldLace" ShadowColor="Transparent">
            <axisy linecolor="64, 64, 64, 64">
                <labelstyle font="Trebuchet MS, 8.25pt, style=Bold"/>
                <majorgrid linecolor="64, 64, 64, 64"/>
            </axisy>
            
            <axisx IsMarginVisible="False" linecolor="64, 64, 64, 64">
                <labelstyle font="Trebuchet MS, 8.25pt, style=Bold"/>
                <majorgrid linecolor="64, 64, 64, 64"/>
            </axisx>
        </asp:ChartArea>
    </chartareas>
</asp:chart>

In the code behind of your graph user control you will want to publicly expose the chart control.

 public System.Web.UI.DataVisualization.Charting.Chart MainChart
    {
        get
        {
            return mainChart;
        }
    }

The Page Load event should go about parsing the query string for any data needed to generate the chart itself.

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            int kpiID = 0;
            int organizationID = 0;
            int programID = 0;
            int fiscalYearID = 0;
            int height = 0;
            int width = 0;

            int.TryParse(Request.QueryString["kpiID"], out kpiID);
            int.TryParse(Request.QueryString["organizationID"], out organizationID);
            int.TryParse(Request.QueryString["programID"], out programID);
            int.TryParse(Request.QueryString["fiscalYearID"], out fiscalYearID);
            int.TryParse(Request.QueryString["height"], out height);
            int.TryParse(Request.QueryString["width"], out width);

            if (height == 0)
                height = 296;

            if (width == 0)
                width = 412;

            mainChart.Height = Unit.Pixel(height);
            mainChart.Width = Unit.Pixel(width);


            string kpiName = Request.QueryString["kpiName"];

            if (kpiID != 0)
                BuildGraph(kpiID, fiscalYearID, organizationID, programID, kpiName);
        }
    }

    The next step is to create two web pages: graph.aspx, and graphImageMap.aspx.  Each page will contain nothing but your newly created graph user control, however, their code behinds will differ slightly.

GraphImage.aspx content:

Page Content for graphImage.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="graphImage.aspx.cs" Inherits="graphImage" %>
<%@ Register src="ascx/graph.ascx" tagname="graph" tagprefix="uc1" %>
<uc1:graph ID="graph1" runat="server" />

Code Behind for graphImage.aspx:

public partial class graphImage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            graph1.MainChart.RenderType = System.Web.UI.DataVisualization.Charting.RenderType.BinaryStreaming;
        }
    }
}

GraphImageMap.aspx content:

Page Content for graphImageMap.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="graphImageMap.aspx.cs" Inherits="graphImageMap" %>
<%@ Register src="ascx/graph.ascx" tagname="graph" tagprefix="uc1" %>
<uc1:graph ID="graph1" runat="server" />

Code Behind for graphImageMap.aspx:

public partial class graphImageMap : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            graph1.MainChart.RenderType = System.Web.UI.DataVisualization.Charting.RenderType.ImageMap;
            graph1.MainChart.ImageLocation = "graphImage.aspx?" + Request.QueryString.ToString();
        }
    }
}

 

In the code behind of the graphImage web page, set the exposed chart control property of the graph user control to binary streaming. In the code behind of the graphImageMap web page, set the exposed chart control property of the graph user control to imagemap. Also, set the ImageLocation property to reference graphImage webpage and pass along the query string. This will ensure that the imagemap page is creating the exact same chart as the image page chart. To try out this new MS Chart functionality, we used JQUERY to setup a real world example. Let’s say you want to pop up an interactive chart when a user hovers over a link on a webpage.

<html>
<head>
 <script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
    <script type="text/javascript" src="js/jquery-ui-1.8.6.custom.min.js"></script>
    
     <script type="text/javascript">
         function ShowDialog(imgURL) {
             var uniqueTime = new Date().getTime();
             $("#graphImage").attr("src", imgURL + '&time=' + uniqueTime);
             $("#dialog").dialog("open");
         }
         // we will add our javascript code here
         $(document).ready(function() {
             $("#dialog").dialog({
                 autoOpen: false,
                 height: 350,
                 width: 440,
                 modal: false,
                 closeOnEscape: true,
                 show: 'fade',
                 hide: 'fade'
             });


         });

     function ShowDialog(imgURL) {
             $("#graphImage").attr("src", imgURL);
             $("#dialog").dialog("open");
         }
         // we will add our javascript code here
         $(document).ready(function() {

             $(".test").mouseenter(function() {
                 $.ajax({
                     url: "graphImageMap.aspx?kpiID=2004&fiscalYearID=5&organizationID=4&programID=219&kpiname=AmazingMetric",
                     cache: false,
                     async: false,
                     success: function(html) {
                         $("#dialogInner").replaceWith(html);
                     }
                 });
                 $("#dialog").dialog("open");
             });
     </script>  
</head>
<body>
    <a id='link' class="test">hello world</a>
        <div id="dialog" title="My Graph">
            <div id="dialogInner"></div>
        </div>
</body>
</html>

I hope you found this post helpful in creating an interactive MS Charting solution.  Now get coding!