如何清除javafx条形图中添加的文本?

如何清除javafx条形图中添加的文本?,java,text,javafx,charts,bar-chart,Java,Text,Javafx,Charts,Bar Chart,我在条的顶部添加了一些文本(每个条的值)。它正在工作,但问题是每次更新图表时我都想删除此文本。事实上,文本在更新数据后会保持不变 对于第一个图表,由于没有以前的数据,因此它显示正确。 但在我更新图表数据后,我得到的是(它正在工作,但之前添加的文本仍然存在…): 我用红色突出显示了错误的部分 我使用以下方法将文本添加到每个栏的顶部: private void displayLabelForData(XYChart.Data<String, Number> data) { f

我在条的顶部添加了一些文本(每个条的值)。它正在工作,但问题是每次更新图表时我都想删除此文本。事实上,文本在更新数据后会保持不变

对于第一个图表,由于没有以前的数据,因此它显示正确。

但在我更新图表数据后,我得到的是(它正在工作,但之前添加的文本仍然存在…):

我用红色突出显示了错误的部分

我使用以下方法将文本添加到每个栏的顶部:

private void displayLabelForData(XYChart.Data<String, Number> data) {
    final Node node = data.getNode();
    final Text dataText = new Text(data.getYValue() + "");
    node.parentProperty().addListener(new ChangeListener<Parent>() {
      @Override public void changed(ObservableValue<? extends Parent> ov, Parent oldParent, Parent parent) {
        Group parentGroup = (Group) parent;
        parentGroup.getChildren().add(dataText);
      }
    });

    node.boundsInParentProperty().addListener(new ChangeListener<Bounds>() {
      @Override public void changed(ObservableValue<? extends Bounds> ov, Bounds oldBounds, Bounds bounds) {
        dataText.setLayoutX(
          Math.round(
            bounds.getMinX() + bounds.getWidth() / 2 - dataText.prefWidth(-1) / 2
          )
        );
        dataText.setLayoutY(
          Math.round(
            bounds.getMinY() - dataText.prefHeight(-1) * 0.5
          )
        );
      }
    });
}
private void displaybelfordata(XYChart.Data){
最终节点=data.getNode();
final Text dataText=新文本(data.getYValue()+);
node.parentProperty().addListener(新的ChangeListener()){

@Override public void changed(observeValue我只找到了一个解决方案,那就是在收到更新时清除每个数据的每个parentNode。然后重新构建整个系列。 如下所示,它可以工作,但我没有检查性能。在我的环境中,速度非常快:

ObservableList<Series<String, Number>> allSeries = yourBarChart.getData();
    if (updateReceived) {
        for (XYChart.Series<String, Number> series : allSeries) {
            for (XYChart.Data<String, Number> data : series.getData()) {
                Node node = data.getNode();
                Parent parent = node.parentProperty().get();
                if (parent != null && parent instanceof Group) {
                    Group group = (Group) parent;
                    group.getChildren().clear();
                }
            }
        }
        allSeries.clear();
    }
observeList allSeries=yourBarChart.getData();
如果(updateReceived){
用于(XYChart.Series系列:allSeries){
对于(XYChart.Data:series.getData()){
Node=data.getNode();
Parent=node.parentProperty().get();
if(parent!=null&&parent instanceof Group){
组组=(组)父级;
group.getChildren().clear();
}
}
}
allSeries.clear();
}

我发现只有一个解决方案,那就是在收到更新时清除每个数据的每个parentNode。然后重新构建整个系列。 如下所示,它可以工作,但我没有检查性能。在我的环境中,速度非常快:

ObservableList<Series<String, Number>> allSeries = yourBarChart.getData();
    if (updateReceived) {
        for (XYChart.Series<String, Number> series : allSeries) {
            for (XYChart.Data<String, Number> data : series.getData()) {
                Node node = data.getNode();
                Parent parent = node.parentProperty().get();
                if (parent != null && parent instanceof Group) {
                    Group group = (Group) parent;
                    group.getChildren().clear();
                }
            }
        }
        allSeries.clear();
    }
observeList allSeries=yourBarChart.getData();
如果(updateReceived){
用于(XYChart.Series系列:allSeries){
对于(XYChart.Data:series.getData()){
Node=data.getNode();
Parent=node.parentProperty().get();
if(parent!=null&&parent instanceof Group){
组组=(组)父级;
group.getChildren().clear();
}
}
}
allSeries.clear();
}

就我个人而言,我更喜欢对条形图进行子类化,并重写适当的方法

这只是一个针对您需要的演示,还有一些改进需要完成,即覆盖所有相关方法、文本格式化程序、文本居中、调整图表区域大小以适应添加的文本等。但我想您会明白:

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

import javafx.application.Application;
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.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class BarChartSample 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";

    /**
     * Barchart with a clear button
     */
    @Override
    public void start(Stage stage) {

        final CategoryAxis xAxis = new CategoryAxis();
        final NumberAxis yAxis = new NumberAxis();
        final BarChartExt<String, Number> bc = new BarChartExt<String, Number>(xAxis, yAxis);

        bc.setTitle("Country Summary");
        xAxis.setLabel("Country");
        yAxis.setLabel("Value");

        XYChart.Series series1 = new XYChart.Series();
        series1.setName("2003");
        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));

        XYChart.Series series2 = new XYChart.Series();
        series2.setName("2004");
        series2.getData().add(new XYChart.Data(austria, 57401.85));
        series2.getData().add(new XYChart.Data(brazil, 41941.19));
        series2.getData().add(new XYChart.Data(france, 45263.37));
        series2.getData().add(new XYChart.Data(italy, 117320.16));
        series2.getData().add(new XYChart.Data(usa, 14845.27));

        XYChart.Series series3 = new XYChart.Series();
        series3.setName("2005");
        series3.getData().add(new XYChart.Data(austria, 45000.65));
        series3.getData().add(new XYChart.Data(brazil, 44835.76));
        series3.getData().add(new XYChart.Data(france, 18722.18));
        series3.getData().add(new XYChart.Data(italy, 17557.31));
        series3.getData().add(new XYChart.Data(usa, 92633.68));

        bc.getData().addAll(series1, series2, series3);

        Button clearButton = new Button("Clear");
        clearButton.setOnAction(e -> {

            bc.getData().clear();

        });

        HBox toolbar = new HBox();
        toolbar.getChildren().addAll(clearButton);

        VBox root = new VBox();
        VBox.setVgrow(bc, Priority.ALWAYS);
        root.getChildren().addAll(toolbar, bc);

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

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

    /**
     * Custom barchart with text on top of bars
     *
     * @param <X>
     * @param <Y>
     */
    private static class BarChartExt<X, Y> extends BarChart<X, Y> {

        /**
         * Registry for text nodes of the bars
         */
        Map<Node, Node> nodeMap = new HashMap<>();

        public BarChartExt(Axis xAxis, Axis yAxis) {
            super(xAxis, yAxis);
        }

        /**
         * Add text for bars
         */
        @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);

                Node text = new Text(String.valueOf(item.getYValue()));
                nodeMap.put(item.getNode(), text);
                getPlotChildren().add(text);

            }

        }

        /**
         * Remove text of bars
         */
        @Override
        protected void seriesRemoved(final Series<X, Y> series) {

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

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

            }

            nodeMap.clear();

            super.seriesRemoved(series);
        }

        /**
         * Adjust text of bars, position them on top
         */
        @Override
        protected void layoutPlotChildren() {

            super.layoutPlotChildren();

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

                Node text = nodeMap.get(bar);

                text.relocate(bar.getBoundsInParent().getMinX(), bar.getBoundsInParent().getMinY() - 30);

            }

        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
