使用 Dojo Toolkit 来创建移动图表应用

轻松开发用于移动设备的图表应用

本文探究 dojox.mobile 和 dojox.charting 包的功能。文章使用 Dojo Toolkit 并通过步进式例子来创建一个移动图表应用,随后再通过支持触摸交互来增强应用的功能。此外还涵盖了一些高级主题,比如改进渲染性能等。

Damien Mandrioli, 软件工程师, IBM

//www.ibm.com/developerworks/i/p-dmandrioli.jpgDamien Mandrioli 是 IBM 的一名软件工程师。他的专业兴趣包括可视化组件、Web 应用开发和用户界面可用性。在加入 Dojo Toolkit 开发团队之前,Damien 花了五年的时间开发 IBM ILOG Elixir 可视化产品的组件和演示。



2012 年 7 月 18 日

简介

在本文中,我们学习如何使用 Dojo Toolkit 的图表框架来创建在移动设备上运行的引人注目的图表应用。学习如何在 Dojo 移动应用内部实例化和配置图表组件,以及如何 在组件上启用触摸交互,以实现与移动设备的更好整合。我们还会探讨图表应用的一些可改进加载和渲染速度的高级可选做法。

您还可以 下载 本文的源代码。


创建一个 Dojo 移动图表应用

在使用 Dojo 来构建移动应用时,这里的建议是依赖 dojox.mobile 包来完成。这是一个相对轻量的 Dojo 层,其提供了一组面向移动的轻量级的部件、一个解析器和一个过渡框架。考虑到移动应用的这些功能的重要性,大多数的移动 Dojo 图表应用都有可能会使用这一框架。

dojox.mobile 应用的上下文中实例化图表的最简单方式是依赖解析,并将图表代码放在 dojox.mobile 部件标记内部(类似于 您在普通的 Dijit 桌面应用中会采用的做法)。首先,您 需要一个定义了应用标记的 HTML 文件,接着是一个 HTML 引用的 JavaScript 源文件,该文件包含了应用程序的 JavaScript 逻辑。

本文中的例子给您展示了如何构建一个使用柱状图来显示销售数据的简单应用,该柱状图以月为单位,覆盖的时间阶段为三年。清单 1 中的代码被用来创建一个 HTML 文件。

清单 1. 最初的移动图表应用的 HTML 文件
<!DOCTYPE HTML> 
<html> 
  <head> 
    <title>Dojo Toolkit Mobile Charting</title> 
    <meta name="viewport" content="width=device-width,initial-scale=1, 
      maximum-scale=1,minimum-scale=1,user-scalable=no"/> 
    <meta name="apple-mobile-web-app-capable" content="yes" /> 
    <link rel="stylesheet" type="text/css" 
      href="../../../dojo_current/dojox/mobile/themes/iphone/iphone.css"> 
    <script type="text/javascript" src="../../../dojo_current/dojo/dojo.js" 
      data-dojo-config="parseOnLoad: true"></script> 
    <script type="text/javascript" src="src_01.js" charset="utf-8"></script> 
  </head> 
  <body> 
    <div id="view1" data-dojo-type="dojox.mobile.View"> 
      <h1 id="head1" data-dojo-type="dojox.mobile.Heading">Chart View</h1> 
      <div data-dojo-type="dojox.mobile.RoundRect"> 
        <button id="b1" data-dojo-type="dojox.mobile.Button" 
          class="mblBlueButton">Zoom</button> 
        <button id="b2" data-dojo-type="dojox.mobile.Button" 
          class="mblBlueButton">Unzoom</button> 
        <div data-dojo-type="dojox.charting.widget.Chart" id="chart" 
          style="width: 100%; height: 180px;"> 
          <div class="plot" name="grid" type="Grid" 
               vMinorLines="true"></div>             
          <div class="axis" name="x" 
               fixUpper="minor"   
               majorTickStep="1" 
               minorTicks="false"></div> 
          <div class="axis" name="y" vertical="true" min="0"></div> 
          <div class="plot" name="plot" type="Columns" ></div> 
          <div class="series" name="data" plot="plot" 
            data="20, 32, 32, 45, 37, 28, 24, 48, 44, 21, 32, 33, 
                32, 34, 44, 32, 39, 43, 44, 46, 36, 41, 25, 27, 
                28, 45, 46, 33, 34, 35, 29, 44, 48, 48, 49, 43"></div> 
        </div> 
      </div> 
    </div> 
  </body> 
