.NET Zone is brought to you in partnership with:

I am a web developer with passion for datavisualization and ui components. My experience over the past 10 years is mostly in the asp.net stack, with asp.net, mvc, sl and wpf. David has posted 1 posts at DZone. You can read more from them at their website. View Full User Profile

A sales dashboard ASP.NET application

09.06.2013
| 3380 views |
  • submit to reddit
Introduction

In this article, we tackle a common data visualization task – creating a sales dashboard. A sales dashboard is widely used in business presentations, to outline key performance indicators for a given business process or objective. Key to any such presentation is the good visualization of the data, as well as the polished appearance.  To achieve the task a hand, I am using related chart components, which offer all of the required functionality. The sample uses chart components from ShieldUI, which are freely available from their site.

Download sample

The finished presentation looks like this:

Using the code

To start off, I create a new Visual Studio project for web. The web application needs to contain a single .aspx file, which will host the related controls.  The second step is to include the .dll files for the chart components to the project:

Once we have added the .dlls for the component we will use, we need to reference it in the project.

This can be done directly in the .aspx page, containing out dashboard sample: 

<%@ Register Assembly="Shield.Web.UI" Namespace="Shield.Web.UI" 
TagPrefix="shield" %>   

Then, since this control is a server-side wrapper of a client JavaScript component, we also need to include references to the base JavaScript chart. This is also done in the .aspx file:

<head>  
 <link rel="stylesheet" type="text/css"  
 href="shield-chart.1.2.2-Trial/shield-chart.1.2.2-Trial/css/shield-chart.min.css"/>  
   <script src="shield-chart.1.2.2-Trial/shield-chart.1.2.2-Trial/js/jquery-1.9.1.min.js"  
     type="text/javascript"></script>  
   <script src="shield-chart.1.2.2-Trial/shield-chart.1.2.2-Trial/js/shield-chart.all.min.js"  
     type="text/javascript"></script>  
 </head>  

The next phase of the project is to transform the requirements into code. The requirements specify that we need to have two or more related charts. In our case, we have a control to host the quarters, as well as a second chart to display data related to each quarter and one more chart to relate to the second one. In this manner, we can have subdivision by quarter and product-line - a common data visualization scenario for a sales dashboard. Following the outline above, we add the first chart to the .aspx file. Its declaration looks like this:

<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="false">  
    <ContentTemplate>  
       <shield:ShieldChart ID="ShieldChart1" runat="server" AutoPostBack="true" OnSelectionChanged="ShieldChart1_SelectionChanged" Width="320px" Height="330px"  
        OnTakeDataSource="ShieldChart1_TakeDataSource">  
        <PrimaryHeader Text="Quarterly Sales">  
        </PrimaryHeader>  
         <ExportOptions AllowExportToImage="false" AllowPrint="false" />  
         <TooltipSettings CustomPointText="Sales Volume: <b>{point.y}</b>">  
         </TooltipSettings>  
        <Axes>  
          <shield:ChartAxisX CategoricalValuesField="Quarter">  
            </shield:ChartAxisX>  
                 <shield:ChartAxisY>  
                   <Title Text="Quarter Overview"></Title>  
                 </shield:ChartAxisY>  
               </Axes>  
               <DataSeries>  
                 <shield:ChartBarSeries DataFieldY="Sales">  
                   <Settings EnablePointSelection="true" 
			EnableAnimation="true">  
                     <DataPointText BorderWidth="">  
                     </DataPointText>  
                   </Settings>  
                 </shield:ChartBarSeries>  
               </DataSeries>  
               <Legend Align="Center" BorderWidth=""></Legend>  
             </shield:ShieldChart>  
           </ContentTemplate>  
   </asp:UpdatePanel>   

It is wrapped in an update panel, to provide smooth visual updates.

In order to populate the chart control with data, we use the TakeDataSource event handler, in the code-behind of the .aspx file:

protected void ShieldChart1_TakeDataSource(object sender, Shield.Web.UI.ChartTakeDataSourceEventArgs e)  
     {  
       ShieldChart1.DataSource = new object[]   
       {  
         new {Quarter = "Q1", Sales = 312 },   
         new {Quarter = "Q2", Sales = 212 },   
         new {Quarter = "Q3", Sales = 322 },   
         new {Quarter = "Q4", Sales = 128 }  
       };  
     }   

