Skip to main content

Create a slick mashup with Google Charts, Ajax, Project Zero, and WebSphere sMash

Zero's integration of Groovy scripting simplifies the process

Dan Jemiolo (danjemiolo@us.ibm.com), Advisory Software Engineer, IBM 
Dan Jemiolo is an Advisory Software Engineer on IBM's Project Zero team in Research Triangle Park, NC. He is currently working on reusable components for the Zero platform and its service catalog. His previous work includes the design and development of Apache Muse 2.0 and participation in OASIS Web services standards bodies. Dan came to IBM after earning his Master of Science degree in Computer Science from Rensselaer Polytechnic Institute.

Summary:  Google Charts is a neat service that lets developers generate charts and graphs using a simple HTTP GET request. Because all of its features have been made available through HTTP, this service can be easily integrated into Web applications built with Project Zero. This article gives you a demonstration of Groovy scripts that let you use Google Charts without having to construct its cumbersome HTTP URLs. You'll create a helpful Web interface that lets users build charts and graphs visually. Try the sample project that shows how easy it is to create mashup applications using the Zero platform.

Date:  25 Mar 2008
Level:  Introductory
Activity:  4110 views

Editor's note: IBM® WebSphere® sMash and IBM WebSphere sMash Developer Edition are based on the highly acclaimed Project Zero incubator project. Project Zero is the development community for WebSphere sMash and will continue to offer developers a cost-free platform for developing applications with the latest builds, the latest features, and the support of the community.

Before you get started

This article assumes that you have downloaded Project Zero M4 and used it to create one or more applications. You will need a basic understanding of Groovy scripting, Ajax techniques, and HTML, all of which are demonstrated in Zero's tutorials and samples. For links to introductory material on Project Zero and related technologies, check out the Resources section.

The Project Zero community
Take a stroll around the Project Zero Web site and see how Project Zero provides a powerfulbut radically simpledevelopment and execution platform for modern Web applications. The active community discusses project development, provides help to developers, and wants to hear your ideas!

Introduction: The Google Charts API

Google Charts is a neat service that lets developers generate charts and graphs using a simple HTTP GET request. Clients send requests to http://chart.apis.google.com/chart along with one or more query parameters indicating the type of chart they want; a complete list of these query parameters is provided in the Google Charts API documentation (see Resources). Currently, the API allows for control of a broad range of attributes, including a chart's title, layout, colors, axes, data, and legends. Figure 1 is a simple example of the API in action.


Figure 1. Sample chart: (Source: Google.com)
Figure 1. Sample Chart

If you right-click on the image and select Properties, you can see the URL that was used to generate the chart. I will cover the specific roles of the query string parameters in future sections. The important thing to take away from this inspection is that the query parameter names are rather trite, and when you combine them all into one URL, the result is long and cumbersome. In the next section, you'll start to encapsulate these complex URLs with some Groovy code running on Project Zero.

Exposing a more RESTful charts API

It's nice to be able to create charts in a browser using only the address bar, but as noted in the Introduction, this could actually be quite tedious. Being able to create a chart in the address bar might seem useful from a non-developer's perspective, but once beyond the point of simple examples, the URLs are simply too long. A better design approach would be to expose chart creation with HTTP POST and JSON (for developers) and provide a graphical interface on top of it (for non-developers). This would make it easier for both sets of users to debug problems with their chart layout or data. You can implement this approach with Project Zero by encapsulating chart URL creation in a Groovy script and then making an Ajax-based Web interface that invokes that script via HTTP.

Creating the sample projects

To show off your work, you will need to create two projects: one to hold your Groovy wrapper code and one to hold your sample Ajax UI. You should create two Zero applications—one named zero.charts and one named chart.maker —to hold the Groovy code and Ajax code, respectively. The two projects were kept separate so that the Groovy code can be easily reused by different applications. You'll start your work in the zero.charts application.

Generating chart URLs in Groovy

The first step towards simplifying chart creation with Groovy is to define the data structure(s) used to specify chart details. Instead of the original parameter names used by Google Charts, you will define a more verbose data structure with JSON; the use of JSON means you can rely on normal data types (for example, an actual array of integers instead of a string with serialized integers delimited by commas) and make it easier to see what values are being passed to the chart generator. Listing 1 shows the data structure you'll use to communicate between Ajax clients and your Groovy script.


