使用Jfreechart时,我的X轴数据TimeSeries的时间跨度是从0-23点,可是我发现当数据中包含12点的时候,TimeSeries会自动将该时间设置为0点,难道是要将X轴设置为24小时制?但是貌似除了12点有问题外,它默认的是为24小时制的。求解!
代码如下:
package com.sinocrm.utils;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import org.apache.poi.hssf.usermodel.*;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardXYItemLabelGenerator;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.*;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.TextAnchor;
import sun.awt.image.codec.JPEGImageEncoderImpl;
import sun.tools.jar.resources.jar_fr;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
* Created by ds on 14-7-11.
* 创建一个横坐标为时间的图标
*/
public class JfreeChartUtil {
/**
* 设置工厂创建的图表样式
* 此设置主要解决中文乱码问题
*/
private static void setCNTheme() {
//创建主题样式
StandardChartTheme standardChartTheme = new StandardChartTheme("CN");
//设置标题字体
standardChartTheme.setExtraLargeFont(new Font("隶书", Font.BOLD, 20));
//设置图例的字体
standardChartTheme.setRegularFont(new Font("宋书", Font.PLAIN, 15));
//设置轴向的字体
standardChartTheme.setLargeFont(new Font("宋书", Font.PLAIN, 15));
//设置画布背景为白色
standardChartTheme.setPlotBackgroundPaint(Color.white);
//设置网格竖线颜色为红色
standardChartTheme.setDomainGridlinePaint(Color.pink);
//设置网格横线颜色为红色
standardChartTheme.setRangeGridlinePaint(Color.pink);
//设置曲线图与XY轴的距离
standardChartTheme.setAxisOffset(new RectangleInsets(0d, 0d, 0d, 0d));
//应用主题样式
ChartFactory.setChartTheme(standardChartTheme);
}
/**
* 创建一个横坐标为时间,只有一个序列的折线图
*
* @param title 图形的title
* @param yLabel Y轴的标签
* @param seriesName 序列的名称(用于图例显示)
* @param list 数据集合(object[]数据中第一个参数为时间(String或者是date),第二参数为具体数据
* @return
*/
public static JFreeChart createTimeSeriesChart(String title, String yLabel, String seriesName, List<Object[]> list) {
//设置画布的默认主题
setCNTheme();
//创建图形线
XYDataset dataset = createDataset(seriesName, list);
//创建图形
return createTimeChart(title, yLabel, dataset);
}
/**
* 创建一个横坐标为时间,只有一个序列的折线图
*
* @param title 图形的title
* @param yLabel Y轴的标签
* @param seriesName 序列的名称集合,与data的长度一致(用于图例显示)
* @param data 数据按照序列集合存放(object[]数据中第一个参数为时间(String或者是date),第二参数为具体数据 )
* @return
*/
public static JFreeChart createTimeSeriesChart(String title, String yLabel, String[] seriesName, List<List<Object[]>> data) {
//设置画布的默认主题
setCNTheme();
//创建图形线
XYDataset dataset = createDataset(seriesName, data);
//创建图形
return createTimeChart(title, yLabel, dataset);
}
/**
* 用给定数据集创建一个时间折线图
*
* @param title 图title m
* @param yLabel Y轴标签
* @param dataset 数据集合
* @return <code>JFreeChart</code>
*/
private static JFreeChart createTimeChart(String title, String yLabel, XYDataset dataset) {
//获取X轴的标签
String xLabel = "时间",format = "yyyy-MM-dd";
Number t1 = dataset.getX(0, 0),t2 = dataset.getX(0, dataset.getItemCount(0) - 1);
Date d1 = new Date(t1.longValue()),d2= new Date(t2.longValue());
if(MyUtils.compareDate(d1,d2,format)==0){
xLabel += "("+MyUtils.dateToStr(d1,format)+")";
}else {
xLabel += "("+MyUtils.dateToStr(d1,format)+"至"+MyUtils.dateToStr(d2,format)+")";
}
JFreeChart freeChart = createTimeChart(title, xLabel, yLabel, dataset);
return freeChart;
}
/**
* 用给定数据集创建一个时间折线图
*
* @param title 图title m
* @param xLabel x轴标签
* @param yLabel Y轴标签
* @param dataset 数据集合
* @return <code>JFreeChart</code>
*/
private static JFreeChart createTimeChart(String title, String xLabel,String yLabel, XYDataset dataset) {
JFreeChart freeChart = ChartFactory.createTimeSeriesChart(title, xLabel, yLabel, dataset);
//设置X轴的时间格式
/*XYPlot xyplot = freeChart.getXYPlot();
DateAxis dateaxis = (DateAxis)xyplot.getDomainAxis();
SimpleDateFormat sfd = new SimpleDateFormat("HH:mm");
dateaxis.setRange(MyUtils.strToDate("00:00:00","HH🇲🇲ss"),MyUtils.strToDate("23:59:59","HH🇲🇲ss"));
dateaxis.setDateFormatOverride(sfd);
xyplot.setDomainAxis(dateaxis);*/
/* 设置是否显示数据点并且显示具体数据信息
//设置数据样式
XYPlot plot = freeChart.getXYPlot();
XYLineAndShapeRenderer lineRender = (XYLineAndShapeRenderer) plot.getRenderer();
//是否显示数据点
lineRender.setBaseShapesVisible(true);
//显示数据点
XYItemRenderer itemRenderer = plot.getRenderer();
itemRenderer.setBaseItemLabelsVisible(true);
itemRenderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_LEFT));
itemRenderer.setBaseItemLabelGenerator(new StandardXYItemLabelGenerator());
plot.setRenderer(itemRenderer);*/
return freeChart;
}
/**
* 创建数据集合
*
* @param collection 用于装载多序列的集合
* @param seriesName 序列名称
* @param dataList 序列数据的集合
* @return <code>TimeSeriesCollection</code>
*/
private static TimeSeriesCollection createDataset(TimeSeriesCollection collection, String seriesName, List<Object[]> dataList) {
if (collection == null) {
collection = new TimeSeriesCollection();
}
TimeSeries timeSeries = new TimeSeries(seriesName);
Date date;
double data;
for (Object[] objects : dataList) {
if (objects == null || objects.length < 2 || objects[0] == null || objects[1] == null) {
continue;
}
if (objects[0] instanceof Date) {
date = (Date) objects[0];
} else {
date = MyUtils.strToDateTime(objects[0].toString());
}
if (objects[1] instanceof Integer) {
data = (Integer) objects[1] - 0.0;
} else {
data = Double.parseDouble(objects[1].toString());
}
timeSeries.add(new Second(date), data);
}
collection.addSeries(timeSeries);
return collection;
}
/**
* 创建只有单个序列的数据集合
*
* @param seriesName 序列名称
* @param dataList 序列数据的集合
* @return <code>TimeSeriesCollection</code>
*/
private static TimeSeriesCollection createDataset(String seriesName, List<Object[]> dataList) {
return createDataset(null, seriesName, dataList);
}
/**
* 创建包含多个序列的数据集合
*
* @param seriesName 序列名称
* @param dataList 序列数据的集合
* @return <code>TimeSeriesCollection</code>
*/
private static TimeSeriesCollection createDataset(String[] seriesName, List<List<Object[]>> dataList) {
TimeSeriesCollection collection = new TimeSeriesCollection();
int index = 0;
List<Object[]> temp;
for (String name : seriesName) {
temp = dataList.get(index++);
createDataset(collection, name, temp);
}
return collection;
}
/**
* 将生成的图表信息导出到Excel文件中
*
* @param freeChart 图表
* @param workbook Excel工作簿 g
* @param sheetName 创建的工作区的名称
* @throws IOException
*/
public static void exportChartToExcel(JFreeChart freeChart, HSSFWorkbook workbook, String sheetName) throws IOException {
HSSFSheet sheet = workbook.createSheet(sheetName);
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 100, 50, (short) 1, 1, (short) 15, 25);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ChartUtilities.writeChartAsJPEG(outputStream, freeChart, 1000, 500);
patriarch.createPicture(anchor, workbook.addPicture(outputStream.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
}
/**
* 将生成的图表信息导出到Excel文件中
*
* @param freeCharts 图表集合
* @param workbook Excel工作簿 g
* @param sheetName 创建的工作区的名称
* @throws IOException
*/
public static void exportChartToExcel(JFreeChart[] freeCharts, HSSFWorkbook workbook, String sheetName) throws IOException {
int row1 = 1, row2 = 25, index = 0;
HSSFSheet sheet = workbook.createSheet(sheetName);
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
HSSFClientAnchor anchor;
ByteArrayOutputStream outputStream;
for (JFreeChart freeChart : freeCharts) {
anchor = new HSSFClientAnchor(0, 0, 100, 50, (short) 1, row1, (short) 15, row2);
outputStream = new ByteArrayOutputStream();
ChartUtilities.writeChartAsJPEG(outputStream, freeChart, 1000, 500);
patriarch.createPicture(anchor, workbook.addPicture(outputStream.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
row2 += 28;
row1 += 28;
}
}
public void testExportToExcel() throws IOException {
List list = new ArrayList();
Object[] objects;
double[] data = {2.1, 3.2, 4.4, 3.8, 5.6, 1.2, 3, 5, 5.2, 2.4, 2.2, 1, 3, 4, 2, 1, 1, 2};
for (int i = 13; i < 23; i++) {
objects = new Object[]{"2014-7-11 " + i + ":10:12", data[i - 13]};
list.add(objects);
}
for (int i = 0; i < 8; i++) {
objects = new Object[]{"2014-7-12 " + i + ":30:12", data[i]};
list.add(objects);
}
JFreeChart[] freeCharts = new JFreeChart[3];
freeCharts[0] = JfreeChartUtil.createTimeSeriesChart("测试图例1", "Y轴", "序列一", list);
freeCharts[1] = JfreeChartUtil.createTimeSeriesChart("测试图例2", "Y轴", "序列er一", list);
freeCharts[2] = JfreeChartUtil.createTimeSeriesChart("测试图例3", "Y轴", "序列3一", list);
String filePath = "H:/test_file/jFreeChart/excels/test.xls";
HSSFWorkbook workbook = new HSSFWorkbook();
JfreeChartUtil.exportChartToExcel(freeCharts, workbook, "图表");
OutputStream fos = null;
try {
File file = new File(filePath);
if (file.getParent() != null && !file.exists()) {
file.mkdirs();
}
fos = new FileOutputStream(filePath);
HSSFSheet sheet = workbook.createSheet("test");
for (int i = 0; i < 5; i++) {
HSSFRow row = sheet.createRow(i);
for (int j = 0; j < 6; j++) {
HSSFCell cell = row.createCell(j);
cell.setCellValue(i + ":" + j);
}
}
workbook.write(fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos != null) {
fos.close();
}
}
}
public static void testExportToImg() throws IOException {
List list = new ArrayList();
Object[] objects;
double[] data = {2.1, 3.2, 4.4, 3.8, 5.6, 1.2, 3, 5, 5.2, 2.4, 2.2, 1, 3, 4, 2, 1, 1, 2};
for (int i = 12; i < 23; i++) {
objects = new Object[]{"2014-7-11 " + i + ":10:12", data[i - 12]};
list.add(objects);
}
/*for (int i = 0; i < 8; i++) {
objects = new Object[]{"2014-7-12 " + i + ":30:12", data[i]};
list.add(objects);
}*/
JFreeChart jFreeChart = JfreeChartUtil.createTimeSeriesChart("测试图例1","Y轴", "序列一", list);
BufferedImage bufferedImage = jFreeChart.createBufferedImage(800, 400);
OutputStream outputStream = new FileOutputStream("H:\\test_file\\jFreeChart\\images\\test.jpeg");
JPEGImageEncoder encoder = new JPEGImageEncoderImpl(outputStream);
encoder.encode(bufferedImage);
outputStream.flush();
outputStream.close();
}
public static void main(String[] args) throws IOException {
testExportToImg();
}
}
12点的值默认被置为0点了,这样的话,如果我的时间是从0点到23点的话,那么生成图形就会因为时间重复而报错,请各位帮我分析一下原因,O(∩_∩)O谢谢
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
O(∩_∩)O哈哈~终于找到答案了,还是看源码来的比较快点额。
分析一下:如果说format中使用yyyy-MM-ddHH:mm:ss得到的结果是24小时制的,那么使用calendar.get(Calendar.HOUR_OF_DAY)来获取实际的hour值,也应该是24小时制的。也就是说如果hour==12,那么返回结果应该还是12;如果当hour>12时,得到的结果是诸如13......。但是问题就是当>12时,结果返回正常;当==12时结果就成了0。
推测一下:通过setTime()获取的Calendar默认是12小时制的,那么时间周期就是0-11,12就会被认为是归零,而当hour>12时,Calendar会默认为24小时制,时间周期就是0-23,当24的时候也会被归零。我们已经知道通过Hour_Of_Day跟Hour来区分获取的是24小时制还是12小时制,那么通过设置Calendar的Hour_of_Day就可以告诉Calendar我当前用的是24小时制。所以这个就是解决方案。
//用于设置为24小时制if(StringUtils.isNotEmpty(dateStr)){//dateStr是获取的日期的hour值calendar.setTime(date);calendar.set(Calendar.HOUR_OF_DAY,Integer.valueOf(dateStr));date=calendar.getTime();}不错,虽然我用jfreechart没碰到过这个问题,但是你的分析结果,我看懂了,以后碰到这样的问题就有思路了。