Jfreechart优化X轴标签

Jfreechart optimize X axis labels

在 JFreechart 中,我有一个带有日期(和时间)的 X 轴。

我如何要求 JFreechart 优化它们并充分利用它?

现在它包含的标签比 space 多,所有标签都转换为“...”。

如果不是所有刻度都有标签,那完全没问题,但我想要尽可能多的(如果它们适合并且可以完全显示)。

我怎样才能做到这一点?

更新 1:

这是复制截断标签的完整最小源代码。 (还更新了屏幕截图)。 JFreechart 默认不处理优化:

import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;

public class LineChart_AWT extends ApplicationFrame {

    public LineChart_AWT( String applicationTitle , String chartTitle ) {
          super(applicationTitle);
          JFreeChart lineChart = ChartFactory.createLineChart(
             chartTitle,
             "Dates","Temperature",
             createDataset(),
             PlotOrientation.VERTICAL,
             true,true,false);

          CategoryPlot plot = (CategoryPlot) lineChart.getPlot();
          plot.getRangeAxis().setRange(25, 27);

          ChartPanel chartPanel = new ChartPanel( lineChart );
          chartPanel.setPreferredSize( new java.awt.Dimension( 560 , 367 ) );
          setContentPane( chartPanel );
       }

       private DefaultCategoryDataset createDataset( ) {
          DefaultCategoryDataset dataset = new DefaultCategoryDataset( );

          dataset.addValue( 26.44,"Temperature","2019-08-18 00:00");
          dataset.addValue( 26.2,"Temperature","2019-08-18 01:00");
          dataset.addValue( 25.93,"Temperature","2019-08-18 02:00");
          dataset.addValue( 25.71,"Temperature","2019-08-18 03:00");
          dataset.addValue( 25.54,"Temperature","2019-08-18 04:00");
          dataset.addValue( 25.42,"Temperature","2019-08-18 05:00");
          dataset.addValue( 25.25,"Temperature","2019-08-18 06:00");
          dataset.addValue( 25.19,"Temperature","2019-08-18 07:00");
          dataset.addValue( 25.25,"Temperature","2019-08-18 08:00");
          dataset.addValue( 25.36,"Temperature","2019-08-18 09:00");
          dataset.addValue( 25.52,"Temperature","2019-08-18 10:00");
          dataset.addValue( 25.86,"Temperature","2019-08-18 11:00");
          dataset.addValue( 26.51,"Temperature","2019-08-18 12:00");
          dataset.addValue( 26.82,"Temperature","2019-08-18 13:00");


          return dataset;
       }

       public static void main( String[ ] args ) {
          LineChart_AWT chart = new LineChart_AWT(
             "X-axis demo" ,
             "X-axis labels are truncated");

          chart.pack( );
          RefineryUtilities.centerFrameOnScreen( chart );
          chart.setVisible( true );
       }
    }

更新 2:

我更喜欢@trashgod 推荐的 X 轴标签旋转 45°。 但是,当更多数据出现时,这种方法无法正常工作:

是否可以设置最大允许标签数?我会将它设置为一些默认值,例如 5 或 6。或者,如果这会隐藏周围环境,也可以定义边距或填充以提高可读性。

更新后的示例创建了一个 CategoryDataset,并使用 ChartFactory 方法 createLineChart() 创建了一个 CategoryPlot。您可以调整标签位置以提高可读性,如 及以下所示。此外,

it would be nice to have a vertical grid line only when the label is visible and hide all other grid lines.

plot.getDomainAxis().setCategoryLabelPositions(
    CategoryLabelPositions.UP_45);
plot.setDomainGridlinesVisible(true);
plot.setRangeGridlinesVisible(false);

更一般地说,创建一个 TimeSeries 并使用相应的 ChartFactory 方法,createTimeSeriesChart()。调整封闭图表大小时,生成的 DateAxis 将自动调整标签。此外,

  • 您可以调整日期格式,如图所示here

  • 要确定图表的初始大小,请按照建议覆盖 getPreferredSize() here

  • 使用setRange()时,查询底层数据集,如下图

  • event dispatch thread.

  • 构造和操作 Swing GUI 对象

import java.awt.Dimension;
import java.awt.EventQueue;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.ui.ApplicationFrame;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Day;
import org.jfree.data.time.Hour;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;

public class TempChart extends ApplicationFrame {

    public TempChart(String applicationTitle, String chartTitle) {
        super(applicationTitle);
        TimeSeries s = createSeries();
        JFreeChart chart = ChartFactory.createTimeSeriesChart(
            chartTitle, "Date", "Temperature", new TimeSeriesCollection(s));

        XYPlot plot = (XYPlot) chart.getPlot();
        plot.getRangeAxis().setRange(Math.floor(s.getMinY()), Math.ceil(s.getMaxY()));

        ChartPanel chartPanel = new ChartPanel(chart) {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(560, 367);
            }
        };
        add(chartPanel);
    }

    private TimeSeries createSeries() {
        TimeSeries series = new TimeSeries("Temperature");

        series.add(new Hour(0, new Day()), 26.44);
        series.add(new Hour(1, new Day()), 26.2);
        series.add(new Hour(2, new Day()), 25.93);
        series.add(new Hour(3, new Day()), 25.71);
        series.add(new Hour(4, new Day()), 25.54);
        series.add(new Hour(5, new Day()), 25.42);
        series.add(new Hour(6, new Day()), 25.25);
        series.add(new Hour(7, new Day()), 25.19);
        series.add(new Hour(8, new Day()), 25.25);
        series.add(new Hour(9, new Day()), 25.36);
        series.add(new Hour(10, new Day()), 25.52);
        series.add(new Hour(11, new Day()), 25.86);
        series.add(new Hour(12, new Day()), 26.51);
        series.add(new Hour(13, new Day()), 26.82);

        return series;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                TempChart chart = new TempChart(
                    "Temperature demo", "Time Axis labels adjust on resize");
                chart.pack();
                chart.setLocationRelativeTo(null);
                chart.setVisible(true);
            }
        });
    }
}