【问题标题】:JavaFX Area Charts and adding dynamic labels following cursorJavaFX 面积图并在光标后添加动态标签
【发布时间】:2015-03-20 17:51:58
【问题描述】:

我希望能够在光标后的图表中添加标签。我已经在堆栈溢出中看到了几个这样的例子,它们将标签附加到一系列的值/节点,但我希望能够对整个区域图执行此操作。当我想添加一个标签(最终是一个浮动的值框)时,我的问题就来了。我正在努力弄清楚如何做到这一点并保持场景的布局。当我将图表作为专用项目添加到场景中时,图表会按预期呈现。但是当我向场景添加标签时,它会被共享并且图表不再填满整个画布

Group root = new Group();
root.getChildren().addAll(sac,myLabel);
Scene scene = new Scene(root, 800, 600); // Now the Chart shares the scene with the label

我想添加标签,以便在鼠标移动到图表上时使用它,然后简单地将其转换到光标位置。我对鼠标事件没有任何问题,只是我似乎无法与瞬态对象共享场景。我认为这是由于对如何管理这种特殊情况缺乏了解。这个问题的解决方案很可能是动态生成这个标签,而不是将它作为静态场景对象。感谢您提供任何帮助。

下面的完整测试用例(Java 8)

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.StackedAreaChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;

public class AreaChartTestCase extends Application {

    final NumberAxis xAxis = new NumberAxis(1, 31, 1);
    final NumberAxis yAxis = new NumberAxis();
    final StackedAreaChart<Number, Number> sac
            = new StackedAreaChart<Number, Number>(xAxis, yAxis);
    Label myLabel = new Label();

    @Override
    public void start(Stage stage) {
        stage.setTitle("Area Chart Sample");
        sac.setTitle("Temperature Monitoring (in Degrees C)");
        XYChart.Series<Number, Number> seriesApril
                = new XYChart.Series<Number, Number>();
        seriesApril.setName("April");
        seriesApril.getData().add(new XYChart.Data(1, 4));
        seriesApril.getData().add(new XYChart.Data(3, 10));
        seriesApril.getData().add(new XYChart.Data(6, 15));
        seriesApril.getData().add(new XYChart.Data(9, 8));
        seriesApril.getData().add(new XYChart.Data(12, 5));
        seriesApril.getData().add(new XYChart.Data(15, 18));
        seriesApril.getData().add(new XYChart.Data(18, 15));
        seriesApril.getData().add(new XYChart.Data(21, 13));
        seriesApril.getData().add(new XYChart.Data(24, 19));
        seriesApril.getData().add(new XYChart.Data(27, 21));
        seriesApril.getData().add(new XYChart.Data(30, 21));
        XYChart.Series<Number, Number> seriesMay
                = new XYChart.Series<Number, Number>();
        seriesMay.setName("May");
        seriesMay.getData().add(new XYChart.Data(1, 20));
        seriesMay.getData().add(new XYChart.Data(3, 15));
        seriesMay.getData().add(new XYChart.Data(6, 13));
        seriesMay.getData().add(new XYChart.Data(9, 12));
        seriesMay.getData().add(new XYChart.Data(12, 14));
        seriesMay.getData().add(new XYChart.Data(15, 18));
        seriesMay.getData().add(new XYChart.Data(18, 25));
        seriesMay.getData().add(new XYChart.Data(21, 25));
        seriesMay.getData().add(new XYChart.Data(24, 23));
        seriesMay.getData().add(new XYChart.Data(27, 26));
        seriesMay.getData().add(new XYChart.Data(31, 26));

        final Node chartPlotBackground = sac.lookup(".chart-plot-background");
        chartPlotBackground.setOnMouseEntered((MouseEvent mouseEvent) -> {
            myLabel.setVisible(true);
        });

        chartPlotBackground.setOnMouseExited((MouseEvent mouseEvent) -> {
            myLabel.setVisible(false);
        });

        chartPlotBackground.setOnMouseMoved((MouseEvent mouseEvent) -> {
            myLabel.setText("Location : X = " + mouseEvent.getSceneX() + " : Y = "+ mouseEvent.getSceneY());
            myLabel.setTranslateX(mouseEvent.getSceneX());
            myLabel.setTranslateY(mouseEvent.getSceneY());
        });

        Group root = new Group();
        root.getChildren().addAll(sac, myLabel);
        Scene scene = new Scene(root, 800, 600); // Now the Chart shares the scene with the label
        sac.getData().addAll(seriesApril, seriesMay);
        stage.setScene(scene);
        stage.show();

    }

    public static void main(String[] args) {
        launch(args);
    }
}

【问题讨论】:

  • 在示例中,您的标签取决于mouseEvent.getSceneX/Y 值,这似乎不是特别有用。这是你真正想要的吗?还是您希望标签依赖于某些图表特定值?如果是这样,它与鼠标悬停的区域或鼠标所在的确切点有关?
  • 感谢您的回复。老实说,鼠标的跟踪只是为了展示我正在尝试做的事情。我相当肯定我可以做得那么优雅。真正的问题是我不明白如何将标签添加到场景然后应用布局,以便图表在窗口/画布中最大化并且标签没有绑定到特定的布局区域。基本上我的问题比这更根本......一个小组使我能够做到这一点,但似乎我不能最大化图表。

标签: layout charts javafx


【解决方案1】:

所以我想我已经解决了。至少达到我要求的水平。

    Group root = new Group();
    root.setManaged(false);
    root.getChildren().add(ac);
    root.getChildren().add(myLabel);
    Scene scene = new Scene(root);

    scene.widthProperty().addListener(new ChangeListener<Number>() {
        @Override
        public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneWidth, Number newSceneWidth) {
            ac.setPrefWidth((double) newSceneWidth);
        }
    });
    scene.heightProperty().addListener(new ChangeListener<Number>() {
        @Override
        public void changed(ObservableValue<? extends Number> observableValue, Number oldSceneHeight, Number newSceneHeight) {
            ac.setPrefHeight((double) newSceneHeight);
        }
    });

通过监听宽度和高度属性的变化并手动管理图表和标签的布局,我能够获得所需的布局和功能。我不能 100% 确定这是否是最佳方法,但它有效.

【讨论】:

    猜你喜欢
    • 2018-05-18
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多