</html>

清单 1 中的代码引用了 Dojo 数据类型属性中的 dojox.mobiledojox.charting 类。为了正确 解析和实例化该标记,必须将相应的模块导入 JavaScript 源文件,如清单 2 所示。

清单 2. 最初的移动图表应用的 JavaScript 源文件
require(["dojo", "dojox/mobile", "dojox/mobile/parser", 
  "dojox/mobile/Button", "dojox/charting/widget/Chart", 
  "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Columns",
  "dojox/charting/plot2d/Grid"]);

本文中的示例依赖于最近介绍过的用于管理 Dojo 应用依赖的 AMD 语法。(参见 参考资料 了解更多 关于 AMD 的信息。)如果您不想 切换到新格式的话,可以使用 替代的 dojo.require 这一依赖格式构建具有后向 兼容性的类似的应用程序。

如果您运行相应的应用程序,应当会获得 如图 1 所示的结果。

水平移动视图上的条形图,有两个用于缩放控制的按钮

图 1 中的图表仅仅是静态的非交互式图表,数据是来自定义在标记中的 series 的 data 属性的硬编码数据。在进一步深入之前 需要对应用进行一些细微的调整。

到目前为止,该应用是专为 Webkit 移动和桌面浏览器定做的。如果您希望该应用程序 在 Firefox 等其他桌面浏览器上更好地运行,您可以 更新您的依赖项列表,添加 dojox/mobile/compat 模块, 如清单 3 所示。该示例使用 dojo/has AMD 插件,只有当应用没有运行在 Webkit 浏览器上而需要用到兼容性模块时,才会包含该模块。

清单 3. 添加非 Webkit 浏览器支持
require(["dojo/_base/kernel", "dojo/_base/sniff", "dojox/mobile", "dojox/mobile/parser",
	"dojo/has!webKit?:dojox/mobile/compat", 
	"dojox/mobile/Button", "dojox/charting/widget/Chart", 
	"dojox/charting/axis2d/Default", "dojox/charting/plot2d/Columns",
	"dojox/charting/plot2d/Grid"]);

下一步是使用外部数据源而不是应用中的硬编码数据来给显示的图表提供数据。 为此,您可以使用 Dojo Charting 和 Dojo Core 的数据存储 API。

dojo.datadojox.data 包中有一些类,允许 从各种数据源加载数据,并将它们连接到 Dojo 组件。对于该示例,假设您在服务器上有清单 4 中的 JSON 数据 并想加载数据。

清单 4. JSON 数据示例
{
  "items": 
  [ 
{"value": 0}, {"value": 32}, {"value": 32}, {"value": 45}, {"value": 37}, {"value": 28}, 
{"value": 24}, {"value": 48}, {"value": 44}, {"value": 21}, {"value": 32}, 
{"value": 33}, {"value": 32}, {"value": 34}, {"value": 44}, {"value": 32}, 
{"value": 39}, {"value": 43}, {"value": 44}, {"value": 46}, {"value": 36}, 
{"value": 41}, {"value": 25}, {"value": 27}, {"value": 28}, {"value": 45}, 
{"value": 46}, {"value": 33}, {"value": 34}, {"value": 35}, {"value": 29}, 
{"value": 44}, {"value": 48}, {"value": 48}, {"value": 49}, {"value": 43} 
  ]
}

JSON 数据可以由 dojo.data.ItemFileReadStore 的实例加载。若要使用图表来处理数据,将您的 dojo.data 实例连接到 Series 对象,该对象负责使用 来自存储中的数据项填充图表。

