【问题标题】:javafx implement x-value labels for a line chartjavafx 为折线图实现 x 值标签
【发布时间】:2015-07-01 15:33:13
【问题描述】:

我尝试根据这篇帖子label on barchart 实现jewelsea 的方法,但标签不可见,我不明白为什么。 唯一的区别是我使用的是 fxml 文件,而我的图表数据由几个系列组成。

为了更好地说明问题,我做了一个MVCE:

public class PaneController implements Initializable{
	@FXML
	private LineChart<Number, Number> lineChart;

	@Override
	public void initialize(URL location, ResourceBundle resources) {
		// TODO Auto-generated method stub
		lineChart.setLegendVisible(false);
		lineChart.setCreateSymbols(false);
		lineChart.setData(createData());
		
		/** for each serie add label on the peak if intensity > 0 */
		for(int i=0;i<lineChart.getData().size();i++){
			for(XYChart.Data<Number, Number> value:lineChart.getData().get(i).getData()){
				if(value.getYValue().intValue()>0){
		    	value.nodeProperty().addListener(new ChangeListener<Node>() {
		            @Override public void changed(ObservableValue<? extends Node> ov, Node oldNode, final Node node) {
		            	System.out.println("value:"+node);
		                if (node != null) {
		                  displayLabelForData(value);
		                } 
		              }
		            });
				}
		    }
		}
		
	}
	/** create data for the line chart */
	public ObservableList<Series<Number,Number>> createData(){
		 ObservableList<Series<Number,Number>> data = FXCollections.observableArrayList();
		 for(int i=1;i<=10;i++){
			 XYChart.Series<Number, Number> peakSelect = new XYChart.Series<>();
			 peakSelect.getData().add(new XYChart.Data<Number, Number>(i,0));
			 peakSelect.getData().add(new XYChart.Data<Number, Number>(i,i*2));
			 data.add(peakSelect);
		 }
		 return data;
	}
	
	  /** places a x value label on each peak */
	  private void displayLabelForData(XYChart.Data<Number, Number> data){
		  final Node node = data.getNode();
		  final Text dataText = new Text(data.getXValue() + "");
		  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 ) );
			  }
		  });
	  }
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.chart.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<AnchorPane xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.PaneController">
   <children>
      <LineChart fx:id="lineChart" prefHeight="400.0" prefWidth="500.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
        <xAxis>
          <NumberAxis side="BOTTOM" />
        </xAxis>
        <yAxis>
          <NumberAxis side="LEFT" />
        </yAxis>
      </LineChart>
   </children>
</AnchorPane>

主类:

public class Main extends Application {
	@Override
	public void start(Stage primaryStage) {
		try {
			FXMLLoader loader = new FXMLLoader();
			loader.setLocation(Main.class.getResource("Pane.fxml"));
			AnchorPane rootPane = (AnchorPane) loader.load();
			Scene scene = new Scene(rootPane);
			primaryStage.setScene(scene);
			primaryStage.setTitle("Test");
			primaryStage.show();
			
			PaneController controller = loader.getController();
            
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		launch(args);
	}
}

感谢您的帮助!

【问题讨论】:

  • 问题在于value.nodeProperty().addListener 行的initialize 方法。不知何故,ChangeListener 从未被调用过。我看看能不能找出原因。

标签: javafx-2 javafx-8


【解决方案1】:

我不知道如何解决您的问题,但是我可以为您指出另一种获得类似效果的方法。如果你需要使用折线图,你可以试试这个https://stackoverflow.com/a/14623439/4683264。但是,从您的示例看来,您可以使用条形图,并使用您链接的问题中的 Jewelsea 的答案。

【讨论】:

  • 好的,谢谢你的回答,我注意到没有使用监听器,但我不明白为什么。我认为问题不在于图表的类型,而在于 fxml 文件的使用。我用折线图尝试了jewelsea的代码,它可以工作。
  • @Thomas 视图节点一直为空,它从未设置过...无论如何很高兴我能提供帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 2014-01-01
  • 1970-01-01
相关资源
最近更新 更多