IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Web development  >

使用 Google Charts、Ajax 和 Project Zero(WebSphere sMash)创建精巧的 mashup

Zero 通过集成 Groovy 脚本编制简化创建过程

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

样例代码

英文原文

英文原文


级别: 初级

Dan Jemiolo (danjemiolo@us.ibm.com), 顾问软件工程师, IBM

2008 年 6 月 02 日

Google Charts 是一个非常出色的服务,它让开发人员可以使用简单的 HTTP GET 请求来生成图形和图表。由于它的所有特性都可以通过 HTTP 获得,因此该服务很容易集成到用 Project Zero 构建的 Web 应用程序中。本文演示一些 Groovy 脚本,这些脚本让您不必构造繁琐的 HTTP URL 就可以使用 Google Charts。您将创建一个 Web 界面,该界面使用户可以可视化地构建图形和图表。尝试一下示例项目,看看使用 Zero 平台创建 mashup 应用程序是多么容易。

开始之前

本文假设您已经下载了 Project Zero M4,并使用它创建过一个或多个应用程序。您需要对 Groovy 脚本编制、Ajax 技术和 HTML 有基本的理解,这些内容可以通过 Zero 的教程和示例获得。要获得关于 Project Zero 和相关技术的初级读物,请参阅 参考资料 小节中的链接。

Project Zero 资源中心和社区

访问 Project Zero 资源中心 ,这里汇集了与 Project Zero 相关的技术资源,包括入门教程、开发示例、特性简介和相关下载等。

访问 Project Zero Web 站点 ,了解 Project Zero 如何为现代 Web 应用程序提供一个强大 — 但是极其简单 — 的开发和执行平台。

活跃的 Project Zero 社区 讨论项目开发,为开发人员提供帮助,并期待您的加入!

简介:Google Charts API

Google Charts 是一个非常出色的服务,它让开发人员可以使用简单的 HTTP GET 请求来生成图形和图表。客户机发送请求到 http://chart.apis.google.com/chart,同时发送的还有一个或多个查询参数,表明需要的图表的类型;这些查询参数的完整列表可在 Google Charts API 文档中找到(参见 参考资料)。目前,该 API 允许对很多属性进行控制,包括图表的标题、布局、颜色、轴线、数据和说明。图 1 是使用该 API 的一个简单的例子。


图 1. 示例图表:(来源:Google.com)
图 1. 示例图表

如果在图像上单击右键并选择 Properties,就可以看到用于生成该图表的 URL。在后面的小节中我将谈到查询字符串参数的具体作用。但是,查询参数的名称相当老套,在将它们组合到一个 URL 时,得到的 URL 冗长繁琐。在下一节中,您将开始使用 Project Zero 上运行的 Groovy 代码来封装这些复杂的 URL。

公开更加 RESTful 的图表 API

能够在浏览器中仅仅通过地址栏创建图表当然很好,但是正如 简介 小节中所述,这样做实际上是很繁琐的。能够在地址栏中创建图表,对于非开发人员来说这看上去很有用,但是一旦稍微复杂一些,URL 就会显得太长。更好的设计方法是使用 HTTP POST 和 JSON(用于开发人员)公开图表的创建,并在此基础上提供图形化的界面(用于非开发人员)。这将使这两种用户都更容易地调试图表布局或数据方面的问题。可以使用 Project Zero 实现这种方法,具体做法是将图表 URL 的创建封装在一个 Groovy 脚本中,然后创建一个基于 Ajax 的 Web 界面,该界面通过 HTTP 调用那个脚本。

创建示例项目

为了展示您的工作,您需要创建两个项目:一个存放 Groovy 包装器代码,另一个用于存放示例 Ajax UI。您应该创建两个 Zero 应用程序 — 一个名为 zero.charts,另一个名为 chart.maker — 以分别存放 Groovy 代码和 Ajax 代码。这两个项目是分离的,以便允许不同的应用程序重用 Groovy 代码。您将从 zero.charts 应用程序中开始。

