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()
时,查询底层数据集,如下图
上 仅 构造和操作 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);
}
});
}
}
在 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()
时,查询底层数据集,如下图- 上 仅 构造和操作 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);
}
});
}
}