使用 DataChart 实现 Dojo Chart 的自动更新

在 UI 设计中,Chart(图表)的出现为用户提供了一种可以直观分析数据的手段,Chart 在很多系统中应用甚广。Dojo 对 Chart 的支持非常强大,对于用户在 UI 上动态更新 Chart 的需求也提供了很多方法。在开发过程中,我们经常会遇到这样一种常见的场景,用户对 Chart 展现出的数据并不十分满意,用户希望能够通过在 UI 上修改数据来实现对 Chart 的修订,使 Chart 展现出其所期望的形态。本文将介绍一种实现此场景的方法,通过使用 DataChart 绑定 Dojo Grid 与 Dojo Chart 来实现这一需求。

与本文相关的 Dojo 插件

在文章开始前,我们先来介绍一下下文中将要使用的 Dojo 插件:

  • DataChart(dojox.charting.DataChart)是 Chart2D 的一个扩展,它使用 Dojo Store 作为数据的存储结构。DataChart 会监听 Dojo Store 的‘onSet’事件,每当 Dojo Store 中的数据发生变化时,DataChart 会自动更新图表。
  • ItemFileWriteStore(dojo.data.ItemFileWriteStore)是 Dojo Store 中的一种,它是 ItemFileReadStore 的一个扩展,即可以作为 Grid 的数据结构,也可以用作 DataChart 的数据结构。ItemFileWriteStore 的特性是可以接收用户在 UI 上的输入,其它 Dojo Store 是不能接收 UI 输入的。
  • DataSeries(dojox.charting.DataSeries)是一个非常特殊的 Series,它可以用来绑定 Dojo Chart 和 Dojo Store,后文会介绍详细的使用方法。

创建数据源

首先我们创建数据源,本文使用 ItemFileWriteStore 作为 Chart 和 Grid 的共同数据源,通过使用共同的数据源来实现 Chart 和 Grid 的联动。下面我们创建一个示例数据:

