当前位置: 首页 > 知识库问答 >
问题:

JFreeChart-FX时间序列垂直刻度标签重叠

轩辕经赋
2023-03-14

使用jfreechart fx渲染带有垂直刻度标签的时间序列图表时,标签意外地与域轴重叠,有时在调整大小时会发生更改。我无法用Swing或纯Java2D重现这一点,如图所示。我欢迎任何指导。

import java.awt.BasicStroke;
import java.awt.Color;
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.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;

/**
 * @see https://stackoverflow.com/q/70021577/230513
 */
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");
        // data
        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);
        // axes
        NumberAxis rangeAxis = new NumberAxis("Value");
        NumberFormat numberFormat = NumberFormat.getInstance();
        numberFormat.setMinimumFractionDigits(2);
        numberFormat.setMaximumFractionDigits(2);
        rangeAxis.setNumberFormatOverride(numberFormat);
        rangeAxis.setLowerMargin(0.08); // 8% lower margin
        rangeAxis.setAutoRangeIncludesZero(false);
        DateAxis domainAxis = new DateAxis("Date");
        domainAxis.setDateFormatOverride(outFormat);
        domainAxis.setVerticalTickLabels(true);
        // renderer, plot, chart
        XYSplineRenderer r = new XYSplineRenderer(15);
        XYPlot xyplot = new XYPlot(dataset, domainAxis, rangeAxis, r);
        JFreeChart chart = new JFreeChart(null, xyplot);
        r.setSeriesPaint(0, new Color(255, 152, 0));
        r.setSeriesStroke(0, new BasicStroke(2.0f));
        // display
        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);
    }
}

共有1个答案

宣俊豪
2023-03-14

所引用的示例使用的渲染器不存在ChartFactory。这些工厂说明了典型的用例;最后,将图表主题应用于图表。下面的变体应用了标准图表主题,该主题为影响几何图形的元素(如字体度量和轴偏移)建立一致的默认值;可以自定义默认值,如图所示。

这个问题在纯Java2D中不会出现,它在初始线程上运行。类似的Swing程序通常安排在EventQueue上。jfreechart fx程序依赖于自定义的GraphicsContext;应用ChartTheme可确保在第一次更新时出现所需的默认值。

import java.awt.BasicStroke;
import java.awt.Color;
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.StandardChartTheme;
import org.jfree.chart.axis.DateAxis;
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;

/**
 * @see https://stackoverflow.com/a/70058016/230513
 * @see https://stackoverflow.com/q/70021577/230513
 */
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");
        // data
        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);
        // axes
        NumberAxis rangeAxis = new NumberAxis("Value");
        NumberFormat numberFormat = NumberFormat.getInstance();
        numberFormat.setMinimumFractionDigits(2);
        numberFormat.setMaximumFractionDigits(2);
        rangeAxis.setNumberFormatOverride(numberFormat);
        rangeAxis.setLowerMargin(0.08); // 8% lower margin
        rangeAxis.setAutoRangeIncludesZero(false);
        DateAxis domainAxis = new DateAxis("Date");
        domainAxis.setDateFormatOverride(outFormat);
        domainAxis.setVerticalTickLabels(true);
        // renderer, plot, chart
        XYSplineRenderer r = new XYSplineRenderer(15);
        XYPlot xyplot = new XYPlot(dataset, domainAxis, rangeAxis, r);
        JFreeChart chart = new JFreeChart(null, xyplot);
        StandardChartTheme theme = new StandardChartTheme("Custom");
        theme.setPlotBackgroundPaint(Color.WHITE);
        theme.setDomainGridlinePaint(Color.LIGHT_GRAY);
        theme.setRangeGridlinePaint(Color.LIGHT_GRAY);
        theme.apply(chart);
        r.setSeriesPaint(0, new Color(255, 152, 0));
        r.setSeriesStroke(0, new BasicStroke(2.0f));
        // display
        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);
    }
}
 类似资料:
  • 问题内容: 我已经用JFreeChart制作了以下图表: 替代文字 是否有可能(如果可以的话)在x轴上扩展日期,使其包含年份,例如。2010年4月2日,2010年5月2日,…,2010年6月3日? 问题答案: 目前尚不清楚,你现在是如何格式化日期,但 在 允许你指定一个合适的。 如果还没有,你应该能够覆盖 在 为罗马数字。 附录:为进行正确的本地化,执行以下操作可能会更容易

  • 我正在使用JFreeChart创建y轴为“对数”的XylineChart,但我遇到了一个我似乎无法解决的错误。 在某些情况下,我的值非常低(在一个这样的情况下,y轴值的范围在4.5e-8到1.7112之间)。我在XYLineChart上绘制这些值,使用y轴的对数轴(并使用LogAxis.createLogTickUnits(区域设置)。在y轴上创建指数刻度单位)。我设定了我的范围从4.5e-8到1

  • 我正在使用JFreeChart制作一个条形图与时间。由于某些原因,在这些图表上,x轴上的刻度标签变为“…”偶尔地似乎有足够的空间来扩展标签,但它只是切断了整个事情。我怎样才能解决这个问题。 我试着用图片按钮上传一张图片,但它似乎不起作用。 下面是与我的项目设置相似的代码。奇怪的是,它的行为不同于我的建筑。在我的上面,不是说“侯......”,而是说“......”。请忽略评论和所有其他未编辑的东西

  • 我试图找到最好的策略,以产生一个1D的时间为基础的绘图与标签。目前看起来是这样的: 问题是,有些时间跨度很少发生,有些时间跨度密度很高。 我想实现的是扭曲时间轴,以便在密集区域中标签间隔开,以避免重叠。或者,我可以想象在没有轴变形的情况下显示实际数据点,但分布标签,使它们不会重叠。 编辑:这是我试图手动清理混乱,以了解我想要的输出:

  • 我对Vertx中的标准顶点和工人顶点感到困惑。它们的用例是什么?

  • 问题内容: 我正在尝试找到生成带有标签的基于1D时间的绘图的最佳策略。当前看起来像这样: 在此处输入图片说明 问题在于时间跨度很少发生,而其他时间间隔则密度很高。 我想要实现的是扭曲时间轴,以便在密集区域中将标签隔开以避免重叠。另外,我可以想象显示没有轴失真的实际数据点,但要分配标签,使它们不重叠。 问题答案: 您可以尝试使用 setDomainPannable()和在此处和此处setMouseW