2017-08-24 5 views
0

Je travaille avec Area Chart of JavaFX. Je souhaite ajouter des séries dynamiquement après que l'utilisateur saisisse des valeurs dans les champs de texte et appuie sur le bouton Ajouter. Je souhaite également ajouter des fonctionnalités de suppression et d'annulation. Supprimer la fonctionnalité fonctionnerait comme si, par exemple, il y avait plusieurs lignes sur la carte de zone, chaque ligne représente une série, l'utilisateur peut supprimer n'importe quelle ligne qu'il souhaite en cliquant sur cette ligne et après avoir cliqué sur le bouton Supprimer. Je veux également ajouter des fonctionnalités d'annulation afin que l'utilisateur puisse annuler ses actions.JavaFX: Comment ajouter une série serveral dynimically sur Area Chart et supprimer une ligne (série) d'un graphique?

L'interface est comme ceci:

enter image description here

Par exemple l'utilisateur peut tracer une ligne comme celui-ci en remplissant les champs de texte:

enter image description here

enter image description here

Maintenant, nous allons dire la l'utilisateur veut supprimer la série qui est en couleur rouge ce que je veux est l'utilisateur cliquez dessus et après cliquez sur le bouton supprimer, il effaçons la série rouge comme ceci:

enter image description here

Jusqu'à présent, j'ai essayé ceci:

import javafx.event.EventHandler; 
import javafx.fxml.FXML; 
import javafx.scene.Node; 
import javafx.scene.chart.AreaChart; 
import javafx.scene.chart.NumberAxis; 
import javafx.scene.chart.XYChart; 
import javafx.scene.control.TextField; 
import javafx.scene.input.MouseEvent; 

public class SampleController { 


    @FXML 
    private NumberAxis xAxis; 
    @FXML 
    private NumberAxis yAxis; 
    @FXML 
    private AreaChart<Number, Number> areaChart; 
    @FXML 
    private TextField txtSt; 
    @FXML 
    private TextField txtEt; 
    @FXML 
    private TextField txtNb; 


    public void initialize() { 

      areaChart.setTitle("Chronos"); 
      xAxis.setLabel("Heures"); 
      yAxis.setLabel("Employés"); 

    } 


     //Button add functionality 
     @FXML 
     private void generateGraph() { 

      //double start = Double.parseDouble(txtSt.getText()); 
      double end = Double.parseDouble(txtEt.getText()); 
      int numberEmployees = Integer.parseInt(txtNb.getText()); 

      XYChart.Series<Number, Number> series= new XYChart.Series<>(); 

      for (double start = Double.parseDouble(txtSt.getText()); start<=end; start++) { 
       series.getData().add(new XYChart.Data<Number, Number>(start, numberEmployees)); 
      } 


      // Add Series to AreaChart. 
      areaChart.getData().add(series); 

      //Mouse click even for series 
      setOnMouseEventsOnSeries(series.getNode(), 
        areaChart, "Series is clicked"); 
     } 


     private void setOnMouseEventsOnSeries(Node node, 
       final AreaChart chart, final String label) { 

      node.setOnMouseClicked(new EventHandler<MouseEvent>() { 

       @Override 
       public void handle(MouseEvent t) { 
        chart.setTitle(label); 
       } 
      }); 

     } 
} 

fichier FXML:

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.scene.chart.AreaChart?> 
<?import javafx.scene.chart.NumberAxis?> 
<?import javafx.scene.control.Button?> 
<?import javafx.scene.control.TextField?> 
<?import javafx.scene.layout.HBox?> 
<?import javafx.scene.layout.VBox?> 

<VBox alignment="CENTER" prefHeight="800.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.SampleController"> 
    <children> 
     <AreaChart fx:id="areaChart" prefHeight="799.0" prefWidth="800.0" VBox.vgrow="ALWAYS"> 
     <xAxis> 
      <NumberAxis autoRanging="false" minorTickCount="1" minorTickLength="1.0" side="BOTTOM" tickLabelGap="1.0" tickLength="1.0" tickUnit="1.0" upperBound="24.0" fx:id="xAxis" /> 
     </xAxis> 
     <yAxis> 
      <NumberAxis fx:id="yAxis" autoRanging="false" minorTickLength="1.0" side="LEFT" tickLabelGap="1.0" tickUnit="1.0" upperBound="10.0" /> 
     </yAxis> 
     </AreaChart> 
     <HBox alignment="CENTER" prefHeight="193.0" prefWidth="800.0"> 
     <children> 
      <TextField fx:id="txtSt" promptText="Start Value" /> 
      <TextField fx:id="txtEt" promptText="End Value" /> 
      <TextField fx:id="txtNb" promptText="Number of Employees" /> 
     </children> 
     </HBox> 
     <HBox alignment="CENTER" prefHeight="71.0" prefWidth="800.0"> 
     <children> 
      <Button mnemonicParsing="false" onAction="#generateGraph" prefHeight="31.0" prefWidth="137.0" text="Add" /> 
      <Button layoutX="342.0" layoutY="12.0" mnemonicParsing="false" prefHeight="31.0" prefWidth="137.0" text="Delete" /> 
      <Button layoutX="410.0" layoutY="12.0" mnemonicParsing="false" prefHeight="31.0" prefWidth="137.0" text="Undo" /> 
     </children> 
     </HBox> 
    </children> 
