Creating a Graph in ASP.NET with AJAX, HttpHandler and Morris.js Plugin

What is a Graph and Importance of Graph?


Graphical representation is something that can make you understand every statistics without a mathematical calculation. It keeps the ability to represent the facts and figures in such a manner that you need not to give any pressure to your brain for calculations.

Lets take a simple example.

Consider yourself as an owner of a laptop selling company which sells thousands of laptops daily. As you are the owner of the company, you must have to keep track of your business if your sales volume is increasing day by day or decreasing. 

In order to keep track of your sales volume in a certain time period what you have to do ????
Yes, you will collect the facts and figure for a comparison and definitely for this comparison you need to do some calculations blah blah blah blah......

Here comes the concepts of Graph by seeing it only you will get a clear cut idea whether your business is growing or not.

Graph is the concept which will save your time, save the utilization of your brain and keeps you away from headache while analyzing a bunch of data.

So, Being a software developer it becomes an important part of development to get all the reports like user accounts, page hits, sales volumes etc. in a graphical representation, so that it will be very easy to understand what is actually happening in the background, and how the business is getting affected day by day.

Here in this article I will show you how to generate a light weight, nice looking Graph using Jquery and AJAX. If you surf in the internet you will get hundreds of plugins for generating Graphs. 
I will be using  morris.js for generating a nice looking graph. For more details about the plugin please visit their website.



Download Source Code Here
   

Let's Create a Graph using Morris.js in ASP.NET


In this example we will be using AJAX, JQURY along with HttpHandler in ASP.NET. So some basic idea on these topics will be highly appreciated. You can download the above demo project for a quick demo.

Lets do this.

Front End Stuffs:


Add a new webform  to your solution (in visual studio). And add the below scripts to the header section of your page.
<link rel="stylesheet" href="http://cdn.oesmith.co.uk/morris-0.4.3.min.css">
 <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
 <script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
 <script src="http://cdn.oesmith.co.uk/morris-0.4.3.min.js"></script>
Now add a div to the body of your page with an id. Here I have given it an id of  "area-example" and put it blank.
 <div id="area-example"></div>
Ok, now we need to bind that div with our data in order to produce a graph. So here you go.....

Add the below script to the header section and I will explain it line by line.
<script type="text/javascript">
        $(document).ready(function () {

            Morris.Area({
                element: 'area-example',
                data: Graph(),
                xkey: 'label',
                ykeys: ['value'],
                labels: ['value']
            });

        });
    </script>
Here in the above script I am trying to bind the div with a graph by calling the Morris.Area function and passing it some parameters.

For more details about Morris Charts you can visit their web.




Let me explain these parameters here we are passing.
  • element (mandatory) : This is the ID of the container where the graph will be rendered.
  • data (mandatory) : Here you can provide the data to bind your graph. It accepts data in JSON format. like
    [
      { label: '2012-10-01', value: 802 },
      { label: '2012-10-02', value: 783 },
      { label: '2012-10-03', value: 820 },
      { label: '2012-10-04', value: 839 },
      { label: '2012-10-05', value: 792 },
      { label: '2012-10-06', value: 859 },
      { label: '2012-10-07', value: 790 },
    ] 

    Or you can call a function to get data from server side. Here I am using AJAX for getting data from server side through a HTTPHandler.
  • xkeys (mandatory) : A string containing the name of the attribute that contains date (X) values.The date format should be in "YYYY-MM-DD" format.
  • ykeys (mandatory) : A string containing the name of the attribute the value for (Y).
  • labels (mandatory) : A list of strings containing labels for the data series to be plotted (corresponding to the values in the ykeys option).
In our case the data attribute is calling a Javascript function named Graph(). And I am calling a HttpHandler through AJAX. Find the function below.
function Graph() {
            var data = "";

            $.ajax({
                type: 'GET',
                url: "http://localhost:60539/GraphHandler.ashx",
                dataType: 'json',
                async: false,
                contentType: "application/json; charset=utf-8",
                data: { 'GraphName': 'line' },
                success: function (result) {
                    data = result;
                },
                error: function (xhr, status, error) {
                    alert(error);
                }
            });

            return data;
        }
I am passing the HttpHandler url in the url attribute, and I am sending some data to the server of json type. You can find the dataType : 'json' and data: {'GraphName': 'line'} which I will be using in my handler.

And as you can see I am making this AJAX call synchronous by setting async attribute to false because I need the AJAX call to wait till the data was retrieved from the back end otherwise the graph will not be loaded.

* It is not recommended usually to make the AJAX call synchronous.

Once the call is completed and it get some data then inside the success attribute I am setting a variable and then at the end of the method returning it.

You need to put this method in script block we have created just before sometime.

Back End Stuffs:


Once the call is transferred to the handler you get the flexibility to use your coding ability to fetch data from server or whatever you want to do.

Here I will be using two classes named GraphData.cs to and GraphDataList.cs. Find the two classes below.
    public class GraphData
    {
        public string label { get; set; }
        public string value { get; set; }
    }
 
    public class GraphDataList
    {
        public List<GraphData> ListOfGraphData { get; set; }
    }