清单 1. 示例数据的代码片段
var itemStore = 
{ 
identifier: "id",label: "month",items:[ 
{id:1,month:"Jan",index1:3.52,index2:3.52,index3:7.48},{id:2,month:"Feb",index1:6.76,{id:3,month:"May",index1:3.98,{id:4,month:"Apr",index1:5.60,{id:5,month:"Mar",index1:8.44,{id:6,month:"Jun",index1:2.47,{id:7,month:"Jul",index2:4.52,{id:8,month:"Aug",index2:5.52,{id:9,month:"Sep",index2:6.52,{id:10,month:"Oct",index2:7.52,{id:11,month:"Nor",index2:8.52,{id:12,month:"Dec",index2:9.52,index3:7.48}
]
};

在上面的代码中,identifier 标识了哪个字段可作为主键,该字段的值是不可重复的。label 标识了哪个字段可以作为标签名,我们可以使用这个字段来为图表的轴标签赋值,后文将有详细介绍。接下来我们使用这个示例数据生成 Dojo Store:

var store = new dojo.data.ItemFileWriteStore({data:itemStore});

创建 Data Grid

创建了数据源,我们还需要创建一个 Grid 来展示数据,因此我们在 HTML 页面中建立两个节点,一个挂载 Grid,另一个预留给 Chart。

清单 2. HTML 页面的代码片段
<td> <div style="height:350px;width:400px;" data-dojo-type="dojox.grid.EnhancedGrid" id="chartGrid" structure= "[ {id:'month',field:'month',name:’月份’,editable:true,width:'25%'},{id:'index1',field:'index1',name:’指数 1’,editable: true,{id:'index2',field:'index2',name:’指数 2’,{id:'index3',field:'index3',name:’指数 3’,width:'25%'}]" > </div> </td> <td><div id="chart1" style="height:350px;width:550px;"></div></td>

Grid 创建成功后,将上节生成的 Dojo Store 赋给 Grid:

dijit.byId('chartGrid').setStore(store);
回页首

使用 DataChart 来实现线图

接下来我们就可以创建 Chart 了,下面以线图(Line Chart)为例,展示如何创建一个 DataChart。

清单 3. 创建 DataChart 的代码片段
function lineChart() { chart=new dojox.charting.DataChart("chart1",{type: "Lines",comparative:true}); chart.setStore(store,{month:"*"},"index1"); chart.render(); }

在这段代码中,DataChart 构造方法的第一个参数是 Chart 在页面上的挂载节点,在这里,我们使用上一节预留的 chart1 节点。第二个参数为 Chart 的各种属性,其中 type 是 Chart 的类型,而 comparative 代表着数据与 Series 所对应的方式,如果将 comparative 设置成 true,那么一个 item 个体将对应 Series 中的一个节点,如果设置成 false,那么每一个 item 个体将对应一条 Series。

在 setStore 方法中,第一个参数是数据源,第二个参数是过滤条件(这里我们要显示所有的数据,所以用*代表选择所有),第三个参数指明了应该显示数据源中的哪一个字段。

最后的效果如下图所示,Data Chart 会自动监听 store 中的‘onSet‘方法,一旦 store 内的数据有所变化,图表也会随之刷新。修改红框内的数据,右边的图表会跟随修改进行变化。

图 1. 使用 DataChart 构建单线图
回页首

使用 DataSeries 来实现多线图

上文我们实现了单线图,那么有多条 Series 的图表,比如多线图应该如何实现呢?我们知道通过将 comparative 设置成 false,可以支持多个 Series,但是这种做法并不符合我们的场景,因为如果将 comparative 设置成 false,那么我们需要将 store 中的每一个 item 改成数组,而这样的 store 与 Grid 是没法兼容的。所以我们最好寻找其它途径,还好我们可以通过使用 DataSeries 来实现拥有多个 Series 的图表,下面就是一个多线图的例子。

清单 4. 使用 DataSeries 的代码片段
function lineChart() { chart = new dojox.charting.DataChart("chart1",comparative:true }); chart.addSeries("index1",new dojox.charting.DataSeries( store,{query: {month: "*"}},"index1"),{stroke: "red"}); chart.addSeries("index2",new dojox.charting.DataSeries( store,"index2"),{stroke: "gold"}); chart.addSeries("index3","index3"),{stroke: "green"}); chart.render(); }

显示的效果如下图所示,修改红框内的数据,右边的图表会跟随修改值进行变化。

图 2. 使用 DataSeries 构建多线图
回页首

使用 Store 中的数据创建标签

到这里我们已经实现了 Grid 与 Chart 之间的联动,但我们还应该为 X 轴添加标签。DataChart 有一个简便的方法可以自动为图表的轴标签赋值,实现方法如下所示:

清单 5.添加 label 的代码片段
xaxis:{labelFunc:"seriesLabels"}, comparative:true }); chart.setStore(store,"index1"); chart.addSeries("index1",34); line-height:1.5em; font-size:1.166em!important"> 上面代码中的黑色斜体字是所添加的内容,其中{labelFunc:"seriesLabels"}是固定表达形式,这个方法是把 store 中标注为“label”字段的值作为标签显示出来,从清单 1 中可以看到我们已经把 month 字段设置为 label,因此 DataChart 就会自动使用月份名来填写 X 轴的标签,效果如下图所示,标签的值与 month 字段是一一对应的,尝试更改左手边 Grid 内的月份值,会发现右手边的标签也会跟随做相应的变化。

图 3. 为多线图的 X 轴添加标签
回页首

总结与补充

本文详细介绍了如何通过使用 DataChart 和 DataSeries 来绑定 Grid 与 Chart,最终实现 Dojo Chart 的动态更新,希望可以对初学 Dojo 的开发者予以帮助。但在有些时候,由于 DataChart 的样式(Style)相对固定不够灵活,可能无法满足用户对于页面样式的要求,此时开发者可以通过监控 Dojo Store 的“onSet”事件来绑定 Grid 与其它类型的 Dojo Chart,或者将 DataSeries 与其它类型的 Dojo Chart 搭配使用,两种方法均可实现以上目的。


原文链接:

http://www.ibm.com/developerworks/cn/web/1312_yuanlei_datachart/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我有一个网格,可以根据更大的树结构编辑小块数据.为了更容易知道用户保存了什么,我希望当用户第一次看到网格时,网格处于不可编辑状态.当用户准备好后,他们可以单击编辑按钮,这将使网格的某些部分可编辑.然后,有一个保存或取消按钮可以保存更改或还原.在大多数情况下它是有效的.但
我即将开始开发一款教育性的视频游戏.我已经决定以一种我可以轻松打包为Web,Mobiles和可能的Standalone版本的方式来实现这一目标.我不想使用Flash.因此,我确信(无论如何我会听取建议)使用JavaScript和SVG.我正在对这个问题进行大量研究,但我很难把各个部分放在一起.我知道Raphae
我正在使用带有Grails2.3.9的Dojo1.9.DojoNumberTextBox小部件–我在表单中使用–将固定格式(JavaScript基本格式)的实数值(例如:12.56)设置为HTML表单输入字段(但根据浏览器区域设置显示/编辑它们,所以用户总是看到格式正确的数字).另一方面,Grails期望输入字段根据浏览器
1.引言鉴于个人需求的转变,本系列将记录自学arcgisapiforjavaScript的学习历程,本篇将从最开始的arcgisapiforjavaScript部署开始,个人声明:博文不在传道受业解惑,旨在方便日后复习查阅。由于是自学,文章中可能会出现一些纰漏,请留言指出,不必留有情面哦!2.下载ArcGISforDe
我正在阅读使用dojo’sdeclare进行类创建的语法.描述令人困惑:Thedeclarefunctionisdefinedinthedojo/_base/declaremodule.declareacceptsthreearguments:className,superClass,andproperties.ClassNameTheclassNameargumentrepresentsthenameofthec
我的团队由更多的java人员和JavaScript经验丰富组成.我知道这个问题曾多次被问到,但为了弄清楚我的事实,我需要澄清一些事情,因为我在客户端技术方面的经验非常有限.我们决定使用GWT而不是纯JavaScript框架构建我们的解决方案(假设有更多的Java经验).这些是支持我的决定的事实.>
路由dojo/framework/srcouting/README.mdcommitb682b06ace25eea86d190e56dd81042565b35ed1Dojo应用程序的路由路由FeaturesRoute配置路径参数RouterHistoryManagersHashHistoryStateHistoryMemoryHistoryOutletEventRouterContextInjectionOutl
请原谅我的无知,因为我对jquery并不熟悉.是否有dojo.connect()的等价物?我找到了这个解决方案:http:/hink-robot.com/2009/06/hitch-object-oriented-event-handlers-with-jquery/但是没有断开功能!你知道jquery的其他解决方案吗?有jquery.connect但这个插件在我的测试中不起作用.
与java类一样,在dojo里也可以定义constructor 构造函数,在创建一个实例时可以对需要的属性进行初始化。//定义一个类mqsy_yjvar mqsy_yj=declare(null,{     //thedefaultusername    username: "yanjun",          //theconstructor   
我一直在寻找一些最佳实践,并想知道Dojo是否具有框架特定的最佳实践,还是最好只使用通用的Javascript标准?特别是我主要是寻找一些功能和类评论的指导方针?解决方法:对于初学者来说,这是项目的风格指南:DojoStyleGuide
我有’05/17/2010’的价值我想通过使用dojo.date.locale将其作为“2010年5月17日”.我尝试过使用dojo.date.locale.parse,如下所示:x='05/17/2010'varx=dojo.date.locale.parse(x,{datePattern:"MM/dd/yyyy",selector:"date"});alert(x)这并没有给我所需的日期
我正在尝试创建一个包含函数的dojo类,这些函数又调用此类中的其他函数,如下所示:dojo.provide("my.drawing");dojo.declare("my.drawing",null,{constructor:function(/*Object*/args){dojo.safeMixin(this,args);this.container=args[0];
我知道你可以使用jQuery.noConflict为jQuery做这件事.有没有办法与Dojo做类似的事情?解决方法:我相信你可以.有关在页面上运行多个版本的Dojo,请参阅thispage.它很繁琐,但似乎是你正在寻找的东西.一般来说,Dojo和jQuery都非常小心,不会破坏彼此或其他任何人的变量名.
我有一个EnhancedGrid,用户经常使用复杂的过滤器.有没有办法允许用户保存或标记过滤器,以便将来可以轻松地重新应用它?我知道我可以通过编程方式设置过滤器,但我无法预测用户想要的过滤器.谢谢!编辑:自己做了一些进展…使用grid.getFilter()返回过滤器的JSON表示,然后使用json.strin
我有这个代码:dojo.declare("City",null,{constructor:function(cityid,cityinfo){}});dojo.declare("TPolyline",GPolyline,{constructor:function(points,color){},initialize:function(map){});应该是什
我遇到的问题是我的所有javascript错误似乎来自dojo.xd.js或子模块.我正在使用chrome调试器和许多dijit功能,如dijit.declaration和dojo.parser.这有点烦人,因为它很难找到简单的错误或滑倒.我希望我可以添加一个选项,允许我的调试器在我的非dojo代码中显示选项会发生的位置.我是
我正在使用DojoToolkit数字/解析函数来处理格式化和使用ICU模式语法解析字符串.有没有人知道有可能采取任意ICU模式字符串并以某种方式使用Dojo(或其他)库将其分解为它的部分(例如,对于数字模式,它可以被分解为小数位数,数千个分组等…).我希望这样做,而不需要让我的代码密切了
我有两个看似相关的问题,访问在不同的地方定义的javascript函数.我遇到的第一个问题是调用我在firgbug或safari控制台中定义的函数.我定义了一个名为getRed的函数,如下所示:functiongetRed(row,col){//dosomethingstuffandreturntheredvalueasa
我想添加一个在Ajax调用中指定的外部样式表.我已经找到了一种方法来使用jQuery(参见下面的示例),但是我需要使该方法适应dojoJavaScript框架.JQuery示例$('head').append('<linkrel="stylesheet"type="text/css"href="lightbox_stylesheet.css">');谢谢.解决方法:一旦你
我正在尝试使用dojo.connect将onMouseDown事件连接到图像,如:dojo.connect(dojo.byId("workpic"),"onMouseDown",workpicDown);functionworkpicDown(){alert("mousedown");}类似的代码几行后,我将onMouse*事件连接到dojo.body确实完全正常工作.但是当我点击图像时