当前 Dojo 做为一个优秀的 Javascript 工具包在基于 Web 的应用程序中越来越受到欢迎。在包括 IBM 在内的众多社区成员的贡献下,Dojo 的版本不断提升,性能和架构不断完善,很多新的特性都被陆续的加入到 Dojo 工具包中,用户能够轻而易举的构建强大的 Web2.0 应用。Websphere Portal 是一个让您插入新功能或者扩展(称为 portlet)的框架,它能够使开发人员灵活的将不同的 portlet 聚集到一个界面中。Websphere Portal 从 6.0 开始用集成 Dojo 工具包来构建各种丰富多彩的自带主题,然而这对使用 Dojo 开发 portlet 带来了新的困扰,开发者只能使用 Websphere Portal 所自带的 Dojo 版本进行开发,多个版本的 Dojo 引入将会产生冲突,造成应用程序无法运行。下面我们来探讨这个问题。
某公司多年前基于 Websphere Portal V6.1.5 开发了内部的数据统计系统,当时该 portlet 是基于表格来显示数据的,如今公司准备将增加一个图表视图来加强数据的可读性,开发人员决定开发一个 portlet 灵活的插入到原有的应用中,开发人员决定选择 Dojo1.5 工具包中的 dojox.charting 来实现,因为 1.5 中的 charting 比 1.3 的在功能和性能上都有了提升,如增加了动画效果、自定义主题、datastore 绑定等新特性,但是由于 Websphere Portal V6.1.5 自带了 Dojo1.3.2 工具包导致了两个版本之间的冲突造成了该应用无法正常运行。
如不进行任何修改,该 portal 应用在运行时加载了两个 Dojo 版本,因为 Dojo 的包机制,只能运行率先加载的那份 Dojo, 如 dojo.require 语句永远调用的首先加载的 Dojo,如果所要 require 的包在早期版本中不存在就发生了错误,这里我们可以为后加载的 Dojo 版本改变其命名空间开区分对这两个 Dojo 版本的调用 , 相关变化代码如下:
清单 1. 命名空间变化示例
dojo.require → dojo15.require dojo.byId → dojo15.byId dojotype → dojo15type ... |
通过这样的做法我们就可以灵活的使用新版本 Dojo 的新特性了 , 原先的的 Dojo1.3 我们继续使用不带版本数字的命名空间,之后的 1.5 版本在每个命名空间加上 15,这样 1.3 版本和 1.5 版本就独立存在了,从而避免了冲突。
表 1 是该公司的原有数据表格,基于表里的数据结构,我们决定使用图表工具包中的多层列(Stacked Columns)来展示以上数据报表,给用户一种更加直观的效果,更加明确的展示报表中的信息。接下来的几个小节将使用 dojo 中上直观的图表视图来代替原有单调的统计表格。
表 1. 该公司某年多种业务收入组成分布表
需要注意的是,要在同页面中加载不同版本 Dojo 的前提条件是所使用的 Dojo 版本必须经过 build,Dojo 本身已经提供了一套对 Dojo 库文件进行 build 的工具,通过定制库文件和压缩文件的方法来减少浏览器加载文件的时间。
Dojo 包提供了 build 工具,该工具位于 util/buildsrcipts 下,执行里面的 build.bat 文件并加上相应的参数和 profile 文件就可以进行 build,具体参数用法请见 http://docs.dojocampus.org/build/index
清单 2. profile.js 文件
/* charting.profile.js */
dependencies = {
layers: [
{
name: "../dojo/dojo15.js",
dependencies: [
"dojox.charting"
]
}
],
prefixes: [
["dijit","../dijit"],
["dojox","../dojox"]
]
};
|
确认该配置文件 (charting.profile.js) 位于 \dojo 根目录 \util\buildsrcipts\profiles\ 下,然后执行 build 命令:
清单 3. dojo 构建命令
build profile=charting action=release releaseName=dojo15 optimize=shrinksafe |
执行 build 命令后将会在 dojo 包中出现一个名为 release 的的文件夹,该文件夹中的 dojo15 就是 build 后的 Dojo 包,可以拿来使用。在 release\dojo15\dojo\ 目录下会出现两个文件:dojo15..uncompressed.js 和 dojo15.js。这两个就是打包后的文件,前者包含了 profile 中所指定的所有文件内容,后者在前者的基础上再进行了优化压缩。
增加 djconfig 的 scopeMap 属性并进行配置:
在 load 相应的 dojo 库之前,对 djConfig 进行设置,将原来的命名空间改为自定义命名空间,下面是相关的版本映射代码:
清单 4. dojo 版本映射配置
<script type="text/javascript">
djConfig = {
scopeMap:[
["dojo", "dojo15"],
["dijit", "dijit15"],
["dojox", "dojox15"],
]
}
</script>
|
为了便于演示,本例省去了去服务端获取数据的过程,直接用一个 json 数组来表示表格中的所有数据。
清单 5. 模拟服务器端数据
var data = [
{name:'Real Estate', income:19.8, cost:6.4, profit:13.4, profitRatio:67.68},
{name:'Logistics', income:6.7, cost:3.7, profit:3, profitRatio:44.78},
{name:'Inland Trade', income:12.3, cost:11.5, profit:0.8, profitRatio:6.50},
{name:'Foreign Trade', income:14.3, cost:13.9, profit:0.4, profitRatio:2.79},
{name:'Others', income:16, cost:11.9, profit:4.1 ,profitRatio:25.63}
]
|
之前我们已经决定使用 stack columns 图表表现该数据,所以必须对原有数据进行加工,提取利润(profit)、成本(cost)作为该图表的统计数列。
清单 6. 加工原有模拟数据
// 初始化统计数列及图表所需元素
var incomeArr = [];
var costArr = [];
var ProfitArr = [];
var labelName = [];
// 提取数据后加入统计数列
for(var i=0;i<data.length;i++){
incomeArr.push(data[i].income);
costArr.push(data[i].cost);
// 添加 profit 数据及其对应 tooltip 内容
ProfitArr.push({
y:data[i].profit,
tooltip:'Income:'+data[i].income+' hundred million'
+'<br/>Cost:'+data[i].cost+' hundred million'
+'<br/>Gross Profit:'+data[i].profit+' hundred million'
+'<br/>Gross Profit Ratio:'+data[i].profitRatio+'%'
});
labelName.push({value:i+1, text:data[i].name});
}
|
我们用 dojo15 命名空间建立了一个包含“成本”和“毛利”两组数据的堆积柱形图,还为该 charting 增加了 tooltip 和 legend 的元素。这样能够使用户更加直观的获取到数据表格中的数据内容,得到成本和毛利的对比情况。
清单 7. 创建层叠柱状图 (Stacked Columns)
var chart = new dojox15.charting.Chart2D("chart");
// 设置图表主题
chart.setTheme(dojox15.charting.themes.Tom);
// 设置 X 轴属性
chart.addAxis(“x”,{labels: labelName}).
// 设置 y 轴属性
addAxis(“y”,{vertical:true, includeZero:true, max:20});
chart.addPlot("default",{type:"StackedColumns", gap: 15}).
// 添加成本数列
addSeries("Cost", costArr).
// 添加利润数列
addSeries("Gross Profit", ProfitArr);
// 创建图表提示
var tooltip = new dojox15.charting.action2d.Tooltip(chart, "default");
// 开始绘图
chart.render();
// 创建图表对应图例
var legend =
new dojox15.charting.widget.Legend({chart: chart, horizontal: true}, "legend");
|
在 Websphere portal 中部署该 portlet
将以上使用 dojox15 为命名空间的 charting 页面作为一个 portlet 部署进 Websphere portal V6 中,与原先已经有的表格视图以及 portal 本身没有产生任何冲突,这就说明了多个版本的 dojo 在这个 portal 页面中实现了共存。
图 1. 部署在 Websphere potal 中的表格与图表
通过以上方法,我们就可以在早期 portal 版本中来使用最新版本的 dojo,不需要将原来所使用的低版本 dojo 升级到最新版本,这样大大降低项目二次开发的复杂程度。同时 dojo 新版本中的 charting 组件也给项目提供了丰富的图表库以及主题,为项目的数据呈现提供了解决方案,下图是 dojo 图表库的简单实例。
图 2. Dojo 图表库
学习
- 查看文章“Customizing charts using Dojo”,了解更多 Dojo 图表库定制功能。
- 查看文章“Javascript 图表库 : Dojo Charting”,了解 Dojo 图表库基础介绍。
- 查看文章“Dojo1.6 新特性:AMD 规范”,理解 Dojo1.6 引入的最新脚本加载机制。
- 访问 developWorks WebSphere Portal 专区。了解 WebSphere Portal 产品系列的简单介绍。
- 访问 developerWorks Lotus 专区。
- 随时关注 developerWorks 技术活动和 网络广播。
讨论
- 加入 developerWorks 中文社区,developerWorks 社区是一个面向全球 IT 专业人员,可以提供博客、书签、wiki、群组、联系、共享和协作等社区功能的专业社交网络社区。
- 加入 IBM 软件下载与技术交流群组,参与在线交流。


