如何清除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)