JFreeChart的条形图栏单位

时间:2017-03-05 14:58:44

标签: java charts jfreechart

我正在尝试用Java创建一个条形图。

我想在DateAxis(不是刻度单位)上设置1H bar单位。有办法吗? 经过大量的谷歌搜索,我没有发现任何有趣的事情。

这就是我得到的:

BarChart

ChartAdapter.java

public class ChartAdapter extends JFrame {

/**
 * Constructs the demo application.
 *
 * @param title  the frame title.
 */
public ChartPanel generateChart(String title, Vector<Vector<String>> dataVector) {
    JFreeChart chart = ChartFactory.createXYBarChart(
        title,
        "X",
        true,
        "Y",
        createDataset(dataVector),
        PlotOrientation.VERTICAL,
        true,
        false,
        false
    );


    final XYItemRenderer renderer = chart.getXYPlot().getRenderer();
    final StandardXYToolTipGenerator generator = new StandardXYToolTipGenerator(
        "{1} = {2}", new SimpleDateFormat("yyyy"), new DecimalFormat("0.00")
    );
    renderer.setToolTipGenerator(generator);

    final XYPlot plot = chart.getXYPlot();
    final DateAxis dAxis = (DateAxis) plot.getDomainAxis();
    dAxis.setVerticalTickLabels(true);
    final NumberAxis nAxis = (NumberAxis) plot.getRangeAxis();

    Calendar c = Calendar.getInstance();
    c.setTime(dAxis.getMinimumDate());
    c.add(Calendar.HOUR, 12);

    final ChartPanel chartPanel = new ChartPanel(chart);
    chartPanel.setPreferredSize(new java.awt.Dimension(600, 300));


    return chartPanel;
}

private IntervalXYDataset createDataset(Vector<Vector<String>> dataVector) {
    TimeSeries series = new TimeSeries("Value");

    for(Vector<String> tempVector : dataVector) {
        Timestamp time = Timestamp.valueOf(tempVector.get(0));
        series.add(new Millisecond(time), Double.parseDouble(tempVector.get(1)));
    }
    TimeSeriesCollection dataset = new TimeSeriesCollection(series);
    dataset.setDomainIsPointsInTime(false);
        return dataset;
    }
}

Test.java

public class Test extends JFrame {

    private JPanel contentPane;
    Vector<Vector<String>> dataVector = new Vector<Vector<String>>();

    /**
     * Launch the application.
     */
    public static void main(String[] args) {



        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Test frame = new Test();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Test() {
        Vector<String> tempString = null;

        Calendar c = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        try {
            c.setTime(sdf.parse("2017-01-12 12:00:00"));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        for(int i=0; i<10; i++) {
            tempString = new Vector<String>();
            tempString.add(sdf.format(c.getTime()));
            tempString.add(String.valueOf((int)(Math.random()*35)));
            c.add(Calendar.HOUR, 1);
            dataVector.add(tempString);
        }




        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        //contentPane.add(chart.generateChart(chart.getMinValue(), chart.getMaxValue()));
        contentPane.add(new ChartAdapter().generateChart("Data", dataVector));
        contentPane.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
    }

}

1 个答案:

答案 0 :(得分:1)

我已经简化了您的示例,专注于构成数据集的区间。使用一个Calendar.HOUR的间隔可确保条形显示为一小时宽。虽然您的问题特别避开了滴答单元,但某些功能可能会有用:

  • 使用显示here的方法获得特定的滴答间隔。

    domainAxis.setTickUnit(new DateTickUnit(DateTickUnitType.HOUR, 1));
    
  • 使用setTickMarkPosition()将刻度线置于所选间隔的中心位置。

    domainAxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);
    

image

import java.awt.EventQueue;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Random;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickMarkPosition;
import org.jfree.chart.axis.DateTickUnit;
import org.jfree.chart.axis.DateTickUnitType;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.time.Hour;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.IntervalXYDataset;

/** @see https://stackoverflow.com/a/42612723/230513 */
public class Test {

    public static void main(String[] args) {

        EventQueue.invokeLater(() -> {
            Test frame = new Test();
        });
    }

    public Test() {
        JFrame f = new JFrame("Data");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new ChartAdapter().generateChart("Data"));
        f.pack();
        f.setVisible(true);
    }

    class ChartAdapter {

        public ChartPanel generateChart(String title) {
            JFreeChart chart = ChartFactory.createXYBarChart(
                title, "Time", true, "Value", createDataset(),
                PlotOrientation.VERTICAL, true, false, false
            );
            final XYItemRenderer renderer = chart.getXYPlot().getRenderer();
            final StandardXYToolTipGenerator generator = new StandardXYToolTipGenerator(
                "{1} : {2}", new SimpleDateFormat("HH:mm"), new DecimalFormat("0.00")
            );
            renderer.setBaseToolTipGenerator(generator);
            final XYPlot plot = chart.getXYPlot();
            final DateAxis domainAxis = (DateAxis) plot.getDomainAxis();
            domainAxis.setVerticalTickLabels(true);
            domainAxis.setTickUnit(new DateTickUnit(DateTickUnitType.HOUR, 1));
            domainAxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);
            domainAxis.setDateFormatOverride(new SimpleDateFormat("HH:mm"));
            return new ChartPanel(chart);
        }

        private IntervalXYDataset createDataset() {
            Random r = new Random();
            TimeSeries series = new TimeSeries("Value");
            Calendar c = Calendar.getInstance();
            for (int i = 0; i < 10; i++) {
                series.add(new Hour(c.getTime()), r.nextGaussian() + 7);
                c.add(Calendar.HOUR, 1);
            }
            return new TimeSeriesCollection(series);
        }
    }
}