【问题标题】:Jfreechart optimize X axis labelsJfreechart优化X轴标签
【发布时间】:2019-08-17 16:17:50
【问题描述】:

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

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

现在它包含比空间更多的标签,所有标签都被转换为'...'。

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

我怎样才能做到这一点?

更新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。或者,如果这会隐藏周围环境,也可以定义边距或填充以增加可读性。

【问题讨论】:

  • 由于默认设置会自动处理此问题,我猜您的代码会导致此问题。请edit 您的问题包含一个minimal reproducible example,以展示您说明的问题。
  • @trashgod:它不会自动处理 - 如屏幕截图所示。
  • 您的minimal reproducible example 很好地说明了问题;我已经在下面详细说明了。

标签: jfreechart


【解决方案1】:

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

只有在标签可见并隐藏所有其他网格线时才有垂直网格线会很好。

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

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

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

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

  • 使用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);
            }
        });
    }
}

【讨论】:

  • 我更喜欢带有 45 度标签的第一种方法。 (这是一个动态生成的图表,域轴可能不是 DateAxis。)但是当添加更多值时,标签彼此非常接近,几乎无法读取它们。这是处理这个的一些简单方法吗?请检查我的问题的更新我已经创建了当前问题的新屏幕截图。谢谢!
  • @trashgood:只有当标签可见并隐藏所有其他网格线时才有垂直网格线会很好。
  • 如果空间有限,您可以使用任一方法使标签垂直;以上。
  • @trashgood:即使使它们垂直也无济于事,因为它们彼此太靠近了:/
  • 也可以考虑SlidingCategoryDataset
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-29
  • 2014-10-09
  • 2011-01-30
  • 2018-02-10
  • 2013-04-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多