javafx为折线图

时间:2015-04-23 12:33:30

标签: javafx-2 javafx-8

我试图根据这篇文章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);
	}
}

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

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