The DataSource property of the control tells the chart what data will be passed to it for visualization. Here we pass a simple object array with sales entry for each quarter. This will represent the chart with the quarterly data. The second, related chart, also added in the .aspx file, looks like this:

<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" 
ChildrenAsTriggers="false">  
     <ContentTemplate>  
       <shield:ShieldChart ID="ShieldChart2" 
OnTakeDataSource="ShieldChart2_TakeDataSource" AutoPostBack="true"  
         OnSelectionChanged="ShieldChart2_SelectionChanged" runat="server" 
Width="463px" Height="331px">  
         <ExportOptions AllowExportToImage="false" AllowPrint="false" />  
         <PrimaryHeader Text="Select a Quarter to show products sales">  
         </PrimaryHeader>  
         <Axes>  
           <shield:ChartAxisY>  
             <Title Text="Break-Down for selected quarter"></Title>  
           </shield:ChartAxisY>  
         </Axes>  
         <DataSeries>  
           <shield:ChartDonutSeries EnableValueXSorting="false" 
CollectionAlias="Q Data" DataFieldY="Data" DataFieldX="Product">  
             <Settings EnablePointSelection="true" 
EnableAnimation="true" AddToLegend="true">  
               <DataPointText BorderWidth="">  
               </DataPointText>  
             </Settings>  
           </shield:ChartDonutSeries>  
         </DataSeries>  
         <Legend Align="Center" BorderWidth=""></Legend>  
       </shield:ShieldChart>  
     </ContentTemplate>  
     <Triggers>  
       <asp:AsyncPostBackTrigger ControlID="ShieldChart1" 
EventName="SelectionChanged" />  
     </Triggers>  
   </asp:UpdatePanel>  
 </div>   

Both the first and the second charts have a selection event handler enabled, in order to allow the re-creation of the related control, since they both have a sub-chart attached to them. The flow of the project allows the end user to select a quarter from among the four quarters visualized in “ShieldChart1”. Then, for this quarter, all available data is displayed in a donut chart, which is hosted in "ShieldChart2". The user can then select a particular category from the donut, which in turn populates the third chart. Its declaration is listed below:

<asp:UpdatePanel ID="UpdatePanel3" runat="server" UpdateMode="Conditional"> 
       <ContentTemplate>  
         <shield:ShieldChart ID="ShieldChart3" runat="server" 
OnTakeDataSource="ShieldChart3_TakeDataSource"  
           Width="905px" Height="280px">  
           <DataSeries>  
             <shield:ChartLineSeries DataFieldY="QuarterSales">  
               <Settings AddToLegend="false">  
                 <DataPointText BorderWidth="">  
                 </DataPointText>  
               </Settings>  
             </shield:ChartLineSeries>  
           </DataSeries>  
           <PrimaryHeader Text="Select a product to show sales details...">  
           </PrimaryHeader>  
           <ExportOptions AllowExportToImage="false" AllowPrint="false" />  
           <Legend Align="Center" BorderWidth=""></Legend>  
         </shield:ShieldChart>  
       </ContentTemplate>  
       <Triggers>  
         <asp:AsyncPostBackTrigger ControlID="ShieldChart2" 
EventName="SelectionChanged" />  
       </Triggers>  
     </asp:UpdatePanel>  

One additional step needs to be taken, in order to allow the re-creation of the sub-charts. This is done on the server, once the selection of the charts is triggered. This cancels out the need to write any client side code. The server side code looks like this: 

protected void ShieldChart1_SelectionChanged(object sender, ChartSelectionChangedEventArgs e)  
 {  
   if (e.Selected)  
   {  
     SelectedQuarter = e.Name;  
     DataPerformance = GetPerformanceData().Where(d => d.Quarter == SelectedQuarter).ToList();  
   }  
   else  
   {  
     DataPerformance = null;  
   }  
   ShieldChart2.DataBind();  
 }  
 protected void ShieldChart2_SelectionChanged(object sender, ChartSelectionChangedEventArgs e)  
 {  
   if (e.Selected)  
   {  
     SalesData = GetSalesDataProducts().Where(s => s.Quarter == SelectedQuarter && s.Product == e.Item.ValueX.ToString()).ToList();  
   }  
   else  
   {  
     SalesData = null;  
   }  
   ShieldChart3.DataBind();  
 }   

This completes our setup, and the sales dashboard is ready for use. Feel free to download the code sample on the top of the article and explore the code for further reference.

Published at DZone with permission of its author, David Johnson.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)