首先,您需要修改 HTML 中 series 的声明,把硬编码数据输入改成引用一个名为 “store” 的数据存储。为此,将清单 6 中的 Series 定义更改为包括 store="store",如清单 7 所示。

清单 6. 之前的 Series 定义
           <div class="series" name="data" plot="plot" 
              data="20, 32, 32, 45, 37, 28, 24, 48, 44, 21, 32, 33,
                    32, 34, 44, 32, 39, 43, 44, 46, 36, 41, 25, 27,
                  28, 45, 46, 33, 34, 35, 29, 44, 48, 48, 49, 43"></div>
清单 7. 之前的 Series 定义,包括 store
            <div class="series" name="data" store="store" plot="plot"></div>

在同一个 HTML 文件中,您可以用清单 8 中的标记定义 store。

清单 8. store 的 HTML 定义
	    <div data-dojo-type="dojo.data.ItemFileReadStore" url="data.json"
       		 data-dojo-id="store" urlPreventCache="true" clearOnClose="true"></div>

清单 8 中的代码使用 ItemFileReadStore 类加载服务器上的 data.json 文件,并把结果与用作 series 的输入的 store 变量关联起来。数据存储类必须作为源文件 require 语句的一部分被请求加入应用中,如 清单 9 所示。

清单 9. 请求加入 store
require(["dojo/_base/kernel", "dojo/_base/sniff", "dojo/data/ItemFileReadStore",
        "dojo/has!webKit?:dojox/mobile/compat", 
        "dojox/mobile", "dojox/mobile/parser", 
        "dojox/mobile/Button", "dojox/charting/widget/Chart", 
        "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Columns",
        "dojox/charting/plot2d/Grid"]);

现在您有了一个渲染来自服务器的月度数据的移动图表应用了,但该例子仍然缺少应该显示目标月份而不是数据索引的 x 轴。清单 10 给出了轴的标签函数的引用。

清单 10. 指定一个标签函数
            <div class="axis" name="x" 
	         fixUpper="minor" majorTickStep="1"
                 minorTicks="false" labelFunc="displayDate"></div>

然后在源文件中定义 displayDate 函数,如清单 11 所示。

清单 11. 在 JavaScript 中实现标签函数
var displayDate;
require(["dojo/_base/kernel", "dojo/_base/sniff", "dojo/data/ItemFileReadStore",
       "dojo/has!webKit?:dojox/mobile/compat", 
       "dojox/charting/action2d/TouchZoomAndPan", 
       "dojox/mobile", "dojox/mobile/parser", 
       "dojox/mobile/Button", "dojox/charting/widget/Chart", 
       "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Columns",
       "dojox/charting/plot2d/Grid"], function(dojo){
  var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", 
                "Oct", "Nov", "Dec"];
  var years = ["08", "09", "10", "11"];
  displayDate = function(idx){
    if ((idx%2) == 0){
     return " ";
    }
			
    var m = parseInt(idx-1);
    if (m%12 == 0){
      // Display the year only for january
      return months[m%12] + " " + years[m/12];
    }else{
      return months[m%12];
    }
  }
});

清单 11 中的代码基本上将每个数据索引都映射到一个字符串。在该示例中, 由于有 三年以上的月度数据,因此字符串由给定索引的相应的 月份构成。

现在您应该得到如图 2 所示的结果。

该视图显示添加了年份和月份的 x 轴标签定制。

启用图表触摸交互

在创建了您自己的 Dojo 移动图表应用后,您可能想要 向它添加特定的移动功能,比如使用触摸手势来与图表进行交互的能力。 这相对比较容易。与图表的其他功能 类似,您可以使用图表定义中的一行代码添加触摸。 例如,要添加触摸缩放和平移功能,您只需要 将清单 12 的内容添加到 HTML 标记。

