In one of my previous posts, I’ve explained how to easily integrate Google charts with ASP.NET application. Here is one more example related to that subject, having some (for me) very cool data filtering features.
Note: For the sake of simplicity, I’ve removed jQuery and AJAX code, so all the processing and chart drawing happens on page load.
Here is C# code:
using System; using System.Collections.Generic; using System.Web.Services; using System.Web.Script.Serialization; public partial class Default2 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { List<DataItem> dataList = new List<DataItem>(); dataList.Add(new DataItem("Column 1", 100, "Male", 25)); dataList.Add(new DataItem("Column 2", 150, "Male", 37)); dataList.Add(new DataItem("Column 3", 250, "Female", 25)); dataList.Add(new DataItem("Column 4", 400, "Female", 35)); dataList.Add(new DataItem("Column 5", 450, "Male", 35)); dataList.Add(new DataItem("Column 6", 460, "Female", 26)); dataList.Add(new DataItem("Column 7", 470, "Female", 30)); dataList.Add(new DataItem("Column 8", 500, "Male", 31)); dataList.Add(new DataItem("Column 9", 550, "Male", 30)); dataList.Add(new DataItem("Column 10", 600, "Female", 33)); JavaScriptSerializer jss = new JavaScriptSerializer(); ClientScript.RegisterStartupScript(this.GetType(), "TestInitPageScript", string.Format("<script type=\"text/javascript\">drawVisualization({0},'{1}','{2}','{3}');</script>", jss.Serialize(dataList), "Text Example", "Name,Value,Gender,Age", "--Choose--")); } } } public class DataItem { #region Internal Members private string _ColumnName = ""; private double _Value1 = 0; private string _Value2 = null; private int _Value3 = 0; #endregion #region Public Properties public string ColumnName { get { return _ColumnName; } set { _ColumnName = value; } } public double Value1 { get { return _Value1; } set { _Value1 = value; } } public string Value2 { get { return _Value2; } set { _Value2 = value; } } public int Value3 { get { return _Value3; } set { _Value3 = value; } } #endregion #region Constructors public DataItem(string columnName, double value1, string value2, int value3) { _ColumnName = columnName; _Value1 = value1; _Value2 = value2; _Value3 = value3; } #endregion }
ColumnName is the name of a specific item, for example person’s name, or name of the product our company makes. Values(Value1, Value2, Value3) closely represent the item, e.g. person’s age, salary, number of products sold etc. In a project I’m currently working on, I use Google chart to show which products are popular among different age/sex groups.
On page load, the data is compiled into JSON string using JavaScriptSerializer(line 29), and then the script is registered using ClientScript.RegisterStartupScript. This way, the script will be executed when loaded on client. Some additional information is also provided, including chart title(line 30), data column names(line 31), neutral value text in the category dropdown list(line 32).
ASPX & javaScript:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"> <title>Google Charts Example</title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" type="text/javascript"></script> <script type="text/javascript" src="//www.google.com/jsapi"></script> <script type="text/javascript"> google.load('visualization', '1.1', { packages: ['controls'] }); </script> <script type="text/javascript"> function drawVisualization(dataValues, chartTitle, columnNames, categoryCaption) { if (dataValues.length < 1) return; var data = new google.visualization.DataTable(); data.addColumn('string', columnNames.split(',')[0]); data.addColumn('number', columnNames.split(',')[1]); data.addColumn('string', columnNames.split(',')[2]); data.addColumn('number', columnNames.split(',')[3]); for (var i = 0; i < dataValues.length; i++) { data.addRow([dataValues[i].ColumnName, dataValues[i].Value1, dataValues[i].Value2, dataValues[i].Value3]); } // Define a category picker control for the Gender column var categoryPicker = new google.visualization.ControlWrapper({ 'controlType': 'CategoryFilter', 'containerId': 'CategoryPickerContainer', 'options': { 'filterColumnLabel': columnNames.split(',')[2], 'ui': { 'labelStacking': 'horizontal', 'allowTyping': false, 'allowMultiple': false, 'caption': categoryCaption, 'label': columnNames.split(',')[2] } } }); // Define a Pie chart var pie = new google.visualization.ChartWrapper({ 'chartType': 'PieChart', 'containerId': 'PieChartContainer', 'options': { 'width': 600, 'height': 350, 'legend': 'right', 'title': chartTitle, 'chartArea': { 'left': 50, 'top': 15, 'right': 0, 'bottom': 0 }, 'pieSliceText': 'label', 'tooltip': { 'text': 'percentage' } }, 'view': { 'columns': [0, 1] } }); // Define a table var table = new google.visualization.ChartWrapper({ 'chartType': 'Table', 'containerId': 'TableContainer', 'options': { 'width': '300px' } }); // Define a slider control for the Age column. var slider = new google.visualization.ControlWrapper({ 'controlType': 'NumberRangeFilter', 'containerId': 'SliderContainer', 'options': { 'filterColumnLabel': columnNames.split(',')[3], 'ui': { 'labelStacking': 'horizontal' } } }); new google.visualization.Dashboard(document.getElementById('PieChartExample')).bind([categoryPicker,slider], [pie, table]).draw(data); } </script> </head> <body> <form id="form1" runat="server"> <div id="PieChartExample"> <table> <tr style='vertical-align: top'> <td> <div id="CategoryPickerContainer"></div> <div id="SliderContainer"></div> </td> </tr> <tr> <td > <div style="float: left;" id="PieChartContainer"></div> <div style="float: left;" id="TableContainer"></div> </td> </tr> </table> </div> </form> </body> </html>
Notice that controls package is used here, instead of corechart, that was used in previous example.
drawVisualization is the function where all the magic happens.
Two classes are important in this example: ControlWrapper and ChartWrapper. ControlWrapper is a wrapper around a JSON representation of a configured control instance – in this case, the “filtering” controls: CategoryFilter (for choosing sex) and NumberRangeFilter (slider, for defining age range).
Finally, new instance od Dashboard class is created, and its bind method invoked.
(I strongly recommend experimenting in Code Playground, it’s very useful!)
As a result, we get something like this:
When an item is selected in gender drop down list, or the age range is changed, both pie chart and table values are filtered. It all happens on client and it’s very fast. Also, the design is lite and very Google-like, so users really like it!