开发者社区> 问答> 正文

jfreechart的TimeSeriesChart时间轴TimeSeries问题?报错

使用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谢谢

展开
收起
爱吃鱼的程序员 2020-06-15 19:26:26 739 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    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就是需要多阅读源代码.

    不错,虽然我用jfreechart没碰到过这个问题,但是你的分析结果,我看懂了,以后碰到这样的问题就有思路了。

    2020-06-15 19:26:42
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载

相关实验场景

更多