清单 12. 添加触摸缩放和平移支持
<div class="action" type="dojox.charting.action2d.TouchZoomAndPan" 
     plot="plot" maxScale="7"></div>

plot 属性允许您将行为附加在图表的某个特定标定点上(在该示例中是名为 plot 的标定点)。您还可以使用各种其他 选项,比如是否允许缩放 (enableZoom="false"),或 您想应用到图表上的最大比例 (maxScale="7")。

另一个有用的触摸交互是当 触摸图表时显示数据指示器。它甚至可以给出一个显示两个触摸点之间的趋势的双工数据指示器。

在单触摸图表时,使用清单 13 中的代码会产生图 3 中的结果。

清单 13. 添加触摸指示器支持
<div class="action" type="dojox.charting.action2d.TouchIndicator" plot="plot" 
     series="data" dualIndicator="true"></div>
该视图显示了简单的触摸指示器。它显示了被触摸数据点的值。

使用双触摸手势,您将获得图 4 所示的结果。

该视图显示了双触摸指示器。它显示了两个被触摸数据点之间的比例变化。

关于触摸交互还有几个参数可用,比如说改变数据指示器的颜色和字体的能力。您甚至可以基于两个触点之间的趋势是正向的还是负向的来决定如何改变指示器的填充颜色。 清单 14 显示了如何在 JavaScript 中构建一个此类指示器的示例。

清单 14. 在 JavaScript 中配置触摸指示器
var indicatorFillFunc = function(v1, v2){
  if(v2){
    return v2.y>v1.y?"green":"red";
}else{
  // single touch point
    return "#ff9000";
  }
};
var indicator = new TouchIndicator(chart, "plot", {
               series: "series", dualIndicator: true, 
               font: "normal normal bold 12pt Helvetica",
               fillFunc: indicatorFillFunc
});

一些移动设备,比如 Android 2.2 和 2.3,在浏览器中不 支持多个触摸事件。您可能 想要映射某些依赖于双触摸的行为,比如缩小和 放大,将这些行为映射到按钮和触摸交互,以此来支持所有设备。对于这种 情况,自本文的第 1 个清单开始,在用户界面 已经存在处于非活动状态的按钮,现在是时候添加一些代码来响应这些按钮的点击和触摸行为了。清单 15 显示了如何指定缩放函数。

清单 15. 指定缩放函数
           <button id="b1" data-dojo-type="dojox.mobile.Button" 
		    onclick="zoomChart()"
            class="mblBlueButton">Zoom</button>
          <button id="b2" data-dojo-type="dojox.mobile.Button"
		  	onclick="zoomChart(true)" 
            class="mblBlueButton">Unzoom</button>

清单 15 中的代码调用缩放和非缩放按钮的 zoomChart 函数。 由于 缩放和非缩放行为非常相似,您只需使用一个带有参数的函数,并把缩小行为的参数值指定为 true 就可以了。

在 JavaScript 源文件中定义 zoomChart 函数,如清单 16 所示。其想法是获取当前的可视边界来计算出新的范围,然后把该范围传递给 Dojo 图表组件的 zoomIn 函数。

清单 16. 在 Javascript 中实现缩放函数
  zoomChart = function(back){
    var chart = dijit.byId("chart").chart;
    var b = chart.getAxis("x").getScaler().bounds;
    var r = 1.25;
    if (back){
      // Unzoom
      chart.zoomIn("x", [b.from / r, b.to * r]);
    }else{
      // Zoom
     chart.zoomIn("x", [b.from * r, b.to / r]);
    }
};

优化应用

现在有了一个完全能够运行的 Dojo 移动图表应用了,但它是没有完全优化过的。

您要进行的第一种优化是提高渲染时间,相比于桌面设备,移动设备通常会有着较慢的 CPU 和内存,因此渲染的过程也较慢。默认情况下,Dojo 并不会缓存已经渲染过的图表项,在使用触摸交互来缩放和平移图表时,大量的已渲染项可能会被销毁并重建。在只有静态的图表时,不启用缓存是对的,因为这样会提供更快的初始渲染。然而在动态的使用情况下,最好是启用缓存,您可以使用几个图表元素的 enableCache 参数。

