条件不一致的动态运算
【问题】
折线图 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 脚本】。