You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在JFreeChart中添加X/Y轴零位置十字线问题求助

问题描述

我希望在图表中添加位于x=0和y=0位置的X轴与Y轴十字线,尝试通过以下代码设置十字线可见,但并未生效:

plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(true);

运行程序后图表正常显示,但零位置的X/Y轴十字线并未出现,完整代码如下:

package Grava;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.fx.ChartViewer;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.statistics.Regression;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class ScatterAdd extends Application {


    private final XYSeries series = new XYSeries("Voltage");
    private final XYSeries trend = new XYSeries("Trend");
    private final XYSeriesCollection dataset = new XYSeriesCollection(series);

    ChoiceBox<String> domainLabels = new ChoiceBox<>();
    ChoiceBox<String> rangeLabels = new ChoiceBox<>();

    private JFreeChart createChart() {
        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series);
        return ChartFactory.createScatterPlot("VI Characteristics", "Current", "Voltage", dataset);
    }

    @Override
    public void start(Stage stage) {

        Image image = new Image("Grava.logo.png");
        stage.getIcons().add(image);


        XYPlot plot = createChart().getXYPlot();
        plot.setDomainCrosshairVisible(true);
        plot.setRangeCrosshairVisible(true);

        XYLineAndShapeRenderer r = (XYLineAndShapeRenderer) plot.getRenderer();
        r.setSeriesLinesVisible(1, Boolean.TRUE);
        r.setSeriesShapesVisible(1, Boolean.FALSE);

        var equation = new TextField();

        series.addChangeListener((event) -> {
            double[] coefficients = Regression.getOLSRegression(dataset, 0);
            double b = coefficients[0]; // intercept
            double m = coefficients[1]; // slope
            equation.setText("y = " + m + " x + " + b);

        });

        JFreeChart chart = createChart();
        domainLabels.getSelectionModel().selectedItemProperty().addListener((ov, s0, s1) -> {
            chart.getXYPlot().getDomainAxis().setLabel(s1);
        });
        rangeLabels.getSelectionModel().selectedItemProperty().addListener((ov, s0, s1) -> {
            chart.getXYPlot().getRangeAxis().setLabel(s1);
        });

        domainLabels.getItems().addAll("Current", "Seconds");
        domainLabels.setValue("Current");

        rangeLabels.getItems().addAll("Voltage", "Metres");
        rangeLabels.setValue("Voltage");

        var xSpin = new Spinner<Double>(-10000000.000, 10000000.000, 0, 0.1);
        xSpin.setEditable(true);
        xSpin.setPromptText("Xvalue");

        var ySpin = new Spinner<Double>(-10000000.000, 10000000.000, 0, 0.1);
        ySpin.setEditable(true);
        ySpin.setPromptText("Yvalue");

        var button = new Button("Add");
        button.setOnAction(ae -> series.add(xSpin.getValue(), ySpin.getValue()));


        HBox xBox = new HBox();
        xBox.getChildren().addAll(domainLabels);

        HBox yBox = new HBox();
        yBox.getChildren().addAll(rangeLabels);

        var enter = new ToolBar(xBox, xSpin, yBox, ySpin, button, equation);
        BorderPane.setAlignment(enter, Pos.CENTER);

        BorderPane root = new BorderPane();
        root.setCenter(new ChartViewer(chart));
        root.setBottom(enter);

        stage.setTitle("ScatterAdd");
        stage.setScene(new Scene(root, 720, 480));
        stage.show();

    }

    public static void main(String[] args) {
        launch(args);
    }
}
问题原因

你连续调用了两次createChart()方法:第一次调用获取的XYPlot实例被设置了十字线属性,但这个实例并没有被用于最终显示的图表;第二次调用创建的JFreeChart对象才是添加到ChartViewer中的实例,而它的十字线属性没有被设置,所以十字线无法显示。

解决方案

只创建一次JFreeChart实例,对同一个实例的XYPlot进行属性设置,修改后的start方法关键代码如下:

@Override
public void start(Stage stage) {

    Image image = new Image("Grava.logo.png");
    stage.getIcons().add(image);

    // 只创建一次chart实例
    JFreeChart chart = createChart();
    XYPlot plot = chart.getXYPlot();
    plot.setDomainCrosshairVisible(true);
    plot.setRangeCrosshairVisible(true);

    XYLineAndShapeRenderer r = (XYLineAndShapeRenderer) plot.getRenderer();
    r.setSeriesLinesVisible(1, Boolean.TRUE);
    r.setSeriesShapesVisible(1, Boolean.FALSE);

    var equation = new TextField();

    series.addChangeListener((event) -> {
        double[] coefficients = Regression.getOLSRegression(dataset, 0);
        double b = coefficients[0]; // intercept
        double m = coefficients[1]; // slope
        equation.setText("y = " + m + " x + " + b);

    });

    // 直接使用已创建的chart实例进行后续操作
    domainLabels.getSelectionModel().selectedItemProperty().addListener((ov, s0, s1) -> {
        chart.getXYPlot().getDomainAxis().setLabel(s1);
    });
    rangeLabels.getSelectionModel().selectedItemProperty().addListener((ov, s0, s1) -> {
        chart.getXYPlot().getRangeAxis().setLabel(s1);
    });

    // 剩余代码保持不变...
}

修改后,十字线会正常显示在x=0和y=0的位置。另外,代码中重复导入的NumberAxis等包可以清理掉,避免冗余。

内容的提问来源于stack exchange,提问作者armitageshanks99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 08:21:35