</VBox> 

Quelqu'un peut-il me guider comment puis-je atteindre ces fonctionnalités.

+0

Ajoutez votre fichier FXML. – Sedrick

+0

@SedrickJefferson La question est mise à jour – Junaid

+0

Bonjour @Junaid Désolé je ne suis pas actif dans SO ces jours-ci parce que j'ai commencé à travailler et à peine eu un temps. Cependant, il semble que vous ayez reçu une bonne réponse de Sedrick. :) – Yahya

Répondre

0

Cela devrait vous aider à démarrer. J'ai ajouté un ArrayList pour suivre les Series qui sont ajoutés au Chart. Les commentaires sont dans le code. Vous pouvez comprendre comment supprimer/supprimer des éléments du ArrayList et/ou Chart ou comment supprimer des éléments du ArrayList puis mettre à jour le Chart.

import java.net.URL; 
import java.util.ArrayList; 
import java.util.ResourceBundle; 
import javafx.event.EventHandler; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.Node; 
import javafx.scene.chart.AreaChart; 
import javafx.scene.chart.XYChart; 
import javafx.scene.control.TextField; 
import javafx.scene.input.MouseEvent; 

/** 
* 
* @author blj0011 
*/ 
public class FXMLDocumentController implements Initializable { 

// @FXML 
// private NumberAxis xAxis; 
// @FXML 
// private NumberAxis yAxis; 
    @FXML 
    private AreaChart<Number, Number> areaChart; 
    @FXML 
    private TextField txtSt; 
    @FXML 
    private TextField txtEt; 
    @FXML 
    private TextField txtNb; 


    ArrayList<XYChart.Series<Number, Number>> seriesContainer = new ArrayList();//Use an ArrayList to hold new Series! 


     //Button add functionality 
     @FXML 
     private void generateGraph() { 

      Double start = Double.parseDouble(txtSt.getText()); 

      Double end = Double.parseDouble(txtEt.getText()); 
      double numberEmployees = Integer.parseInt(txtNb.getText()); 

      XYChart.Series<Number, Number> series= new XYChart.Series<>(); 

      for (int i = start.intValue(); i <= end.intValue(); i++) { 
       series.getData().add(new XYChart.Data(i, numberEmployees)); 
      } 


      // Add Series to series container. 
      seriesContainer.add(series); 

      //Add only new series to AreaChart 
      for(XYChart.Series<Number, Number> entry : seriesContainer) 
      { 
       if(!areaChart.getData().contains(entry)) 
       {      
        areaChart.getData().add(entry); 
       } 
      } 
     } 

     private void setOnMouseEventsOnSeries(Node node, 
       final AreaChart chart, final String label) { 

      node.setOnMouseClicked(new EventHandler<MouseEvent>() { 

       @Override 
       public void handle(MouseEvent t) { 
        chart.setTitle(label); 
       } 
      }); 

     } 

    @Override 
    public void initialize(URL location, ResourceBundle resources) { 
     areaChart.setTitle("Chronos"); 
     areaChart.getXAxis().setLabel("Heures"); 
     areaChart.getYAxis().setLabel("Employés"); 
    } 
} 
+0

Merci @Sedrick l'a eu. Une autre chose pouvez-vous s'il vous plaît me dire comment je peux peupler à travers chacune des séries et obtenir leurs coordonnées X (première valeur et dernière valeur) et la valeur des coordonnées Y. J'ai besoin de cela parce que j'ai besoin de stocker chacune des valeurs de la série en DB. – Junaid

+0

Une seule question par fil. Vous devriez essayer sérieusement de résoudre votre nouveau problème. Après cela, vous devriez ouvrir une nouvelle question. – Sedrick

+0

Ok, je vais poster une nouvelle question avec ce que j'ai essayé jusqu'à présent. – Junaid