在 Groovy 中生成图表 URL

使用 Groovy 简化图表创建的第一步是定义用于指定图表细节的数据结构。您不会使用 Google Charts 所用的原始参数名称,而是用 JSON 定义一个更详细的数据结构;使用 JSON 意味着可以依赖标准数据类型(例如实际的整数数组,而不是包含以逗号分隔的串行化的整数字符串),并且更容易看到什么值被传递给图表生成器。清单 1 展示了 Ajax 客户机与 Groovy 脚本之间的通信将使用的数据结构。


清单 1. 使用 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]
    }
      

在开发期间,可以使用 FireBug 或简单的 JavaScript 警告等工具检查清单 1 中所示的 JSON 对象。与 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 这样冗长的字符串相比,这样的结构更容易调试和验证。

当然,归根到底,您仍然需要发送这样一个 URL 到 Google 的服务器,以获得所需的图表。为此,您将编写一个简单的 Groovy 方法,该方法将 JSON 对象中的字段值复制到一个图表 URL 中。借助 Groovy 的 GString 类型,您可以使 URL 字符串只有一行,而不必创建一个 java.lang.StringBuilder 并逐个添加值。这个 Groovy 方法的代码如清单 2 所示。


清单 2. 构造图表 URL 的 Groovy 代码
                
      
    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('|')}";
    }      
      

基本上,清单 2 中的代码直接从 JSON 对象获得值并(使用 $ 语法)将这些值嵌入到 URL 中。惟一不同的是当 JSON 字段为数组时的情况,在此情况下,必须将它们的值连接成一个字符串。使用 join() 方法很容易做到这一点。

您应该将清单 2 中的代码复制到一个名为 /zero.charts/app/scripts/charts.groovy 的文件中。通过将该代码放到 /app/scripts 目录中,可以让应用程序中的其他 Groovy 脚本以及在依赖关系列表中包括 zero.charts 的任何应用程序访问到它。使该代码易于重用的最后一步是为之创建一个 Groovy 绑定,这将使开发人员可以直接在代码中调用 create() 方法,而不必使用 Zero 的更通用的 invokeMethod() 。要添加 Groovy 绑定,将清单 3 中的 Java™ 类定义复制到 /zero.charts/java 目录中。如果之前没有提供这个绑定,那么开发人员必须 输入粗体显示的代码行。


清单 3. charts.groovy 的 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 });
        }
    }
      

在继续之前,注意传递给清单 3 中 create() 的参数类型为 java.util.Map。在 Zero 中,JSON 对象和 Maps 是一样的。Zero 的所有 I/O API 都知道如何在适当的时候完成 Map 与 JSON 之间的串行化,所以您不必学习专门的 API 就可以直接操纵 JSON 对象。

一旦清单 3 中的 Java 类就绪,就必须将其注册到配置文件中,以便让 Zero 知道它的存在。清单 4 中的文本必须添加到 /zero.charts/config/zero.config 中,以确保 Groovy 绑定有效,并且对 create() 的调用能够得到适当的处理。


清单 4. Groovy 绑定的配置
                
    
    /config/bindings/.groovy += ["zero.charts.ChartsBindings"]
      

通过 HTTP POST 请求图表

现在,您有了 URL 构造代码,接下来只需使用一个 RESTful API 来公开它。为此,您将创建一个名为 charts 的 RESTful 资源类型,并使用 HTTP POST 方法接受图表规范(使用 JSON)并返回图表 URL。这个行为与 RESTful 应用程序中通常实现的行为稍微有些不同。通常,HTTP POST 会导致代码的执行,该代码在与请求 URI 相同的域中创建一个资源,并返回那个新资源的 URI。您将通过构造一个指向 Google Charts 服务的 URI 来 “创建” 一个资源,当客户机访问那个 URI 时,将得到图表。因此,您的服务真正创建并返回的惟一的内容就是一个图表 URI,该 URI 位于 HTTP 响应的 Location 报头中。