Listing 1. Sample chart definition with JSON
                
    
    {
        title: "Sales for 1H 2008",
        type: "bvg",
        height: 300,
        width: 300,
        data: [34, 21, 28, 19, 48, 40],
        xaxis: ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
        yaxis: [0, 40]
    }
      

A JSON object like the one shown in Listing 1 can be inspected during development time using tools like FireBug or simple JavaScript alerts. This will be much easier to debug and validate than a long string such as http://chart.apis.google.com/chart?cht=bvg&chs=500x600&chtt=Sales%20for%201Q%202008&chd=t:134,219,188&chxt=x,y&chxl=0:|Jan|Feb|Mar|1:||300.

Of course, when all is said and done, you still need to send such a URL to Google's server to get the desired chart. To do that, you will write a simple Groovy method that copies the field values in a JSON object into a chart URL. With the help of Groovy's GString type, you can make the URL string on one line, without creating a java.lang.StringBuilder and appending values piece by piece. The code for this Groovy method is shown in Listing 2.


Listing 2. Groovy code for chart URL construction
                
      
    def create(chart)
    {
        return "http://chart.apis.google.com/chart?chxt=x,y" + 
               "&cht=${chart.type}&chs=${chart.width}x${chart.height}" + 
               "&chtt=${chart.title}&chd=t:${chart.data.join(',')}" + 
               "&chxl=0:|${chart.xaxis.join('|')}|1:|${chart.yaxis.join('|')}";
    }      
      

For the most part, the code in Listing 2 takes values directly from a JSON object and embeds them (using the $ syntax) in the URL. The only places where this is not the case is where the JSON fields are arrays, which must have their values concatenated into a single string. You can do this easily with the join() method.

You should copy the code from Listing 2 into a file named /zero.charts/app/scripts/charts.groovy. By putting the code in the /app/scripts directory, you are making it available to all other Groovy scripts in the application, as well as to any applications that include zero.charts in their list of dependencies. The final step towards making the code easily reusable is to create a Groovy binding for it; this will allow developers to invoke the create() method from their code directly without using Zero's more generic invokeMethod() . To add the Groovy binding, copy the Java™ class definition in Listing 3 into the /zero.charts/java directory. The line in bold is what developers would have to type if you did not provide this binding.


Listing 3. Groovy bindings for charts.groovy
                

    package zero.charts;

    import java.io.FileNotFoundException;
    import java.util.Map;

    import org.codehaus.groovy.runtime.MethodClosure;

    import zero.core.groovysupport.bindings.InvokeBindings;

    public class ChartsBindings extends InvokeBindings
    {
        public void addVariables(Map<String, Object> variables)
        {
            super.addVariables(variables);
            variables.put("create", new MethodClosure(this, "create"));
        }
        
        public Object create(Map<String, Object> chart) 
            throws FileNotFoundException, NoSuchMethodException
        {
            return invokeMethod("charts.groovy", "create", new Object[]{ chart });
        }
    }
      

Before we move on, take note that the type of the parameter that you're passing to create() in Listing 3 is a java.util.Map. In Zero, JSON objects and Maps are the same thing. All of Zero's I/O APIs know how to serialize a Map to and from JSON when appropriate, so you don't need to learn a special API just to manipulate JSON objects.

As soon as the Java class from Listing 3 is in place, you just have to let Zero know it exists by registering it in the configuration file. Listing 4 has the text that must be added to /zero.charts/config/zero.config to ensure that your Groovy binding works and calls to create() are resolved properly.


Listing 4. Configuration for Groovy binding
                
    
    /config/bindings/.groovy += ["zero.charts.ChartsBindings"]
      

Request charts through HTTP POST

Now that you have your URL construction code in place, you just need to expose it with a RESTful API. You will do that by creating a RESTful resource type called charts and using the HTTP POST method to accept chart specifications (in JSON) and return chart URLs. This behavior is slightly different than what is normally implemented in a RESTful application. Normally, an HTTP POST results in the execution of code that creates a resource in the same domain as the request URI and returns a URI for that new resource. You will be "creating" a resource by constructing a URI that points to the Google Charts service, and when clients follow that URI, they will get their chart. Thus, the only thing that is really created and returned by your service is a chart URI in the Location header of the HTTP response.

Listing 5 has the Groovy code for the charts resource. Its only HTTP method is POST, which is implemented in the onCreate() method. You should copy this code into a file named /zero.charts/app/resources/charts.groovy.


