JavaFX LineChart with Values

DevelopmentPeasant :

I want to show values on top of the linechart. I've seen this answer which is quite helpful but it changes the linechart nodes. What I want is same idea but showing values not on nodes, but near them (maybe right and above of them) something like:

     53
    O
   / \
  /   \
 /42   \ 21           21
O       O------------O

EDIT:

I've tried to code below but sadly only lines appear, doesnt show nodes.

for (int index = 0; index < value.getData().size(); index++) {
                XYChart.Data dataPoint = value.getData().get(index);
                Node lineSymbol = dataPoint.getNode().lookup(".chart-line-symbol");
                lineSymbol.setStyle("-fx-background-color: " + definedColor + " , white;");

                Label label = new Label(value.getName());
                label.toFront();
                Pane nodeWithText = new Pane();
                label.setStyle("-fx-font-size: 20; -fx-font-weight: bold;");
                StackPane stackPane = new StackPane();
                Group group = new Group(label);
                group.getChildren().add(lineSymbol);
                group.toFront();
                group.setLayoutX(-10);
                group.setLayoutY(-30);
                StackPane.setAlignment(group, Pos.TOP_RIGHT);
                StackPane.setMargin(group,new Insets(0,0,5,0));
                nodeWithText.getChildren().add(group);
                nodeWithText.getChildren().add(lineSymbol);
                dataPoint.setNode(nodeWithText);
}
Slaw :

One option is to set a custom Node for each Data in your chart. Here's a crude example:

import javafx.application.Application;
import javafx.beans.binding.ObjectExpression;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        var chart = new LineChart<>(new NumberAxis(), new NumberAxis());
        chart.getData().add(new Series<>(createData()));

        primaryStage.setScene(new Scene(chart, 600, 400));
        primaryStage.show();
    }

    private static ObservableList<Data<Number, Number>> createData() {
        var list = FXCollections.<Data<Number, Number>>observableArrayList();
        for (int x = 0; x < 10; x++) {
            var data = new Data<Number, Number>(x, Math.pow(x, 2));
            data.setNode(createDataNode(data.YValueProperty()));
            list.add(data);
        }
        return list;
    }

    private static Node createDataNode(ObjectExpression<Number> value) {
        var label = new Label();
        label.textProperty().bind(value.asString("%,.2f"));

        var pane = new Pane(label);
        pane.setShape(new Circle(6.0));
        pane.setScaleShape(false);

        label.translateYProperty().bind(label.heightProperty().divide(-1.5));

        return pane;
    }

}

The above doesn't do anything complex when it comes to positioning the text. For instance, it won't take into account where the line is nor whether or not some of the text is cut off by the chart's clip. Basically, it's a proof-of-concept; the result looks like:

image showing result of example

Some other possible options for adding text to the chart include:

  1. Put the LineChart in a Group or Pane where the chart is the first child. Then, for each Data in your chart, you'd add a Label or Text to the parent and position it relative to the position of the Data's node (when it becomes available). You can calculate these positions using methods such as Node#localToScene and Node#sceneToLocal.
  2. Subclass LineChart and add the Text or Label to the chart directly. As I've never subclassed a chart before, I'm not sure how to implement this option.
  3. Something else I'm not thinking of.

Note that, no matter what you do, if your chart has a lot of data points very close to each other then displaying all the text in a visually pleasing way will be difficult—if not impossible.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=116406&siteId=1