清单 5 展示了 charts 资源的 Groovy 代码。它的惟一的 HTTP 方法是 POST,该方法是在 onCreate() 方法中实现的。您应该将该代码复制到一个名为 /zero.charts/app/resources/charts.groovy 的文件中。


清单 5. 用于图表创建的 REST API
                
    
    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;
    }
      

在谈论用户界面之前,我们花点时间使用 RESTdoc 测试界面对 REST API 进行测试。启动 zero.charts 应用程序(zero run),并在 Web 浏览器中访问 http://localhost:8080/resources/docs/charts。您将看到,charts 资源有一个方法(POST),如果单击它,将看到一个测试表单(如图 2 所示)。将 JSON 数据从 清单 1 复制到请求体中,并单击 Send。您看到的响应应该包括一个 Location 头,其中有一个 Google Charts URI。


图 2. 用于图表创建的 RESTdoc 测试表单
图 2. 用于图表创建的 RESTdoc 测试表单

REST API 就绪后,现在可以在应用程序中使用它。下一节将展示如何使用 Ajax 创建可视化的图表构建器。

设计更有用的界面

REST API 可以让开发人员更易于生成图表,它并不是用来帮助 99% 的不用编写代码的计算机用户的,而是针对那些偶尔为他们的文档和演示创建图表的用户。对于这些用户,可以使用一个 HTML 表单、一点 JavaScript 和最简单的 Ajax API XMLHttpRequest,创建一个简单的基于 Web 的图表构建器。图 3 展示了最终结果:Web 页面的一侧允许用户输入图表描述,而另一侧则显示生成的图表。


图 3. 用于生成图表的 Web 界面
图 3. 用于生成图表的 Web 界面

要开始创建该用户界面,首先必须创建 chart.maker 应用程序与 zero.charts 应用程序之间的一个依赖关系。可以通过将 zero:zero.charts 添加到 /chart.maker/config/ivy.xml 实现。接下来的两个小节将展示最重要的 markup 部分以及界面所需的代码。通过下载本文包含的 示例项目,并查看 chart.maker 项目,可以看到完整的 markup 和代码。

将用户输入映射为 API 输入

如图 3 所示,用于获取用户图表的表单非常简单。除了一个输入值外,该表单上的所有东西都可以很轻松地转换为所需的 JSON 格式。惟一需要额外步骤的输入是图表类型,它是由 Google Charts API 使用两个或三个字母的缩写表示的。该表单显示对图表类型(Line GraphBar Chart - VerticalBar Chart - Horizontal)的完整描述,因此 HTML 下拉菜单需要在这些描述与缩写(分别为 lcbvgbhg)之间映射。清单 6 展示了所需 HTML 下拉菜单的定义。您可以看到用粗体表示的图表类型代码。所有其他表单输入都是简单的文本框(<input type="text"/>


清单 6. 用于图表类型的 HTML 下拉菜单
                
      
    <select id="chartType">
      <option value="lc">Line Graph</option>
      <option value="bvg">Bar Graph - Vertical</option>
      <option value="bhg">Bar Graph - Horizontal</option>
    </select>   
      

除了下拉菜单 markup 外,对于那些不熟悉这种控件的用户,还提供了从菜单中获取所选值的代码。与简单的文本框不同,不能直接读取该控件的 value 属性 — 必须遍历下拉菜单的选项,直到发现当前选中的项(selected)。清单 7 包含了实现这一功能所需的代码。


清单 7. 发现选中的图表类型的 JavaScript
                
    
    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;
    }
      

另一个重要的 UI 元素是表单底部的 Create It! 按钮。这个按钮并非用于提交表单,而是链接到一个 JavaScript 函数,该函数发出一个对 REST API 的 Ajax 请求。为此,需要将一个 JavaScript 函数调用添加到该按钮的 onClick 事件中。清单 8 展示了链接到 createChart() 函数的按钮单击事件,您将在下一节中实现该函数。


