先看这样一份需求:数据库中相同的时间点(如2010-12-7 11:33:30 到时分秒)有很多条数据,要让他们同时显示在图中。
这就要用到时序图,而时序图中X轴的一个时间点只能显示一条数据,为了让他们同时显示,这里有个办法,可能不是很完善,不过也是目前想出的解决办法了,看程序.
JFreeChart chart = null;
TimeSeriesCollection lineDataset = new TimeSeriesCollection();
TimeSeries series = new TimeSeries("", Millisecond.class);//这里定义毫秒级
String SecSecond = null;
double dobTempData = 0.00;
double dobData = 0.00;
// 最大值
double dobMax = 0.00;
// 最小值
double dobMin = 0.00;
int intTemp = 1;
for (int i = 0; i < list.size(); i++) {
// list中第一条记录的第一个值是ID,第二个值是时间,第三个值是房间温度,第四个值是房间位置
Object[] object = (Object[]) list.get(i);
//从数据库中取出来的时间 如2010-12-03 09:10:20一直到时分秒
Date date = TransferUtil.transferToUtilTime(object[1].toString());
if (null != date) {
String secTemp = String.valueOf(date.getHours())
+ String.valueOf(date.getMinutes())
+ String.valueOf(date.getSeconds());
dobTempData = Double.parseDouble(object[2].toString());
if (i == 0) {
dobMax = dobTempData;//把第一条记录中的温度值记为最大值,以便为Y轴设最大值
dobMin = dobTempData;//把第一条记录中的温度值记为最小值,以便为Y轴设最小值
//这样做是因为数据库中相同的时间点有很多数据,而在时序图中一个时间点只显示一个数据,所以想办法让这些数据都显示出来
SecSecond = secTemp;//记录第一条记录中的时间
dobData = dobTempData;//记录第一条记录中的温度值
} else {
if (SecSecond.equals(secTemp)) {
//如果当前循环到的时间与前一条记录中的时间相同,就把这个时间加1ms
//因为X轴上显示的是小时,所以不影响显示效果
date = new Date(date.getTime() + intTemp);
intTemp++;
secTemp = date.toString();
if (dobData != dobTempData) {
series.addOrUpdate(new Millisecond(date),
dobTempData);
dobData = dobTempData;
}
} else {
//如果当前循环到的时间与前一条记录中的时间不相同
intTemp = 1;
if ((!SecSecond.equals(secTemp))
|| (dobData != dobTempData)) {
series.addOrUpdate(new Millisecond(date),
dobTempData);
SecSecond = secTemp;
dobData = dobTempData;
}
}
if (dobTempData > dobMax) {
dobMax = dobTempData;
}
if (dobTempData < dobMin) {
dobMin = dobTempData;
}
}
}
}
lineDataset.addSeries(series);
chart = CreateFoldLineChart.createChart(lineDataset, "", "", "");
double dobBaseTemp = Double.parseDouble(baseTemp);
if (dobBaseTemp > dobMax) {
dobMax = dobBaseTemp;//这里找到最大值
}
dobMax = dobMax + 0.1;
if (dobBaseTemp < dobMin) {
dobMin = dobBaseTemp;//这里找到最小值
}
dobMin = dobMin - 0.1;
XYPlot xyplot = chart.getXYPlot();
// 数据轴精度
NumberAxis na = (NumberAxis) xyplot.getRangeAxis();
// 设置Y轴最大值
if (dobMax > Float.parseFloat(baseTemp)) {
na.setUpperBound(dobMax);
} else {
na.setUpperBound(Float.parseFloat(baseTemp));
}
// 设置Y轴最小值
if (dobMin < Float.parseFloat(baseTemp)) {
na.setLowerBound(dobMin);
} else {
na.setLowerBound(Float.parseFloat(baseTemp));
}
na.setAutoRangeIncludesZero(true);
// 设置纵坐标间隔
na.setTickUnit(new NumberTickUnit((double) 0.5));
// 因为点太密集,数据也就重叠在一起,所以设置折点数据不可见
xyplot.getRenderer().setItemLabelsVisible(false);
// 开始设置基准温度曲线
ValueMarker valuemarker = new ValueMarker(Double.parseDouble(baseTemp));
valuemarker.setLabelOffsetType(LengthAdjustmentType.EXPAND);
valuemarker.setPaint(Color.BLUE);
valuemarker.setStroke(new BasicStroke(1.0F)); // valuemarker.setLabel(label);
valuemarker.setLabelFont(new Font("SansSerif", 0, 11));
valuemarker.setLabelPaint(Color.blue);
valuemarker.setLabelAnchor(RectangleAnchor.TOP_LEFT);
valuemarker.setLabelTextAnchor(TextAnchor.BOTTOM_LEFT);
valuemarker.setLabelOffset(new RectangleInsets(5, 5, 5, 5));
float[] f = { 2, 4, 2, 4 }; // setStroke将基准线设置为虚线,float[]数组实现
valuemarker.setStroke(new BasicStroke(2.0f, 1, 1, 0, f, 1.0f));
xyplot.addRangeMarker(valuemarker, Layer.BACKGROUND);
效果如图:(蓝色是一条基准线)