使用Xstream为FusionCharts提供XML
在寻找一个功能全面、文档齐备、交互性强、易于使用、配置灵活、bug较少还FOR FREE 的图表组件失败之后,老板终于拍板买下fusioncharts的Enterprise Edition。
有些童鞋可能用过这个组件,它是一个用actionscript写的flash chart widget,在浏览器的flash player中播放。其数据和样式都由XML来定义。项目组用fusioncharts也有一段时间了。围绕着其XML格式的数据源提供方案,先后尝试了手工拼装、XSL转换等几种方式,感觉都不太理想。直到一个偶然的机会,我接触到xstream。
根据官方文档对xstream的介绍,XStream is a simple library to serialize objects to XML and back again。我硬译了一下,XStream是一个将java对象和XML相互转化的简单类库。恩,最吸引我的就是简单,400多k的身材、无任何依赖库、API清晰明了。顺带一提,本教程只用到编码功能,也就是java对象 to XML文档。
让我们开始吧
首先下载附件中的压缩包,解压后用eclipse打开它(File - Import - General - Existing Projects into WorkSpace),目录结构在Project Explorer视图中应该是这样滴:
选中项目节点按Run as...按钮,选择Run on server(tomcat的配置问题我就不说了),运行结果如图:
可以看到这是一个双轴复合图表,所需的数据共有三组,其中两个是bar、一个是line。数据和样式的定义也不是本文讨论的范围,让我们看一下最终要传给fusioncharts的XML:
<chart numberSuffix="万" palette="3" lineThickness="5" showValues="0" labelDisplay="Rotate" slantLabels="1" areaOverColumns="0" useRoundEdges="1"> <categories> <category label="2009-09-01" /> <category label="2009-09-02" /> <category label="2009-09-03" /> </categories> <dataset seriesName="下载次数(万)" color="0372AB" showValue="0" lineThickness="2" yaxismaxvalue="100" anchorSides="10" anchorRadius="3" anchorAlpha="100" parentYAxis="P"> <set value="9.3519" /> <set value="6.9093" /> <set value="7.8966" /> </dataset> <dataset seriesName="费用(万)" color="8EAC41" showValue="0" yaxismaxvalue="100" anchorSides="10" anchorRadius="3" anchorAlpha="100" parentYAxis="P"> <set value="14.65065" /> <set value="11.44305" /> <set value="12.32055" /> </dataset> <dataset seriesName="全省KPI完成度(%)" color="FFB200" showValue="0" yaxismaxvalue="100" anchorAlpha="100" parentYAxis="S"> <set value="16.4487" /> <set value="23.6581" /> <set value="96.8973" /> </dataset> </chart>
下面要做的事可以分为4步:1、建立一个Chart对象,其中包含XML中的所有信息。2、用xstream类库设置XML的格式。3、将Chart对象转化为XML文档。4、扫尾工作。
建立Chart对象
比照着XML文档在vo包下面建立好Chart、Category、Dataset和Set四个对象,私有属性加上setter/getter,这个大家都熟。
然后在dao.DataProvider类的createChart方法中按照XML文档中的数据初始化这个Chart,我这里都是硬编码,大家可以根据需要从datasource里面取。
设置XML的格式
如果哪位跳过这一步直接进入步骤3,他一定会很失望的看到这样的XML:
<vo.Chart> ... </vo.Chart>
这是因为没有设置格式,教程里用到了3个相关的API:一是alias方法,用来为xml元素设置别名,这样<vo.Chart>就变成<chart>了;二是useAttributeFor方法,用来将子元素变为属性,例如<chart seriesName="xxx">;三是addImplicitCollection方法,让xstream不要显示Java Collection(教程里是List)的根元素。我只是蜻蜓点水的一带而过,欲知详情,一是参阅Xstream官方教程 、二是将DataProvider类chart2XML方法中对应的API注释掉对比一下。
Chart to XML
调用toXML这个API即可,返回一个String类型的字符串。
扫尾工作
将toXML返回的String传给fusioncharts后,我惊异的发现页面上一片空白。这里有两个暗雷需要扫除:一是要将XML中所有的双引号替换为单引号,这是因为index.jsp中18行setDataXML的参数就是一个字符串;二是要将XML中元素之间的空格去掉(这个bug我找了很久,怪异的fusioncharts)。用Matcher的replaceAll搞定它们。