【问题标题】:JavaFX LineChart Hover ValuesJavaFX LineChart 悬停值
【发布时间】:2013-01-14 22:51:57
【问题描述】:

我正在使用 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 提供的答案完美解决了这个问题。

谢谢你,珠宝海。

【问题讨论】:

    标签: javafx-2


    【解决方案1】:

    使用XYChart.Data.setNode(hoverPane) 为每个数据点显示一个自定义节点。使 hoverNode 成为像 StackPane 这样的容器。添加鼠标事件侦听器,以便您知道何时鼠标entersleaves 节点。在输入时,为 hoverPane 中的值放置一个 Label。退出时,从 hoverPane 中移除标签。

    有一些example code 来演示这种技术。

    将光标悬停在 22 节点上显示示例代码的输出。

    【讨论】:

    • 非常感谢您,我永远不会接近实现这一目标。最后还有一个小问题。你如何将悬停设置为始终在前面?我的一些值是 6 位数,它们隐藏在下一个节点后面,这很烦人 - 请参阅 i.imgur.com/oZgNMNH.png
    • 为保证悬停的节点始终是最上面的节点,只要鼠标进入节点时调用toFront即可。我更新了示例代码以包含此内容。
    • 非常感谢。我快到了,但认为 label.toFront() 会削减它,而不仅仅是 toFront()。再次感谢您的所有帮助,非常感谢:)
    • toFront() 意味着 hoverNode 会在他的父母面前正确吗?不在全图前面。如果您尝试添加更复杂的东西(更大的容器),那么您可能会超出范围。
    • 如何避免鼠标悬停在图表一角,标签只部分可见的情况?似乎标签只在图表区域内绘制,如果它的一部分在外面,我需要更换它,或者将它发送到图表之外的所有人的前面。有什么解决办法吗? @jewelsea
    【解决方案2】:

    使用工具提示:

    import java.util.Iterator;
    import java.util.Map;
    import java.util.Random;
    import java.util.Set;
    import java.util.TreeMap;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.chart.LineChart;
    import javafx.scene.chart.NumberAxis;
    import javafx.scene.chart.XYChart;
    import javafx.scene.chart.XYChart.Data;
    import javafx.scene.control.Tooltip;
    import javafx.stage.Stage;
    
    /**
     *
     * @author blj0011
     */
    public class JavaFXApplication250 extends Application
    {
    
        @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<Number, Number> series = new XYChart.Series();
            series.setName("My portfolio");
            //populating the series with data
            Random rand = new Random();
    
            TreeMap<Integer, Integer> data = new TreeMap();
            //Create Chart data
            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()));//Add data to series
            }
    
            lineChart.getData().add(series);
    
            //loop through data and add tooltip
            //THIS MUST BE DONE AFTER ADDING THE DATA TO THE CHART!
            for (Data<Number, Number> entry : series.getData()) {                
                System.out.println("Entered!");
                Tooltip t = new Tooltip(entry.getYValue().toString());
                Tooltip.install(entry.getNode(), 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);
        }    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-20
      • 2017-06-16
      • 1970-01-01
      • 2012-08-03
      • 2018-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多