使用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没碰到过这个问题,但是你的分析结果,我看懂了,以后碰到这样的问题就有思路了。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。