Listing 5. REST API for chart creation
                
    
    import zero.json.Json;
    
    /**
     *
     * @success 201 Returns the URI for the desired chart in the Location header.
     * @error 500 The chart definition in the request body was not valid JSON.
     * @format application/json
     *
     */
    def onCreate()
    {
    	def chart = Json.decode(request.input[]);
    	
    	def chartImageURL = create(chart);
    	
    	request.headers.out.Location = chartImageURL;
    	request.status = 201;
    }
      

Before we move on to the user interface, take a moment to test the REST API using the RESTdoc test interface. Start the zero.charts application (zero run) and go to http://localhost:8080/resources/docs/charts in your Web browser. You will see that the charts resource has one method (POST), and if you click on it, you will be presented with a test form (see Figure 2). Copy the JSON data from Listing 1 into the request body and click Send. The response you see should include a Location header that has a Google Charts URI.


Figure 2. RESTdoc test form for chart creation
Figure 2. RESTdoc test form for chart creation

With the REST API in place, you're now ready to use it in an application. The next section will show how to use Ajax to create a visual chart builder.

Designing a more helpful interface

Your REST API might make it easier for developers to generate charts, but that doesn't help the 99% of computer users who don't code but who occasionally create charts and graphs for their documents and presentations. For those users, you can make a simple Web-based chart builder with an HTML form, a little JavaScript, and the simplest of Ajax APIs, XMLHttpRequest. Figure 3 shows what the end result will be: One side of the Web page allows the user to enter the chart description while the other shows the generated chart.


Figure 3. Web interface for chart generation
Figure 3. Web Interface for Chart Generation

To get started on the user interface, you must first create a dependency between the chart.maker application and the zero.charts application. You can do this by adding zero:zero.charts to /chart.maker/config/ivy.xml. The next two sections will show the most important parts of the markup and code that are required for the interface. You can see the complete markup and code by downloading the sample projects included with this article and looking at the chart.maker project.

Mapping user input to API input

As you can see from Figure 3, the form needed to get the user's chart specification is fairly simple. With the exception of one input value, everything on the form can be converted into the required JSON format rather easily. The only input that requires an extra step is the chart type, which is represented by the Google Charts API using two- or three-letter abbreviations. The form shows the full description of the chart types (Line Graph, Bar Chart - Vertical, and Bar Chart - Horizontal), so your HTML drop-down menu needs to map between these descriptions and the abbreviations (lc, bvg, and bhg, respectively). Listing 6 shows the definition of the HTML drop-down menu that you need; you can see the chart type codes in bold. All of the other form inputs are simple text boxes (<input type="text"/>)


Listing 6. HTML drop-down menu for chart types
                
      
    <select id="chartType">
      <option value="lc">Line Graph</option>
      <option value="bvg">Bar Graph - Vertical</option>
      <option value="bhg">Bar Graph - Horizontal</option>
    </select>   
      

In addition to the drop-down menu markup, some code is also provided to retrieve the selected value from the menu for those that aren't as familiar with this control. Unlike simple text boxes, you can't just read the value property of the control—you must iterate over the drop-down menu's options until you find the one that is currently selected. Listing 7 has the code that you'll need to do this.


Listing 7. JavaScript for finding selected chart type
                
    
    function getSelection(elementName)
    {
        var select = document.getElementById(elementName);
        
        for (var i = 0; i < select.options.length; i++)
            if (select.options[i].selected)
                return select.options[i].value;
        
        return null;
    }
      

Another important UI element is the Create It! button that appears at the bottom of the form. Rather than have this button cause a form submission, you are going to link it to a JavaScript function that makes an Ajax request to your REST API. To do this, you just need to add a JavaScript function call to the button's onClick event. Listing 8 shows the button click linked to a function named createChart(), which you will implement in the next section.


Listing 8. Initiating chart creation with JavaScript
                
    
    <input type="button" value="Create It!" onClick="createChart();"/>
    

The last UI element to cover in detail is the image that shows the generated charts. Listing 9 shows how to write an HTML <img/> tag that is hidden when the page loads. You will use JavaScript to set the source of the tag to the generated chart's URL and then make it visible.


Listing 9. HTML image for chart display
                
    
    <img id="chartImage" style="display:none;" src=""/>
    

You should look at the /public/index.html file in the chart.maker sample project to see all of these pieces of markup and code together. The next section will cover the Ajax-oriented JavaScript (also included in the file) that manipulates the UI elements to show the charts that reflect the user's input.

Displaying generated charts with Ajax

