JFreeChart-FX时间序列图垂直刻度标签重叠域轴及缩放异常问题求助
问题根因
该异常是jfreechart-fx适配JavaFX渲染层时的边界计算缺陷导致:垂直刻度标签的宽高计算未与JavaFX的坐标映射逻辑对齐,仅在FX渲染环境下触发,Swing/原生Java2D渲染逻辑不受影响。窗口缩放时框架会自动重新计算刻度间隔,标签长度变化进一步加重了重叠现象。
可行解决思路
可任选以下一种或组合使用解决重叠问题:
- 调整域轴刻度标签内边距,给垂直方向预留足够展示空间,在设置垂直刻度标签的代码后新增:
需导入domainAxis.setTickLabelInsets(new Insets(25, 2, 2, 2));java.awt.Insets包,可根据标签长度调整第一个参数(顶部内边距)的数值。 - 固定域轴刻度间隔,避免窗口缩放时自动调整刻度导致的标签位移:
需导入domainAxis.setTickUnit(new DateTickUnit(DateTickUnitType.DAY, 1));org.jfree.chart.axis.DateTickUnit、org.jfree.chart.axis.DateTickUnitType包,可根据数据的时间跨度调整刻度单位和间隔。 - 调整绘图区与坐标轴的偏移量,给底部域轴预留更多展示空间:
xyplot.setAxisOffset(new RectangleInsets(5, 5, 35, 5));RectangleInsets的四个参数分别对应上、左、下、右的偏移量,增大第三个参数(底部偏移值)即可给垂直标签预留足够位置,需导入org.jfree.ui.RectangleInsets包。
修改后可运行的完整代码
import java.awt.BasicStroke; import java.awt.Color; import java.awt.Insets; import java.text.NumberFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import javafx.application.Application; import javafx.scene.Scene; import javafx.stage.Stage; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.DateAxis; import org.jfree.chart.axis.DateTickUnit; import org.jfree.chart.axis.DateTickUnitType; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.fx.ChartViewer; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYSplineRenderer; import org.jfree.data.time.Day; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; import org.jfree.ui.RectangleInsets; public class SplineTest extends Application { @Override public void start(Stage stage) throws ParseException { SimpleDateFormat inFormat = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat outFormat = new SimpleDateFormat("dd-MM-yyyy"); // 构造测试数据 double[] values = new double[]{0.67, 0.67, 0.69, 0.70, 0.70, 0.71, 0.71}; String[] dates = new String[]{"2021-11-09", "2021-11-10", "2021-11-11", "2021-11-12", "2021-11-15", "2021-11-16", "2021-11-17"}; TimeSeries series = new TimeSeries("Time Series"); for (int i = 0; i < values.length; i++) { Date date = inFormat.parse(dates[i]); series.add(new Day(date), values[i]); } TimeSeriesCollection dataset = new TimeSeriesCollection(series); // 配置值域轴 NumberAxis rangeAxis = new NumberAxis("Value"); NumberFormat numberFormat = NumberFormat.getInstance(); numberFormat.setMinimumFractionDigits(2); numberFormat.setMaximumFractionDigits(2); rangeAxis.setNumberFormatOverride(numberFormat); rangeAxis.setLowerMargin(0.08); rangeAxis.setAutoRangeIncludesZero(false); // 配置定义域轴 DateAxis domainAxis = new DateAxis("Date"); domainAxis.setDateFormatOverride(outFormat); domainAxis.setVerticalTickLabels(true); // 新增修复代码 domainAxis.setTickLabelInsets(new Insets(25, 2, 2, 2)); domainAxis.setTickUnit(new DateTickUnit(DateTickUnitType.DAY, 1)); // 配置渲染器和绘图区 XYSplineRenderer r = new XYSplineRenderer(15); XYPlot xyplot = new XYPlot(dataset, domainAxis, rangeAxis, r); // 新增绘图区偏移配置 xyplot.setAxisOffset(new RectangleInsets(5, 5, 35, 5)); JFreeChart chart = new JFreeChart(null, xyplot); r.setSeriesPaint(0, new Color(255, 152, 0)); r.setSeriesStroke(0, new BasicStroke(2.0f)); // 渲染展示 Scene scene = new Scene(new ChartViewer(chart)); stage.setTitle("SplineTest"); stage.setScene(scene); stage.setWidth(600); stage.setHeight(400); stage.show(); } public static void main(String[] args) { launch(args); } }
内容的提问来源于stack exchange,提问作者trashgod
相关产品推荐
相关产品推荐

