条件不一致的动态运算

【问题】

折线图 X 轴已时间为刻度 可以实现根据条件不一样显示的列不一样 

比如统计最近一个小时每隔 5 分钟显示一列   统计一天 每隔 1 小时显示一列 统计一周  每隔 1 天显示一列

但是没法实现条件不一样合计的数据跟着变化

就是想实现当条件是一小时时 

条件是一天时:

条件是一周时:

想动态修改 grouping 中 unit 和 interval

修改 X 轴的刻度是网上找的的方法:

importPackage(Packages.org.eclipse.birt.chart.model.data.impl);
importPackage(Packages.java.text);
importPackage(Packages.java.util);
importPackage(Packages.java.lang);

function beforeGeneration(chart, icsc)
{    //01 小时  02 天  03 周
    var type = icsc.getExternalContext().getScriptable().getParameterValue(“type”);
    var stime = icsc.getExternalContext().getScriptable().getParameterValue(“start”);
    var etime = icsc.getExternalContext().getScriptable().getParameterValue(“end”);
    var sh = icsc.getExternalContext().getScriptable().getParameterValue(“sh”);
    var eh = icsc.getExternalContext().getScriptable().getParameterValue(“eh”);

    var format = new SimpleDateFormat(“yyyy-MM-dd”);
    var timeFormat = new SimpleDateFormat(“yyyy-MM-dd HH:mm”);
    var scal = Calendar.getInstance();
    var ecal = Calendar.getInstance();
    var scalH =  Calendar.getInstance();
    var ecalH =  Calendar.getInstance();

    var sd = format.parse(stime);
    var ed = format.parse(etime);
    var sdh = timeFormat.parse(sh);
    var edh = timeFormat.parse(eh);
    scal.setTime(sd);
    ecal.setTime(ed);    
    scalH.setTime(sdh);
    ecalH.setTime(edh);

    var xAxisArray = chart.getAxes();
    xAxisArray[0].setCategoryAxis(false);
     //xAxisArray[0].getGroup().setInterval(2);
 //
 //    chart.setUnits(“Days”);

    if(type==‘01’){
      xAxisArray[0].getScale().setMin(DateTimeDataElementImpl.create(scalH.getTimeInMillis()));
      xAxisArray[0].getScale().setMax(DateTimeDataElementImpl.create(ecalH.getTimeInMillis()));
      xAxisArray[0].getScale().setUnit(xAxisArray[0].getScale().getUnit().MINUTES_LITERAL);
      xAxisArray[0].getScale().setStep(5);

    }else if(type==‘02’){
      xAxisArray[0].getScale().setMin(DateTimeDataElementImpl.create(scal.getTimeInMillis()));
      xAxisArray[0].getScale().setMax(DateTimeDataElementImpl.create(ecal.getTimeInMillis()));
      xAxisArray[0].getScale().setUnit(xAxisArray[0].getScale().getUnit().HOURS_LITERAL);
      xAxisArray[0].getScale().setStep(1);

    } else {
      xAxisArray[0].getScale().setMin(DateTimeDataElementImpl.create(scal.getTimeInMillis()));
      xAxisArray[0].getScale().setMax(DateTimeDataElementImpl.create(ecal.getTimeInMillis()));
      xAxisArray[0].getScale().setUnit(xAxisArray[0].getScale().getUnit().DAYS_LITERAL);
      xAxisArray[0].getScale().setStep(1);

    }
}

【回答】

报表工具擅长处理规则一致的数据,而这种条件不一致的动态运算在报表中是很难实现的。更好的的做法是先写段程序把数据源准备好,然后传给 BIRT 再去画图,而不是在 BIRT 中去直接处理这种数据并画图,推荐使用 SPL 生成动态数据,其中丰富的集合运算可以方便地完成这类计算:

A B
1 =[]
2 if(type==“hour”) >A1=12.(elapse@s(now(),-5*60*~))
3 else if(type==“day”) >A1=24.(elapse@s(now(),-60*60*~))
4 else if(type==“week”) >A1=7.(elapse(now(),-~))
5 =A1.(demo.query(“select sum(v)  from tv where t>? and t<=?”,~, ifn(~[-1],now())))
6 result A5

A1: 需要生成的时间间隔数据集

A2-B2:统计最近一小时,每 5 分钟一条,生成 12 条时间间隔

A3-B3:统计最近一天,每小时一条,生成 24 条时间间隔

A4-B4:统计最近一周,每天一条,生成 7 条时间间隔

A5:按照时间间隔统计求和

A6:返回统计结果

BIRT 可以通过 JDBC 连接集算器,调用脚本方法和调用存储过程一样,详情参考【BIRT 调用 SPL 脚本​】。