Find the below function that is responsible for fetching the graph data from the server. Basically this is a DAL function.
     public GraphDataList GetGraphData(string graphName)
        {
            GraphData graphData = null;
            GraphDataList graphDataList = new GraphDataList();
            graphDataList.ListOfGraphData = new List<GraphData>();

            try
            {
                using (var con = new SqlConnection(connectionString))
                {
                    con.Open();

                    SqlCommand cmd = new SqlCommand();
                    SqlDataAdapter SqlDadp = new SqlDataAdapter();
                   
                    cmd.Parameters.Add("@ProgramID", SqlDbType.Int);
                    cmd.Parameters["@ProgramID"].Value = programID;

                    cmd.CommandType = CommandType.StoredProcedure;

                    using (IDataReader dataReader = cmd.ExecuteReader())
                    {
                        while (dataReader.Read())
                        {
                            graphData = new GraphData();

                            graphData.label = Convert.ToString(dataReader["Date"].ToString());
                            graphData.value = Convert.ToString(dataReader["AmountPaid"].ToString());

                            graphDataList.ListOfGraphData.Add(graphData);
                        }
                        dataReader.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.LogError(ex);
            }

            return graphDataList;
        }
As you can see in the this method I am calling a stored procedure and binding the GraphDataList with the returned values. Finally it returns the graphDataList.

Now we need to call this method from ProcessRequest method of the HttpHandler.

Here is the code for ProcessRequest method.
        public void ProcessRequest(HttpContext context)
        {
            System.Collections.Specialized.NameValueCollection forms = context.Request.Form;
            
            string chartName = context.Request["GraphName"];
           
            DataAccessLayer Dal = new DataAccessLayer();

            int programID = 1;

            if (!string.IsNullOrEmpty(chartName))
            {
                GraphDataList graphList = new GraphDataList();

                switch (chartName)
                {
                    case "line":
                        graphList = Dal.GetGraphData(chartName);
                        break;
                    case "donut":
                        graphList = Dal.GetGraphData(chartName);
                        break;
                }

                //oper = null which means its first load.
                var jsonSerializer = new JavaScriptSerializer();
                string data = jsonSerializer.Serialize(graphList.ListOfGraphData);
                context.Response.Write(data);
            }
        }
As you can see I am retrieving the parameter I have passed from AJAX, from the context.Request. Then we are almost done.

Just call the GetGraphData(chartName) with the graph name and hold the returned data in a list, we just created before 2-3 minutes ago.

We are just 1 step away from generating a nice looking graph.

Finally serialize the list with JavaScriptSerializer and parse it back. now you will get a beautiful graphical representation of your data.

Here I have plotted a graph between the time frame and the sales volume of a organization. And the graph looks like below

Graph

Hopefully you got something from this article and demonstration. If you want a complete demo then feel free to download the source code from above link.

If you like the article, a +1 will be very much appreciated, that is present at the top of the Page.




Happy Coding...

9 comments:

  1. Tapan,
    Thanks for the helpful and informative article. Isn't Morris.js Great!!??

    ReplyDelete
  2. Welcome Landon.... Yeha its a cool plugin....

    ReplyDelete
  3. Thanks very much for this! It's been a great help!

    ReplyDelete
    Replies
    1. You welcome.... and keep visiting this site for more articles and info....

      Delete
  4. url: "http://localhost:60539/GraphHandler.ashx",

    GraphHandler what code written it ????????????????

    ReplyDelete
    Replies
    1. Hi, inside the HTTPHandler I am fetching the data source for the graph. Check the method named
      "public void ProcessRequest(HttpContext context)" inside GraphHandler.ashx.cs. For better understanding download the source code and see what happening inside.

      Delete
    2. Thanks, but using a JavascriptSerializer is not a right way for my opinion.

      In fact, there is some JSON library which will be way more powerful and adapted for JSON instead of JavascriptSerializer

      Delete
    3. Thanks for this very helpful information!

      Here some code for whom is interested how to create a chart from a button click event:

      // 1. add the following code inside the 'document ready' part of the script:


      $('#run').on('click', function () { // on click event button 'run'
      $('#graph').html(''); // clear previous chart
      var json = GraphDonut(); // get data for this chart calling function 'GraphDonut'
      // Create new donut chart and bind json response to the data option of this chart (var _chart);
      var _chart = new Morris.Donut({
      element: 'graph',
      data: json,
      xkey: 'label',
      ykeys: ['value'],
      labels: ['value'],
      backgroundColor: '#ccc',
      labelColor: '#060',
      colors: [
      '#0BA462',
      '#39B580',
      '#67C69D',
      '#95D7BB'
      ],
      formatter: function (x) { return x + " Total" }
      });

      });

      }); // end document ready

      // 2. Next create the 'GraphDonut()' function outside the document ready part (this function will be called from the button with ID 'run')


      function GraphDonut() {
      var json = null;
      $.ajax({
      type: 'GET',
      url: "http://localhost:60539/GraphHandler.ashx",
      dataType: 'json',
      async: false,
      contentType: "application/json; charset=utf-8",
      data: { 'GraphName': 'donut' },
      success: function (result) {
      json = result;
      },
      error: function (xhr, status, error) {
      alert(error);
      }
      });
      return json;
      }



      //3. Add an extra div with the id 'graph' to the body of your page:

      id="graph

      //4. And finally the button with id 'run' (already in this project) to which the functions (GraphDonut() & create chart) are assigned to

      Delete
    4. Hi Harmen,

      Thanks for this tip :)

      Delete