Interacting with your REST API is a matter of implementing the createCharts() function so that it reads all the form input values, packages them in a JSON object, and sends that JSON object as part of an HTTP POST request to your charts resource. Once the HTTP POST request is complete, you will read the chart URL from the Location response header and (re)set the source of the chart image. Listing 10 shows the code to do just that.


Listing 10. Chart creation and display with Ajax
                
    
    function getHttpClient()
    {
        var hasXHR = window.XMLHttpRequest;
    	return hasXHR ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
    }

    function createChart()
    {
        // step 1
    	var chart = {
    		title: getValue("chartTitle"),
    		type: getSelection("chartType"),
    		height: getValue("chartHeight"),
    		width: getValue("chartWidth"),
    		data: getValues("chartData"),
    		xaxis: getValues("xaxis"),
    		yaxis: getValues("yaxis")
    	};
        
        // step 2
    	var http = getHttpClient();
    	http.open("POST", "/resources/charts", true);
    	
        // step 3
    	http.onreadystatechange = function() {
    		if (http.readyState != 4)
    			return;
    		
    		var chartImage = document.getElementById("chartImage");
    		chartImage.src = http.getResponseHeader("Location");
    		chartImage.style.display = "block";
    	}
    	
        // step 4
    	http.send(JSON.stringify(chart));
    }
    

Let's walk through this code step-by-step:

The first thing that you do in createCharts() is to create a JSON object with the proper name-value pairs. The getValue(s) methods are simple utilities similar to the getSelection() method in Listing 7. Their implementations are rather trivial, and you can see them by looking through the sample project. The important thing to note here is that the field names match what is expected by the /app/scripts/charts.groovy file and the values are in the proper format.

The second step is to create an XMLHttpRequest object and start an HTTP POST request to /resources/charts. The getHttpClient() method hides the conditionals that make sure to instantiate the right class for the right Web browser.

The third step is to define what happens after the request is sent and the response is received. In this case, you will take the value of the Location header and use it to set the value of chartImage.src; you then alter the chartImage style so that it is no longer hidden from the user.

The last step is to send the HTTP POST request. This involves converting the JSON object into a string that can be put in the HTTP POST request body. Because there is no standard JSON-to-string API, an open source library from http://json.org has been used. The JSON.stringify() API call that you see at the end of createChart() is defined in a file called json2.js, which can be obtained from http://www.json.org/json2.js. You should download this JavaScript library from http://json.org and add it to the /chart.maker/public directory. Once the library is in place, the last line of createCharts() will run without issues.

Conclusion

You have seen how to create a slick mashup application and, in the process, make the Google Charts API more easily reusable across your Zero applications. The sample Ajax interface only touched on the basic features that are possible in a visual chart builder, but your server-side code can support any other features that you want to add on. Once again, Zero's integration of Groovy scripting has proven to be a huge time saver when it comes to putting RESTful APIs in front of valuable services and data.



Download

DescriptionNameSizeDownload method
Sample application for this articlezero-chart-maker.zip7KB HTTP

Information about download methods


Resources

Learn

  • Learn what the Google Charts API has to offer.

  • Need an introduction to Project Zero? Take a look at "Get started with Project Zero and PHP" (developerWorks, updated January 2008).

  • The developerWorks Ajax resource center is packed with tools, code, and information to get you started developing slick Ajax applications today.

  • With Web 2.0 being a hot area within development circles, you'll find an ever-growing collection of resources in the Web development zone.

  • Need to get up to speed on PHP? Take a look at our PHP area.

  • The developerWorks Project Zero space is packed with resources to get you started developing with Project Zero now.

  • You'll find a nicely growing library of Project Zero content here on developerWorks.

Get products and technologies

  • Download Project Zero M4 to re-create the projects illustrated in this article.

Discuss

About the author

Dan Jemiolo

Dan Jemiolo is an Advisory Software Engineer on IBM's Project Zero team in Research Triangle Park, NC. He is currently working on reusable components for the Zero platform and its service catalog. His previous work includes the design and development of Apache Muse 2.0 and participation in OASIS Web services standards bodies. Dan came to IBM after earning his Master of Science degree in Computer Science from Rensselaer Polytechnic Institute.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Web development, Sample IT projects, WebSphere
ArticleID=297210
ArticleTitle=Create a slick mashup with Google Charts, Ajax, Project Zero, and WebSphere sMash
publish-date=03252008
author1-email=danjemiolo@us.ibm.com
author1-email-cc=ruterbo@us.ibm.com

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers