Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

JSON Data Visualizer (for Google, Yahoo!, Bing, and Twitter) using jQuery, JavaScript, ASP.NET MVC 2.0

4.83/5 (14 votes)
29 Jun 2010CPOL6 min read 74.1K   898  
This article describes a JSON data visualizer for popular Web Services like Google, Yahoo!, Bing, and Twitter using jQuery, JavaScript, and ASP.NET MVC 2.0.

Introduction

This article describes a JSON data visualizer for popular Web Services like Google, Yahoo!, Bing, and Twitter using jQuery, JavaScript, and ASP.NET MVC 2.0.

Background

Popular Web Services like Google, Yahoo!, Bing, and Twitter return JSON (JavaScript Object Notation) for web applications due to the compact data structure of JSON. When I started developing a mash up application using JSON data, I ran into problems hooking up the data to my web pages because of my lack of understanding of the returned data structure. Hence, I developed this JSON Visualizer, which has been very useful for me to understand the data structure. This analyzer helped me to change the parameters easily and test my REST (Representational State Transfer) calls before designing the application. I hope this would be of similar use to someone.

The data visualizer presents data in the following formats:

  1. RawData option renders raw JSON data returned by a Web Service without any processing.
  2. Table option renders JSON data in a nice table format. I have used a JavaScript program called prettyPrint for JavaScript by James Podesly to render this table data.
  3. Beautify option formats JSON data for printing. For this, I used a JavaScript program called JavaScript unpacker and beautifier by Einar Lielmanis.
  4. Class output option is my own experimental software to traverse the data. For this, I developed a recursive iteration routine inspired by the article: Show Object Properties by Matt Holthe.

Output

The initial page looks like the image shown below. A live demo is available at this site: Json_Demo.

Image 1

When the page gets loaded, the drop down box gets loaded with the search engine names. The parameters also change with the search engine selection. These parameters are hard coded in a JavaScript object, and can be changed easily in code.

The raw data format output is given below. This is sometimes useful, especially when errors are returned and also in debugging this software.

Image 2

The table format output is given below. This is very powerful. Data is represented in a hierarchical format. You can dig through the structure by clicking on the depth reached.

Image 3

The table format with depth expanded output is given below:

Image 4

The beautify view is given below. This is useful when you want to look at the general structure and also when you want to print the results. You have to cut and paste the output to a Word document and print it since I have not included a print option in this version of the software.

Image 5

The class view given below. This I found useful when I wanted to traverse through the array to pick up a particular object.

Image 6

Code Description

Setup

You need Visual Studio 2010 to use this project. You also need some knowledge of jQuery, JavaScript, and MVC 2.0 to follow this discussion.

When you start a new project as an ASP.NET MVC 2.0 Application (in Visual Studio 2010), it creates a home controller with Home and About views. Visual Studio also automatically loads a script folder with jQuery-1.4-1.js. I updated jQuery to version 1.4-2. I also created a custom folder in the Scripts folder to hold unique scripts of this application. The unique scripts are:

  1. beautify.js which was downloaded from http://github.com/einars/js-beautify. This is used to create the printable output.
  2. beautifyresult1.js is used to set up beautify.js.
  3. prettyprint.js from http://github.com/jamespadolsey/prettyPrint.js. This is used for the table output.
  4. BuildClassTree.Js is used for building the class tree.
  5. paramselect1.js takes care of the loading of the selection box, parameters, gets data and displays it.

JSON Controller

The JSON controller gets the data from the Web Service. The code is given below:

C#
public JsonResult JsonData1(string searchengine, string url1, string parameter)
{
    string appid = "";
    switch (searchengine)
    {
        case "Google":
            appid = "";
            break;
        case "Yahoo":
            appid = "Use your appid here";
            break;
        case "Bing":
            appid = "Use your appid here";
            break;
        default:
            break;
    }
    string urselected = url1 + parameter + appid;
    WebClient serviceRequest = new WebClient();
    var JsonResponse = serviceRequest.DownloadString(new Uri(urselected));
    return Json(JsonResponse, JsonRequestBehavior.AllowGet);
}

With this code, we are building a URI using the url1 supplied (which depends on the search engine), app ID, and the parameter. Please note that you have to get your own app ID from Bing and Yahoo!. I have not used the app ID for Google, though they recommend using one. Please also note that the returned data is in JSON format.

JSON View 'Div's

ASP.NET
<div id="controls_div" style="background-color: #FCFCFC">
<select id="select_engine_select" 
    onclick="return select_engine_select_onclick()" 
    style="border: thin solid #000000; width: 108px; background-color: #FCFCFC;" >
</select>
<hr/><b>Parameters</b>
<div id="buildenginediv"></div>
<hr />
<input type="button" class="cssbutton2" id="RawData_button" 
  onclick="Get_Engine_Data('#rawdatadiv')" value="RawData" />