代码把图表元素上的 enableCache 设置为 true, 如清单 17 所示。

清单 17. 优化渲染
<div data-dojo-type="dojox.charting.widget.Chart" id="chart" 
    style="width: 100%; height: 180px;">
<div class="plot" name="grid" type="Grid"
    vMinorLines="true" enableCache="true"></div>
    <div class="axis" name="x" enableCache="true"
        fixUpper="minor"   
        majorTickStep="1"
        minorTicks="false"
        labelFunc="displayDate"></div>
    <div class="axis" name="y" vertical="true" min="0"></div>
    <div class="plot" name="plot" type="Columns" enableCache="true"></div>
    <div class="series" name="data" store="store" plot="plot"></div>
    <div class="action" type="dojox.charting.action2d.TouchZoomAndPan" 
        plot="plot" maxScale="7"></div>
</div>

该示例在 y 轴上没有启用缓存功能。在放大 或缩小时,沿 y 轴的图表并未重新渲染,因此 不会从优化中受益。

另一种优化移动图表应用渲染的方法是阻止不必要的渲染,例如,柱图可能会有轮廓或是阴影,而这些并非是绝对必要的,但它们会消耗渲染时间,您可以考虑去掉它们。另一个例子是数据指示器,对于数据指示器来说,您可以通过把相应样式属性设置成 null 来取消轮廓线,如清单 18 所示。

清单 18. 删除不必要的渲染
<div class="action" type="dojox.charting.action2d.TouchIndicator" plot="plot" 
     series="data" dualIndicator="true" outline="null" lineOutline="null"
     markerOutline="null"></div>

应用加载时间的优化很重要,特别是移动设备的网络连接并不总是和桌面上的一样快。使用 Dojo 提供的新 AMD 加载器,而不是同步加载 各种必需的文件,您将能够通过异步加载文件来提高整体加载性能。添加 Dojo 初始配置上的 async 参数, 如清单 19 所示。

清单 19. 启用异步加载
   <script type="text/javascript" src="../../../dojo_current/dojo/dojo.js"
      data-dojo-config="parseOnLoad: true, async: true"></script>

您可以通过除去任何不是应用绝对必需的实用工具来提高加载时间。例如, 整个移动图表应用是使用依赖于 dojox.mobile 解析器的标记定义的。该轻量级解析器 比 普通 Dojo 解析器轻得多。如果您真的想进一步降低 应用的下载大小,您可以完全地去掉解析器, 使用 JavaScript 来构建您的应用。


结束语

在本文中,您了解了如何在移动 Web 应用的内部使用 Dojo 图表包,它可以为依赖触摸交互事件而非依赖鼠标或按钮样式的移动设备提供量身定制的功能。本文还探讨了一些高级的可选功能项,您可以使用这些选项来改善加载和渲染时间。

如果您有兴趣深入这一主题,由于 Dojo 图表被设计成是可扩展的,因此您可以在其之上构建自己的功能。例如,如果您需要 框架不提供的触摸交互,可以扩展 Dojo 图表行为包来创建自己的交互行为。


下载

描述名字大小
源代码source.zip10KB

参考资料

学习

获得产品和技术

  • 获取 Dojo Toolkit
  • 下载 IBM 产品评估试用版软件,并开始使用来自 DB2、Lotus、Rational、Tivoli 和 WebSphere 的应用程序开发工具和中间件产品。
  • 免费使用 IBM 软件。下载试用版本,通过登录在线试用,在沙箱环境中使用产品或通过云进行访问。您可以选择试用超过 100 款 IBM产品。

讨论

  • 加入 developerWorks 中文社区。查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Web development
ArticleID=826474
ArticleTitle=使用 Dojo Toolkit 来创建移动图表应用
publish-date=07182012