Javafx获取CategoryAxis类别节点

时间:2017-07-27 17:55:26

标签: java charts java-8 javafx-8

是否有可能获得创建CategoryAxis类别的图表(特别是BarChart)创建的节点(列表)?

Bar Chart

目标是为节点添加一些鼠标事件。

我试图通过xAxis.getChildrenUnmodifiable()访问它们,但这会返回刻度线。 还有xAxis.getCategories()但这会返回String类别的标签文字,并添加我需要的鼠标事件Nodes

所以这里有一些代码可以重现我想要完成的事情:

import java.util.HashMap;
import java.util.Map;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.Axis;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;

public class Main extends Application {

    final static String austria = "Austria";
    final static String brazil = "Brazil";
    final static String france = "France";
    final static String italy = "Italy";
    final static String usa = "USA";

    @Override
    public void start(Stage stage) {
        Group group = new Group();
        stage.setTitle("Bar Chart Sample");
        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
        final CustomBarChart<String, Number> bc =
                new CustomBarChart<String, Number>(xAxis, yAxis);
        bc.setTitle("Country Summary");
        bc.setLegendVisible(false);
        xAxis.setLabel("Country");
        xAxis.setTickLabelRotation(90);
        yAxis.setLabel("Value");

        XYChart.Series series1 = new XYChart.Series();
        series1.getData().add(new XYChart.Data(austria, 25601.34));
        series1.getData().add(new XYChart.Data(brazil, 20148.82));
        series1.getData().add(new XYChart.Data(france, 10000));
        series1.getData().add(new XYChart.Data(italy, 35407.15));
        series1.getData().add(new XYChart.Data(usa, 12000));


        final Label tooltipXAxis = new Label("");
        tooltipXAxis.setStyle("-fx-font-size: 12;" +
                "-fx-font-weight: bold;" +
                "-fx-padding: 5px;" +
                "-fx-background-color: white;" +
                "-fx-background-radius: 5;" +
                "-fx-border-radius: 5;" +
                "-fx-border-style: solid;" +
                "-fx-border-width: 2;" +
                "-fx-border-color: black;");
        tooltipXAxis.setVisible(false);

        //xAxis tooltip 
        for (Node n : xAxis.getChildrenUnmodifiable()) {
            n.addEventHandler(MouseEvent.MOUSE_ENTERED,
                    new EventHandler<MouseEvent>() {
                @Override public void handle(MouseEvent e) {
                    tooltipXAxis.setMouseTransparent(true);
                    tooltipXAxis.setText("Tooltip Here");

                    tooltipXAxis.setVisible(true);
                }
            });
            n.addEventHandler(MouseEvent.MOUSE_MOVED,
                    new EventHandler<MouseEvent>() {
                @Override public void handle(MouseEvent e) {
                    Point2D locationInScene = new Point2D(e.getSceneX(), e.getSceneY()-35);
                    Point2D locationInParent = group.sceneToLocal(locationInScene);

                    tooltipXAxis.relocate(locationInParent.getX(), locationInParent.getY());
                }
            });
            n.addEventHandler(MouseEvent.MOUSE_EXITED,
                    new EventHandler<MouseEvent>() {
                @Override public void handle(MouseEvent e) {
                    tooltipXAxis.setVisible(false);
                }
            });
        }

        bc.getData().addAll(series1);

        group.getChildren().addAll(bc, tooltipXAxis);
        Scene scene = new Scene(group);
        stage.setScene(scene);
        stage.show();
    }

    public class CustomBarChart<X, Y> extends BarChart<X, Y> {

        Map<Node, TextFlow> nodeMap = new HashMap<>();

        public CustomBarChart(Axis xAxis, Axis yAxis) {
            super(xAxis, yAxis);
            this.setBarGap(0.0);
        }

        @Override
        protected void seriesAdded(Series<X, Y> series, int seriesIndex) {

            super.seriesAdded(series, seriesIndex);

            for (int j = 0; j < series.getData().size(); j++) {

                Data<X, Y> item = series.getData().get(j);

                Text text = new Text(item.getYValue().toString());
                text.setStyle("-fx-font-size: 10pt;");

                TextFlow textFlow = new TextFlow(text);
                textFlow.setTextAlignment(TextAlignment.CENTER);

                nodeMap.put(item.getNode(), textFlow);
                this.getPlotChildren().add(textFlow);

            }

        }

        @Override
        protected void seriesRemoved(final Series<X, Y> series) {

            for (Node bar : nodeMap.keySet()) {

                Node text = nodeMap.get(bar);
                this.getPlotChildren().remove(text);

            }

            nodeMap.clear();

            super.seriesRemoved(series);
        }

        @Override
        protected void layoutPlotChildren() {

            super.layoutPlotChildren();

            for (Node bar : nodeMap.keySet()) {

                TextFlow textFlow = nodeMap.get(bar);

                if (bar.getBoundsInParent().getHeight() > 30) {
                    ((Text) textFlow.getChildren().get(0)).setFill(Color.WHITE);
                    textFlow.resize(bar.getBoundsInParent().getWidth(), 200);
                    textFlow.relocate(bar.getBoundsInParent().getMinX(), bar.getBoundsInParent().getMinY() + 10);
                } else {
                    ((Text) textFlow.getChildren().get(0)).setFill(Color.GRAY);
                    textFlow.resize(bar.getBoundsInParent().getWidth(), 200);
                    textFlow.relocate(bar.getBoundsInParent().getMinX(), bar.getBoundsInParent().getMinY() - 20);
                }
            }
        }
    }

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

此代码存在的问题是,当勾选标记或xAxis标签悬停时,会显示标签tooltipXAxis。 但是,目标是在类别标签悬停时显示它,如上图所示。

1 个答案:

答案 0 :(得分:1)

请参阅此answer,其中我从图表中提取xAxis行以将其移动。可能它会帮助你。否则,你能提供你的代码,我会玩它。