<input type="button" class="cssbutton2" id="table_Button" 
  onclick="Get_Engine_Data('#tabledatadiv')" value="Table" />
<input type="button" class="cssbutton2" id="Beautify_button" 
  onclick="Get_Engine_Data('#beautifydiv')" value="Beautify" />
<input type="button" class="cssbutton2" id="Class_button" 
  onclick="Get_Engine_Data('#JsonListdiv')" value="Class" />
<input type="button" class="cssbutton2" id="Clear_button" 
  onclick="Clear_AllData()" value="Clear Data" />
<br />
<hr />
</div>
<div id="headerdiv"></div>
<div id="JsonListdiv"></div>
<div id ="rawdatadiv"></div>
<div id="tabledatadiv" ></div> 
<div id="animclassdiv"></div> 
<div id="beautifydiv">
<textarea rows="30" cols="80" name="content" id="textdiv" 
style="background-color: #FCFCFC">
</textarea>
</div>
<div id="footerdiv"></div>

The control's DIV has the drop down select box for the select engine and the buttons. I have used a DIV for each type of data presented to keep the view simple. The paramselect1.js JavaScript file loads the selection box, parameters, gets the data, and displays them. Let me describe the various functions.

Search Engine Selection Box

Search_engines1 has the URL engine and the parameter information specific to each search engine. This can be modified to add new search engines or new parameters.

JavaScript
var search_engines1 =
{
    "Google": {
    "urlengine": "http://ajax.googleapis.com/ajax/services/search/web?v=1.0",
    "parameter": { "&q": "pizza 94539" }
}
,
//Yahoo
"Yahoo": {
"urlengine": http://local.yahooapis.com/LocalSearchService/V3/localSearch?output=json",
"parameter: { 
"&query": "pizza",
"&zip": "94539",
"&results": "2"
}
}
,
//Bing
"Bing": {
"urlengine": http://api.search.live.net/json.aspx?sources=web",
"parameter: { 
"&query":"pizza 94539",
"&count":"2"
}
}
,
//Twitter
"Twitter": {
"urlengine": "http://search.twitter.com/search.json?",
"parameter": { 
"&q":"windows phone 7"
}
}

Build_Engine Function

The Build_Engine function loads the select box with the search engine names, and loads the first search engine parameter as the default value.

JavaScript
function Build_Engine() {
    // jQuery.each(search_engines, function (key, val) { recursiveFunction(key, val) });
    $('#buildenginediv').empty();
    var s = $('#select_engine_select')[0]; //Select the select box
    s.length = 0; //empty out the select box
    var iselect = 0;
    $.each(search_engines1, function (key, val) 
    {
        var op = new Option(key); //Create "Option i" with a value of i
        s[iselect] = op; //Add "Option i" at index i
        iselect++;
    }
    )
    // $('#buildenginediv').append( $("#select_engine_select option:selected")[0].value);
}

The Build_Engine1 function populates the parameters depending on the selected search engine.

JavaScript
function Build_Engine1() {
    $('#buildenginediv').empty();
    var params = $("#select_engine_select option:selected")[0].value;
    var parameter_selected = search_engines1[params];
    param_count = 0;
    $.each(parameter_selected['parameter'], function (key, val) {
    $('#buildenginediv').append('<input id="Key' + param_count + 
       '" type="text" readonly="readonly" style="width: 150px" value="' + 
       key + '"/>' + '<input id="Text' + param_count + 
       '" type="text" style="width: 400px" value="' + 
       val + '"/> <br/>');
    param_count++;
    })
}

Get_Engine_Data Function

The Get_Engine_Data(divname) function has the DIV name passed in as a parameter. It uses this along with the selected engine's parameter value to build the request to the JSON Controller and does a jQuery to get the JSON data. Then it calls the displayresult function.

JavaScript
function Get_Engine_Data(divname) {
    var searchengine_selected = 
        $("#select_engine_select option:selected")[0].value;
    var parameter_selected = search_engines1[searchengine_selected];
    var urlengine = parameter_selected["urlengine"];
    var param1 = '';
    for (var iparamcount = 0; iparamcount < param_count; iparamcount++) {
        var textboxid = '#Text' + iparamcount;
        var keyid = '#Key' + iparamcount;
        param1 += $(keyid).val() + '=' + $(textboxid).val();
    }
    Clear_AllData();
    var selecteditems = { "searchengine": searchengine_selected, 
             "parameter": param1, "url1": urlengine };
    jQuery.getJSON('/Json/JsonData1', selecteditems, function (result) {
    displayresult(result, divname, selecteditems);
    })
}

displayresult Function

