利用Eclipse Birt 2.2 的 Chart 标签库打造网页图表

    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官方都有大量的文献进行讲解,这里就不再赘述),结果如下图所示:

 

Birt 2.2 图1

 

    本来是打算使用Report Viewer,但是查看了网上的文章,虽然绝大多数都是讲解如何使用 Report Viewer 来显示以“rptdesign”为后缀的报表文件,但是也有大量文章指出 Report Viewer 难于扩展的问题,于是乎,在Eclipse创建图表项目的时候,关注了一下项目中自动生成的使用 Chart 标签在网页中显示图表的示例

 

 Birt 2.2 图2

 

    这三个自动生成的与图表在网页中显示的文件是: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[&quot;count&quot;] </Definition>
    </DataDefinition>
    <SeriesIdentifier>统计数量</SeriesIdentifier>


   <DataDefinition>
    <Definition>row[&quot;entcls&quot;] </Definition>
   </DataDefinition>
   <SeriesIdentifier>行业分类</SeriesIdentifier>

 

    上面的黑体字与页面中调用方法 createEntSumDataSet 的参数,和数据源代码中的方法 createEntSumDataSet 中的代码的 columnSet 定义的语句中的内容,一一对应起来,使得 xx.chart 能够从 SampleHelper 中获得所需要的列与数据信息

4.运行index.jsp页面

    所得结果如下:

 

Birt 2.2 图3

 

附注:

    下载 birt-source-2_2_0.zip 这个源代码包的过程,是一个极其痛苦的过程,官方网站上面的下载链接突然失效,后来才知道是服务器无法连接,在网上搜索了很久未果,最终竟然想到镜像,于是用关键字“birt mirror ……”搜索到一个网站“http://www.mirrorservice.org/sites/download.eclipse.org/eclipseMirror/birt/”,这里有着最新的Birt以及Eclipse相关的资料。

    之所以要下载到这个源代码包,就是为了 研究一下SampleHelper到底使用了什么方法来提供数据源给那些图表的。

你可能感兴趣的:(eclipse,jsp,Hibernate,xml,ibatis)