如何清除javafx条形图中添加的文本? [英] How to clear text added in a javafx barchart?

查看:177
本文介绍了如何清除javafx条形图中添加的文本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在条形图的顶部添加了一些文本(每个条形图的值)。它正在工作,但问题是我想在每次更新图表时删除此文本。实际上,文本在更新数据后仍然存在。



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



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



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



我使用此方法在每个条形图的顶部添加文本:

  private void displayLabelForData(XYChart .Data< String,Number>数据){
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

);
}
});
}

我的完整代码可用


I add some text at the top of bars (the value of each bar). It's working but the problem is I want to remove this text each time I update the chart. In fact, text stays after updating data.

For the first chart, since there is no previous data it's displaying correctly.

But after I update chart's data, here is what I get (it's working but previous added text remains...):

I highlighted in red the wrong part

I add the text on top of each bar with this method:

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
          )
        );
      }
    });
}

My full code is available on Gist

Still no answer to this...

Thanks !

解决方案

Personally I'd prefer subclassing BarChart and overriding the proper methods.

This is just a demo for your needs, there's refinement to be done, i. e. overriding all related methods, formatter for the text, centering the text, resize chart area to fit the added text, etc. But I guess you'll get the drift:

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);
    }
}

Screenshot:

这篇关于如何清除javafx条形图中添加的文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