displayresult(result, divname, selecteditems) uses the JSON result, DIV name and the selected items to build the view.

  1. If raw data is requested, it is appended to the rawdatadiv.
  2. If table data is requested, we parse the JSON using jQuery parseJSON and call prettyPrint. The resulting table is appended to the tablediv.
  3. If beautify result is requested, we call the beautifyresult function. The beautifyresult function sets the parameters required for the beautify.js function, calls it, and adds it to the TextArea. We also need to show the beautifydiv because it has the text area to which the beautify data is output.
  4. If class result is requested, we do a parseJSON on the result and call the BuildTree function which is described later.
JavaScript
function displayresult(result, divname, selecteditems) {
    $('#headerdiv').append("<hr/>" + "Results From: " + 
       selecteditems["searchengine"] + " : " + " Parameters: " + 
       selecteditems["url1"] + selecteditems["parameter"] + "<hr/>");
    switch (divname) {
        case '#rawdatadiv':
            $(divname).append(result);
            break;
        case '#tabledatadiv':
            data = $.parseJSON(result);
            var tbl = prettyPrint(data);
            $(divname).append(tbl);
            break;
        case '#beautifydiv':
            $(divname).show();
            beautifyresult(result);
            break;
        case '#JsonListdiv':
            result1 = '{"datamade":' + result + '}';
            data = $.parseJSON(result1);
            folderarray = new Array();
            BuildTree(data, "datamade", 0);
            break;
        default:
            break;
    }
    $('#footerdiv').append("<hr/>" + "done" + "<hr/>");
}

Buildtree Function

The BuildTree function takes three parameters and has recursion. Before calling it, you also have to set up an array called folderarray. The function looks at the object and depending on whether it is the parent or object or array, builds each item and appends it to JsonListdiv. The levelcount keeps track of the level, and folderarray keeps track of the name of the parent.

JavaScript
function BuildTree(obj, parent, levelcount) {
    // Go through all the properties of the passed-in object
    var space = new String("   ");
    var space1 = "";
    var prefix = "";
    var parentprint = "";
    //Setting level counter
    if (parent != undefined) {
        for (var ispace = 0; ispace < levelcount; ispace++) {
            var space1 = space1 + space;
        }
        if (typeof obj == "object") {
            levelcount++;
        }
        else {
            levelcount = 0;
        }
    }
    //start analyzing the object
    for (var i in obj) {
        // if a parent (2nd parameter) was passed in, then use that to 
        // build the message. Message includes i (the object's property name) 
        // then the object's property value on a new line
        var msgi;
        var msgobj;
        if (parent) { msgi = i; msgobj = obj[i]; } else { msgi = msgobj = ""; };
        // If this property (i) is an object, then recursively process the object
        //had to add null test because Google has some null data!
        if ((typeof obj[i] == "object") && (obj[i] != null)) {
            if (parent) {
                if ($.isArray(obj)) {
                    folderarray[levelcount] = '[' + i + '].';
                }
                //not Array
                else {
                    folderarray[levelcount] = i +'.';
                }
                //
                BuildTree(obj[i], parent + "." + i, levelcount);
            }
            //not parent 
            else {
                BuildTree(obj[i], i, levelcount);
            }
        }
        // not object
        else {
            parentfolderstring = "";
            for (var ifolder = 2; ifolder < levelcount; ifolder++) 
            {
                parentfolderstring += folderarray[ifolder];
            };
            // var stringtoreplace ='.[';
            var parentfolderstring1 = parentfolderstring.replace(/\.\[/g, "[");
            //for i in obj continues
            var parentitem = '<font size="2" color="black"><B>' + 
                             space1 + parentfolderstring1;
            var childitem = msgi + ': </B></font>' + 
                '<font size="2" color="blue">' + 
                msgobj + '</B></font>';
            $('#JsonListdiv').append(parentitem + childitem + '<br/>');
        }
        //end of for i in obj loop
    }
}

Points of Interest

JSON format is a compact format to get data from various Web Services. The JSON Visualizer described here has been useful to me for understanding the data structure to develop my projects. I hope it will be useful to you too.

References

  1. "prettyPrint" for JavaScript by James Podesly for table data visualization.
  2. JavaScript unpacker and beautifier by Einar Lielmanis for Beautify format.
  3. Show Object Properties by Matt Holthe for understanding recursive scanning of JavaScript objects.
  4. http://apiwiki.twitter.com/Twitter-Search-API-Method%3A-search for Twitter search.
  5. http://developer.yahoo.com/common/json.html#overview about Yahoo! JSON.
  6. http://developer.yahoo.com/search/local/V3/localSearch.html for Yahoo! search.
  7. http://msdn.microsoft.com/en-us/library/dd251056.aspx about Bing.
  8. http://code.google.com/apis/ajaxfeeds/documentation/ for Google.

History

This is the first version of this article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)