使用multipleDataSet绘制timeSeriex图表或在JRBeanCollectionDataSource中传递Collection对象

时间:2014-10-09 12:28:31

标签: java jasper-reports

实际上我必须使用 JasperReports 绘制timeSeries。

如何为不同的数据集生成时间序列图?当我有一个数据集在一段时间内绘制时,我能够生成时间序列图。但是,当我有多个数据集进行绘图时,我面临着问题。

我正在使用列表数据源。

public class KpiReportPoints {
    private String deviceDn;
    private List<KpiReportPoint> kpiPoints;
}

public class KPiReportPoint{
    private Date time;
    private Double value;

   public Date getTime() {
      return time;
   }

   public void setTime(Date time) {
      this.time = time;
   }

   public Double getValue() {
      return value;
   }

   public void setValue(Double value) {
      this.value = value;
   }

   @Override
   public int hashCode() {
      return time.hashCode();
   }

   @Override
   public boolean equals(Object obj) {
      boolean equal = false;
      if (obj instanceof KPIReportPoint){
         KPIReportPoint point  = (KPIReportPoint) obj;
         equal = time.equals(point.getTime())&& value.equals(point.getValue());
      }
      return equal;
   }

   @Override
   public int compareTo(KPIReportPoint o) {
      return this.time.compareTo(o.getTime());
   }
}

上述两个类都有他们的getter和setter,并且都是公共的,所以根据我的问题,每个类的定义都没有。我正在路过人口稠密的人 List<KpiReportPoints>JRBEanCollectionDataSource(kpiReportpointsList);

现在下面是我的jrxml:

<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="KPI_Reports" pageWidth="842" pageHeight="595" orientation="Landscape" columnWidth="802" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
    <subDataset name="Dataset">
        <field name="time" class="java.util.Date"/>
        <field name="value" class="java.lang.Double"/>
    </subDataset>
    <parameter name="X_UNIT" class="java.lang.String">
        <parameterDescription><![CDATA[]]></parameterDescription>
        <defaultValueExpression><![CDATA["Date"]]></defaultValueExpression>
    </parameter>
    <parameter name="Y_UNIT" class="java.lang.String">
        <parameterDescription><![CDATA[]]></parameterDescription>
        <defaultValueExpression><![CDATA["%"]]></defaultValueExpression>
    </parameter>
    <parameter name="REPORT_NAME" class="java.lang.String">
        <defaultValueExpression><![CDATA["KPI Report"]]></defaultValueExpression>
    </parameter>
    <parameter name="from" class="java.util.Date"/>
    <parameter name="to" class="java.util.Date"/>
    <field name="deviceDn" class="java.lang.String"/>
    <field name="kpiPoints" class="java.util.List"/>
    <background>
        <band splitType="Stretch"/>
    </background>
    <title>
        <band height="20" splitType="Stretch">
            <textField pattern="EEE, d MMM yyyy HH:mm:ss Z" isBlankWhenNull="true">
                <reportElement x="513" y="0" width="253" height="20"/>
                <textElement/>
                <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression>
            </textField>
        </band>
    </title>
    <summary>
        <band height="443">
            <timeSeriesChart>
                <chart isShowLegend="true" customizerClass="com.ipaccess.nos.business.pm.impl.KPIChartCustomizer">
                    <reportElement mode="Opaque" x="0" y="0" width="766" height="443" isPrintInFirstWholeBand="true"/>
                    <chartTitle position="Top">
                        <font size="14" isBold="true" pdfFontName="Courier-Bold" isPdfEmbedded="true"/>
                        <titleExpression><![CDATA[$P{REPORT_NAME}]]></titleExpression>
                    </chartTitle>
                    <chartSubtitle/>
                    <chartLegend position="Bottom"/>
                </chart>
                <timeSeriesDataset timePeriod="Second">
                    <datasetRun subDataset="Dataset">
                        <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{kpiPoints})]]></dataSourceExpression>
                    </datasetRun>
                    <timeSeries>
                        <seriesExpression><![CDATA[$F{deviceDn}]]></seriesExpression>
                        <timePeriodExpression><![CDATA[$F{time}]]></timePeriodExpression>
                        <valueExpression><![CDATA[$F{value}]]></valueExpression>
                    </timeSeries>
                </timeSeriesDataset>
                <timeSeriesPlot isShowLines="true" isShowShapes="true">
                    <plot labelRotation="90.0"/>
                    <timeAxisLabelExpression><![CDATA[$P{X_UNIT}]]></timeAxisLabelExpression>
                    <valueAxisLabelExpression><![CDATA[$P{Y_UNIT}]]></valueAxisLabelExpression>
                    <valueAxisFormat>
                        <axisFormat>
                            <labelFont>
                                <font size="10"/>
                            </labelFont>
                        </axisFormat>
                    </valueAxisFormat>
                    <domainAxisMinValueExpression><![CDATA[$P{from}]]></domainAxisMinValueExpression>
                    <domainAxisMaxValueExpression><![CDATA[$P{to}]]></domainAxisMaxValueExpression>
                </timeSeriesPlot>
            </timeSeriesChart>
        </band>
    </summary>
</jasperReport>

这个问题是jrxml编译好了但是在尝试生成报告时会引发异常:

[#|2014-10-10T09:59:05.769+0530|SEVERE|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=290;_ThreadName=Thread-3;|net.sf.jasperreports.engine.JRException: Error retrieving field value from bean : time
        at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getBeanProperty(JRAbstractBeanDataSource.java:127)
        at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getFieldValue(JRAbstractBeanDataSource.java:100)
        at net.sf.jasperreports.engine.data.JRBeanCollectionDataSource.getFieldValue(JRBeanCollectionDataSource.java:104)
    at net.sf.jasperreports.engine.fill.JRFillData

我对此问题感到非常生气,并且在上面的代码中找不到任何可能导致此问题的问题。如果你们中的任何人能够看到并且有任何时间遇到这个错误,那么请告诉我一些有关错误的线索。

2 个答案:

答案 0 :(得分:0)

我猜问题就在这里。

public class KpiReportPoints {
    private String deviceDn;
    private List<KpiReportPoint> kpiPoints;
}

您正在传递KpiReportPoints列表,这很好,但列表中还会包含private List<KpiReportPoint> kpiPoints;列表本身。

Jasper Report的问题在于它会识别JRBEanCollectionDataSource(kpiReportpointsList),并会抓取deviceDnkpiPoints。现在,因为你有一个字段$F{deviceDn}deviceDn字符串是一个完美的匹配。没问题,直到这里。

问题部分: 当它获取kpiPoints时,现在Jasper Report将从该列表中获取值并填充报告,因为它是not the primitive type

解决方案: 我建议您使用Custom Data Sourceredesign您的报告,以便它识别kpiPoints列表,并进一步从该列表中获取值并填写报告。

答案 1 :(得分:0)

您说: “我将填充的列表作为JRBEanCollectionDataSource(kpiReportpointsList)传递;”

您应该将其作为列表传递,因为模板需要在以下位置使用列表:

<datasetRun subDataset="Dataset">
    <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{kpiPoints})]] </dataSourceExpression>
</datasetRun> 

您必须使用Java:

List<KPiReportPoint> yourList = new ArrayList<KPiReportPoint>();
// fill the list with values
// ...............
// end fill

mapParams.put("kpiPoints", yourList);
// fill the compiled report
JasperFillManager.fillReport(yourReport, mapParams, new JREmptyDataSource());