清单 8. 使用 JavaScript 初始化图表创建
                
    
    <input type="button" value="Create It!" onClick="createChart();"/>
    

最后要详细谈到的 UI 元素就是显示所生成图表的图像。清单 9 展示了如何编写一个当页面装载时会隐藏的 HTML <img/> 标记。您将使用 JavaScript 将该标记的源设为所生成图表的 URL,然后使之可见。


清单 9. 用于显示图表的 HTML 图像
                
    
    <img id="chartImage" style="display:none;" src=""/>
    

您应该查看 chart.maker 示例项目中的 /public/index.html 文件,看看所有这些 markup 和代码。接下来的小节将谈到面向 Ajax 的 JavaScript(也被包括在该文件中),它用于操纵 UI 元素,以显示反映用户输入的图表。

使用 Ajax 显示生成的图表

与 REST API 的交互就是实现 createCharts() 函数,使之读取所有表单输入值,将它们打包到一个 JSON 对象中,并将 JSON 对象作为 HTTP POST 请求的一部分发送到 charts 资源。HTTP POST 请求完成后,您将从 Location 响应报头读取图表 URL,并设置(重置)图表图像的源。清单 10 显示了实现这一点的代码。


清单 10. 使用 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));
    }
    

我们来逐步讲解这段代码:

createCharts() 中,首先做的事情是使用适当的名称-值对创建一个 JSON 对象。getValue(s) 方法是类似于 清单 7 中的 getSelection() 方法的简单实用程序。它们的实现非常普通,可以从示例项目中查看它们。这里要特别注意的是,字段名称与 /app/scripts/charts.groovy 文件期望的名称相匹配,并且值使用适当的格式。

第二步是创建一个 XMLHttpRequest 对象,并发起一个对 /resources/charts 的 HTTP POST 请求。getHttpClient() 方法隐藏有一些条件,以确保为适当的 Web 浏览器实例化适当的类。

第三步是定义发送请求和收到响应之后的动作。在这个例子中,您将获取 Location 报头的值,并使用它设置 chartImage.src 的值;然后,修改 chartImage 样式,使之不再对用户隐藏。

最后一步是发送 HTTP POST 请求。这包括将 JSON 对象转换成可放入 HTTP POST 请求体中的字符串。由于没有标准的 JSON-to-string API,所以使用来自 http://json.org 的开源库。createChart() 最后的 JSON.stringify() API 调用是在一个名为 json2.js 的文件中定义的,该文件可以从 http://www.json.org/json2.js 获得。您应该从 http://json.org 下载这个 JavaScript 库,并将它添加到 /chart.maker/public 目录。一旦这个库准备就绪,createCharts() 的最后一行将顺利运行。

结束语

您看到了如何创建精巧的 mashup 应用程序,并且在此过程中使 Google Charts API 更易于在 Zero 应用程序之间重用。示例 Ajax 界面只涉及可视化图表构建器中的一些基本特性,但是服务器端代码可以支持您想要添加的任何其他特性。在将 RESTful API 用于宝贵的服务和数据方面,Zero 对 Groovy 脚本编制的集成再次被证明可以节省大量的时间。






回页首


下载

描述名字大小下载方法
本文的示例应用程序zero-chart-maker.zip7KBHTTP
关于下载方法的信息


参考资料

学习

获得产品和技术

讨论


关于作者

Dan Jemiolo 是 IBM 位于美国北卡罗来纳州 Research Triangle Park 的 Project Zero 团队的一名顾问软件工程师。目前主要负责 Zero 平台的可重用组件及其服务目录的工作。他的工作包括 Apache Muse 2.0 的设计和开发,也曾参加过 OASIS Web 服务标准组织。三年前他从 Rensselaer Polytechnic Institute 获得了计算机科学的理学硕士学位,之后加入了 IBM。




对本文的评价








Java 和所有基于 Java 的商标是 Sun Microsystems 公司的专有商标。 其他公司、产品或服务的名称可能是其他公司的商标或服务标志。

IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款