在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
相关产品推荐
相关产品推荐

