JFreeChart的条形图条形单位 [英] JFreeChart's Bar Chart Bar Unit

查看:67
本文介绍了JFreeChart的条形图条形单位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我想在 DateAxis上使用1H条形单位(不是刻度单位)。有办法吗?
经过大量Google搜索后,我没有发现任何有趣的东西。



这就是我得到的:





ChartAdapter.java

 公共类ChartAdapter扩展JFrame {

/ **
*构造演示应用程序。
*
* @param title为框架标题。
* /
公共ChartPanel generateChart(String title,Vector< Vector< Vector< String>> dataVector){
JFreeChart chart = ChartFactory.createXYBarChart(
title,
X,
true,
Y,
createDataset(dataVector),
PlotOrientation.VERTICAL,
true,
false,

);


最终XYItemRenderer渲染器= chart.getXYPlot()。getRenderer();
最终的StandardXYToolTipGenerator生成器=新的StandardXYToolTipGenerator(
{1} = {2},新的SimpleDateFormat( yyyy),新的DecimalFormat( 0.00)
);
renderer.setToolTipGenerator(generator);

最终XYPlot图= chart.getXYPlot();
最后的DateAxis dAxis =(DateAxis)plot.getDomainAxis();
dAxis.setVerticalTickLabels(true);
最后的NumberAxis nAxis =(NumberAxis)plot.getRangeAxis();

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

最终的ChartPanel chartPanel =新的ChartPanel(图表);
chartPanel.setPreferredSize(new java.awt.Dimension(600,300));


退货图表
}

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数据集= new TimeSeriesCollection(series);
dataset.setDomainIsPointsInTime(false);
返回数据集;
}
}

Test.java

 公共类测试扩展了JFrame {

私人JPanel contentPane;
Vector< Vector< String>> dataVector =新的Vector< Vector< String>>();

/ **
*启动应用程序。
* /
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();
}
}
});
}

/ **
*创建框架。
* /
public Test(){
Vector< String> tempString = null;

日历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自动生成的catch块
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(newEmptyBorder(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));
}

}


解决方案

我已经简化了您的示例,将重点放在组成数据集的间隔上。使用间隔为 Calendar.HOUR 的间隔可确保条形显示一小时宽。尽管您的问题专门避开了刻度单位,但某些功能将来可能会有用:




  • 使用显示的方法

      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);
    }

    类ChartAdapter {

    public ChartPanel generateChart(String title){
    JFreeChart chart = ChartFactory.createXYBarChart(
    title, Time,true, Value,createDataset(),
    PlotOrientation.VERTICAL,true,false,false
    );
    最终XYItemRenderer渲染器= chart.getXYPlot()。getRenderer();
    最终的StandardXYToolTipGenerator生成器=新StandardXYToolTipGenerator(
    {1}:{2},新SimpleDateFormat( HH:mm),新DecimalFormat( 0.00)
    );
    renderer.setBaseToolTipGenerator(generator);
    最终XYPlot图= chart.getXYPlot();
    最后的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));
    返回新的ChartPanel(图);
    }

    private IntervalXYDataset createDataset(){
    Random r = new Random();
    TimeSeries系列= new TimeSeries( Value);
    日历c = Calendar.getInstance();
    for(int i = 0; i< 10; i ++){
    series.add(new Hour(c.getTime()),r.nextGaussian()+ 7);
    c.add(Calendar.HOUR,1);
    }
    返回新的TimeSeriesCollection(series);
    }
    }
    }


    I'm trying to create a bar chart in Java.

    I'd like to have 1H bar unit on the DateAxis (not tick unit). Is there a way? After a lot of google search, I haven't found anything interesting about this.

    This is what I get:

    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));
        }
    
    }
    

    解决方案

    I've simplified your example to focus on the intervals comprising the dataset. Using intervals of one Calendar.HOUR ensures that the bars appear one hour wide. Although your question specifically eschews tick units, some features may be useful going forward:

    • Use the approach shown here to get a specific tick interval.

      domainAxis.setTickUnit(new DateTickUnit(DateTickUnitType.HOUR, 1));
      

    • Use setTickMarkPosition() to center the tick marks in the chosen interval.

      domainAxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);
      

    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);
            }
        }
    }
    

    这篇关于JFreeChart的条形图条形单位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