import java.util.HashMap;
导入java.util.Map;
导入javafx.application.application;
导入javafx.scene.Node;
导入javafx.scene.scene;
导入javafx.scene.chart.Axis;
导入javafx.scene.chart.BarChart;
导入javafx.scene.chart.CategoryAxis;
导入javafx.scene.chart.NumberAxis;
导入javafx.scene.chart.XYChart;
导入javafx.scene.control.Button;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.Priority;
导入javafx.scene.layout.VBox;
导入javafx.scene.text.text;
导入javafx.stage.stage;
公共类BarChartSample扩展了应用程序{
最终静态字符串austria=“austria”;
最终静态字符串巴西=“巴西”;
最终静态字符串france=“france”;
最终静态字符串意大利=“意大利”;
最终静态字符串usa=“usa”;
/**
*带清除按钮的条形图
*/
@凌驾
公众假期开始(阶段){
最终CategoryAxis xAxis=新CategoryAxis();
最终数字axis yAxis=新数字axis();
最终条形图文本bc=新的条形图文本(xAxis,yAxis);
bc.setTitle(“国家概要”);
xAxis.setLabel(“国家”);
yAxis.setLabel(“值”);
XYChart.Series系列1=新的XYChart.Series();
系列1.集合名称(“2003”);
series1.getData().add(新的XYChart.Data(奥地利,25601.34));
series1.getData().add(新的XYChart.Data(巴西,20148.82));
series1.getData().add(新的XYChart.Data(法国,10000));
series1.getData().add(新的XYChart.Data(意大利,35407.15));
series1.getData().add(新的XYChart.Data(美国,12000));
XYChart.Series系列2=新的XYChart.Series();
序列2.集合名称(“2004”);
series2.getData().add(新的XYChart.Data(奥地利,57401.85));
series2.getData().add(新的XYChart.Data(巴西,41941.19));
series2.getData().add(新的XYChart.Data(法国,45263.37));
series2.getData().add(新的XYChart.Data(意大利,117320.16));
series2.getData().add(新的XYChart.Data(美国,14845.27));
XYChart.Series系列3=新的XYChart.Series();
系列3.集合名称(“2005”);
series3.getData().add(新的XYChart.Data(奥地利,45000.65));
series3.getData().add(新的XYChart.Data(巴西,44835.76));
series3.getData().add(新的XYChart.Data(法国,18722.18));
series3.getData().add(新的XYChart.Data(意大利,17557.31));
series3.getData().add(新的XYChart.Data(美国,92633.68));
bc.getData().addAll(系列1、系列2、系列3);
按钮清除按钮=新按钮(“清除”);
clearButton.setOnAction(e->{
bc.getData().clear();
});
HBox工具栏=新的HBox();
toolbar.getChildren().addAll(clearButton);
VBox root=新的VBox();
setVgrow(bc,Priority.ALWAYS);
root.getChildren().addAll(工具栏,bc);
场景=新场景(根,800600);
舞台场景;
stage.show();
}
/**
*在条形图顶部显示文本的自定义条形图
*
*@param
*@param
*/
私有静态类BarChartText扩展了BarChart{
/**
*条形图文本节点的注册表
*/
Map nodeMap=newhashmap();
公共条形图文本(X轴、Y轴){
超级(xA)