Eclipse Birt 2.2 的发布,着实让我吓了一大跳,因为它的 Notable Features 一文中的亮点实在是多得惊人,比如交叉表、图表等等。
这次自己做的一个小软件里面需要用到Birt,反正是自己做来自己用的,也不用管IDE工具是否稳定,只要好用便行,就选了 Birt 2.2.0 这个版本,Eclipse 3.3.0(当时为了避免麻烦,直接下载的是 Eclipse-birt-all-in-one-2.2.0 这个全功能版)
现在我来说明一下,自己如何利用rptdesign格式的文件创建描述图表的xml格式的chart文件。
1.使用rptdesign文件创建chart文件
创建一个包含有图表的报表文件(由于创建报表的方法,网上、Eclipse官方都有大量的文献进行讲解,这里就不再赘述),结果如下图所示:
本来是打算使用Report Viewer,但是查看了网上的文章,虽然绝大多数都是讲解如何使用 Report Viewer 来显示以“rptdesign”为后缀的报表文件,但是也有大量文章指出 Report Viewer 难于扩展的问题,于是乎,在Eclipse创建图表项目的时候,关注了一下项目中自动生成的使用 Chart 标签在网页中显示图表的示例
这三个自动生成的与图表在网页中显示的文件是:index.jsp,SampleBar.chart,SamplePie.chart。
由于,之前创建的报表文件也是使用圆饼图,所以比对该报表文件与SamplePie.chart中的内容,不难发现,其中有一部分内容的xml定义是一致的。它们起始的一段代码均为:
<?xml version="1.0" encoding="UTF-8"?> <model:ChartWithoutAxes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:attribute="http://www.birt.eclipse.org/ChartModelAttribute" xmlns:layout="http://www.birt.eclipse.org/ChartModelLayout" xmlns:model="http://www.birt.eclipse.org/ChartModel" xmlns:type="http://www.birt.eclipse.org/ChartModelType"> <Type>Pie Chart</Type> <SubType>Standard Pie Chart</SubType> ……
结束均为
</SeriesDefinitions> <MinSlicePercent>false</MinSlicePercent> </model:ChartWithoutAxes>
rtpdesign格式的文件中的这段内容嵌套在标签<![CDATA[……]>之间,将这段内容单独拷贝出来,取名为 xx.chart
2.定义数据源
下载包“birt-source-2_2_0.zip ”,这里有一个类名为 SampleHelper.java 的源代码,参考它的方法 createSampleEvaluator() 中的代码,大致可以了解到如何创建自己的数据源。
由于准备使用iBatis、hibernate等ORM框架,所以通常数据的返回值为List,而List中的每个对象元素是表示一行数据的Map对象,于是在SampleHelper中增加自己的方法,来处理这种情况,其代码如下:
public static final IDataRowExpressionEvaluator createEntSumDataSet( Collection dataColl, String categoryName, String valueName) { if (dataColl == null || StringUtils.isEmpty(categoryName) || StringUtils.isEmpty(valueName)) { throw new RuntimeException("数据集合、分类名称、数据名称三个参数不能为空!"); } if (dataColl.size() <= 0) { throw new RuntimeException("数据集合所包含的数据行不能小于或等于0!"); } String[] columnSet = new String[] { "row[\"" + categoryName + "\"]", "row[\"" + valueName + "\"]" }; Object[][] dataSet = new Object[2][dataColl.size()]; int rowIndex = 0; for (Iterator iterator = dataColl.iterator(); iterator.hasNext(); rowIndex++) { Map rowMap = (Map) iterator.next(); dataSet[0][rowIndex] = rowMap.get(categoryName); dataSet[1][rowIndex] = new Integer ((String) rowMap.get(valueName)); } return new SampleDataRowEvaluator(set, data); }
参数中,dataColl就是我们之前提到的ORM返回的数据集合, categoryName 是我们指定的饼图的每个分块的名称,而 valueName 则表示我们指定的分块对应的数据内容(由于我的 rptdesign 文件中,数据内容为数值,所以这里需要将 valueName 这一列所对应的数据全部转换为数值类型)
从上面代码不难看出,categoryName 和 valueName 分别表示的是数据的两列的列名;dataSet的一维下标为列下标,二维下标为每一列的第几行
3.页面中显示图表
在index.jsp中添加如下代码:
<% // 定义数据源 ArrayList dataList = new ArrayList(); HashMap rowMap = new HashMap(); rowMap.put("entcls", "国有企业"); rowMap.put("count", "100"); dataList.add(rowMap); rowMap = new HashMap(); rowMap.put("entcls", "私营企业"); rowMap.put("count", "55"); dataList.add(rowMap); rowMap = new HashMap(); rowMap.put("entcls", "外资企业"); rowMap.put("count", "99"); dataList.add(rowMap); rowMap = new HashMap(); rowMap.put("entcls", "独资企业"); rowMap.put("count", "129"); dataList.add(rowMap); rowMap = new HashMap(); rowMap.put("entcls", "个体工商户"); rowMap.put("count", "392"); dataList.add(rowMap); rowMap = new HashMap(); rowMap.put("entcls", "合资企业"); rowMap.put("count", "112"); dataList.add(rowMap); rowMap = new HashMap(); rowMap.put("entcls", "三资企业"); rowMap.put("count", "231"); dataList.add(rowMap); rowMap = new HashMap(); rowMap.put("entcls", "股份企业"); rowMap.put("count", "890"); dataList.add(rowMap); rowMap = new HashMap(); rowMap.put("entcls", "垄断企业"); rowMap.put("count", "190"); dataList.add(rowMap); rowMap = new HashMap(); rowMap.put("entcls", "私人独资企业"); rowMap.put("count", "120"); dataList.add(rowMap); rowMap = new HashMap(); rowMap.put("entcls", "注册企业"); rowMap.put("count", "790"); dataList.add(rowMap); rowMap = new HashMap(); rowMap.put("entcls", "注册企业2"); rowMap.put("count", "790"); dataList.add(rowMap); %> Pie chart (PNG FROM RPTDESIGN): <br> RealPath:<%=session.getServletContext().getRealPath( "qyjbxxReport.chart")%><br> <!-- xx.chart 放在 Eclipse 网络项目的 WebContent 文件夹下面 --> <chart:renderChart width="600" height="500" output="jpg" model="<%=session.getServletContext().getRealPath("xx.chart") %>" data="<%=CreditEntSum.createCreditEntSumDataSet(dataList, "entcls ", "count ") %>"> </chart:renderChart> <br>
报表的xml文件xx.chart中需要做出相应的修改,以保证,能够顺利找到需要的列和数据
两处修改后的内容如下:
<DataDefinition> <Definition>row["count"] </Definition> </DataDefinition> <SeriesIdentifier>统计数量</SeriesIdentifier> <DataDefinition> <Definition>row["entcls"] </Definition> </DataDefinition> <SeriesIdentifier>行业分类</SeriesIdentifier>
上面的黑体字与页面中调用方法 createEntSumDataSet 的参数,和数据源代码中的方法 createEntSumDataSet 中的代码的 columnSet 定义的语句中的内容,一一对应起来,使得 xx.chart 能够从 SampleHelper 中获得所需要的列与数据信息
4.运行index.jsp页面
所得结果如下:
附注:
下载 birt-source-2_2_0.zip 这个源代码包的过程,是一个极其痛苦的过程,官方网站上面的下载链接突然失效,后来才知道是服务器无法连接,在网上搜索了很久未果,最终竟然想到镜像,于是用关键字“birt mirror ……”搜索到一个网站“http://www.mirrorservice.org/sites/download.eclipse.org/eclipseMirror/birt/”,这里有着最新的Birt以及Eclipse相关的资料。
之所以要下载到这个源代码包,就是为了 研究一下SampleHelper到底使用了什么方法来提供数据源给那些图表的。