Значения наведения JavaFX LineChart

Я создаю линейную диаграмму в JavaFX. В настоящее время все хорошо, и он успешно создает диаграмму с необходимыми данными из хранимой процедуры базы данных. Во всяком случае, что я требую, если это возможно, для каждой точки данных в LineChart есть событие наведения мыши на нем, которое указывает значение за определенной точкой, например, 150 000 фунтов стерлингов. Я видел примеры этого, которые были сделаны на PieCharts, где он показывает значение% при наведении, но я не могу найти примеры где-либо для LineCharts, может это даже быть сделано?

Может ли кто-нибудь указать мне в правильном направлении, если это возможно?

Код до сих пор:

private static final String MINIMIZED = "MINIMIZED";
private static final String MAXIMIZED = "MAXIMIZED";
private static String chartState = MINIMIZED;
// 12 Month Sales Chart
XYChart.Series<String, Number> series = new XYChart.Series<>();
XYChart.Series<String, Number> series2 = new XYChart.Series<>();

public void getDeltaData() {

    try {
        Connection con = DriverManager.getConnection(connectionUrl);
        //Get all records from table
        String SQL = "";
        Statement stmt = con.createStatement();

        //Create the result set from query execution.
        ResultSet rs = stmt.executeQuery(SQL);

        while (rs.next()) {

            series.getData().add(new XYChart.Data<String, Number>(rs.getString(1),
                    Double.parseDouble(rs.getString(7))));
            series2.getData().add(new XYChart.Data<String, Number>(rs.getString(1),
                    Double.parseDouble(rs.getString(8))));

        }
        rs.close();
        stmt.close();

    } catch (Exception e) {
    }
    yearChart = createChart();
}

    protected LineChart<String, Number> createChart() {
    final CategoryAxis xAxis = new CategoryAxis();
    final NumberAxis yAxis = new NumberAxis();

    // setup chart
    series.setName("Target");
    series2.setName("Actual");
    xAxis.setLabel("Period");
    yAxis.setLabel("£");

    yearChart.getData().add(series);
    yearChart.getData().add(series2);

    yearChart.setCreateSymbols(false);

    return yearChart;
}

Ответ, предоставленный jewelsea, является идеальным решением этой проблемы.

Спасибо, драгоценность.

Ответы

Ответ 1

Используйте XYChart.Data.setNode(hoverPane), чтобы отобразить пользовательский node для каждой точки данных. Сделайте hoverNode контейнером, как StackPane. Добавьте прослушиватели событий мыши, чтобы вы знали, когда мышь входит и выходит the node. В поле ввода введите Label для значения внутри hoverPane. После выхода снимите метку с панели hover.

Существует несколько пример кода, чтобы продемонстрировать эту технику.

Вывод образца кода показан с курсором, наведенным на 22 node.

hoverednode

Ответ 2

Использование всплывающей подсказки:

@Override
public void start(Stage stage) {
    stage.setTitle("Line Chart Sample");
    //defining the axes
    final NumberAxis xAxis = new NumberAxis();
    final NumberAxis yAxis = new NumberAxis();
    xAxis.setLabel("Number of Month");
    //creating the chart
    final LineChart<Number,Number> lineChart = new LineChart<>(xAxis,yAxis);

    lineChart.setTitle("Stock Monitoring, 2010");
    //defining a series
    XYChart.Series series = new XYChart.Series();
    series.setName("My portfolio");
    //populating the series with data
    Random rand = new Random();

    TreeMap<Integer, Integer> data = new TreeMap();

    for(int i = 0; i < 3; i++)
    {
        data.put(rand.nextInt(51), rand.nextInt(51));            
    }

    Set set = data.entrySet();
    Iterator i = set.iterator();
    while(i.hasNext())
    {
        Map.Entry me = (Map.Entry)i.next();
        System.out.println(me.getKey() + " - " + me.getValue());
        series.getData().add(new XYChart.Data(me.getKey(), me.getValue()));
    }

    lineChart.getData().add(series);

    Set<Node> node = lineChart.lookupAll(".default-color0.chart-line-symbol.series0.");                    
    node.forEach((element) -> {
        element.setOnMouseEntered((MouseEvent event1) -> {
            double x = event1.getScreenX();
            double y = event1.getScreenY();
            List keys = new ArrayList(data.keySet());
            System.out.println("over value!");
            if (event1.getSource().toString().contains("data0")) {
                Tooltip t = new Tooltip(data.get(Integer.parseInt(keys.get(0).toString())).toString());
                Tooltip.install(element, t);
            } else if (event1.getSource().toString().contains("data1")) {
                 Tooltip t = new Tooltip(data.get(Integer.parseInt(keys.get(1).toString())).toString());
                 Tooltip.install(element, t);
            } else if (event1.getSource().toString().contains("data2")) {
                 Tooltip t = new Tooltip(data.get(Integer.parseInt(keys.get(2).toString())).toString());
                Tooltip.install(element, t);
            }
        });
    });

    Scene scene  = new Scene(lineChart,800,600);

    stage.setScene(scene);
    stage.show();
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    launch(args);
}