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. Another important objective is the intuitive layout and user interface, to allow the end user easy navigation through the data. To achieve the task a hand, I am using related chart components, which offer all of the required functionality. The sample uses ASP.NET chart from ShieldUI , which is freely available from their site.
Download Sample
The layout works as follows. Initially, only a grid is populated, which represents some companies, downloaded from a local json file. Upon selection of an item in the grid, or a company, the first chart, which is a bar chart, is rendered and populated with data. This is the "quarters" chart and represent a graph for the quarterly sales of a company. Each bar represents a separate quarter from a sales report. Clicking, or selecting a bar from the first chart populates the second chart - which represents the sales for a particular quarter, broken down by product category. Selecting a piece of the donut chart, or a category, populates the third chart, which represents the sales for this particular category during this quarter.
To keep things simple, some of the data is random.
The layout works as follows. Initially, only a grid is populated, which represents some companies, downloaded from a local json file. Upon selection of an item in the grid, or a company, the first chart, which is a bar chart, is rendered and populated with data. This is the "quarters" chart and represent a graph for the quarterly sales of a company. Each bar represents a separate quarter from a sales report. Clicking, or selecting a bar from the first chart populates the second chart - which represents the sales for a particular quarter, broken down by product category. Selecting a piece of the donut chart, or a category, populates the third chart, which represents the sales for this particular category during this quarter.
To keep things simple, some of the data is random.
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 runat="server">
    <title></title>
    <link rel="stylesheet" type="text/css" href="//www.shieldui.com/shared/components/latest/css/shieldui-all.min.css" />
    <link id="gridcss" rel="stylesheet" type="text/css" href="//www.shieldui.com/shared/components/latest/css/light/all.min.css" />
    <script type="text/javascript" src="//www.shieldui.com/shared/components/latest/js/jquery-1.10.2.min.js"></script>
    <script type="text/javascript" src="//www.shieldui.com/shared/components/latest/js/shieldui-all.min.js"></script>
        
    <asp:ContentPlaceHolder ID="HeadContent" runat="server">
    </asp:ContentPlaceHolder>
</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, as well as a grid, to trigger the sub-charts. First, we take 
care of the grid control.  First, we add a div, which will host the 
control on the aspx page. It may look something like this: 
<div id="gridcontainer" style="width: 400px; height: 357px; top: 55px; left: 25px;">
</div> 
The
 next step is to add the declaration of the js code, to initialize the 
grid.  This is a client-side component, and its initialization is listed
 below: 
  <script src="Data/gridData.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#gridcontainer").shieldGrid({
                dataSource: {
                    data: gridData
                },
                sorting: {
                    multiple: true
                },
                paging: {
                    pageSize: 9,
                    pageLinksCount: 5,
                     messages: 
                     {
                            infoBarTemplate: ""                   
                     }
                },
                events: {
                    selectionChanged: onSelectedChanged,
                },
                selection:
                {
                    type: "row",
                    multiple: false,
                    toggle: false
                },
                columns: [
            { field: "company", title: "Company", width: "110px" },
            { field: "email", title: "Email Address" }
            ]
            });
        });
        function onSelectedChanged(e) {
           __doPostBack('UpdatePanel2', 'gridTrigger');
        }
            
    </script> 
This
 declaration is pretty straightforward. It declares the pagesize and 
allows selection. Selection triggers a client-side event, which does a 
postback. The postback, in turn, populates or re-populates the chart 
controls.  
The
 next step is to setup the first chart in 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. This 
eliminates any flicker, when we are recreating the controls - each 
sub-chart will be recreated upon selection of the master chart. 
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:
<div id="container2" style="width: 490px; height: 340px; margin: auto; top: 5px; left: 5px; position: inherit;">
    <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: 
<div id="container3_box" style="width: 925px; height: 300px; border: 2px solid #40B3DF; margin: auto; top: 420px; left: 25px; position: absolute;">
    <div id="container3" style="width: 890px; height: 290px; margin: auto; top: 5px; left: 5px; position: inherit;">
        <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>
    </div>
</div>
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();
}
The
 "GetPerformance" and "GetSalesDataProducts" methods return data, which 
is filtered on quarter and product. This applies the selection made by 
the user. Subsequent to this, once we have determined what data will be 
passed to the chart control, we call the DataBind method. It applies the
 new data to the control and renders the result.
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.

TakeDataSource event handler, in the code-behind of the .aspx file: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: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: 
Няма коментари:
Публикуване на коментар