JavaFX:如何在区域图表上动态添加几个系列并从图表中删除行(系列)? [英] JavaFX: How to add serveral series dynimically on Area Chart and delete line(series) from chart?

查看:187
本文介绍了JavaFX:如何在区域图表上动态添加几个系列并从图表中删除行(系列)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JavaFX的Area Chart。我想在用户在文本字段中输入值并按添加按钮后动态添加系列。我还想在其中添加删除和撤消功能。删除功能就像是,例如,如果区域图上有多行代表每行代表系列,用户可以通过点击该行并点击删除按钮后删除他想要的任何行。我还想添加撤消功能,以便用户可以撤消他的操作。



界面如下:





例如,用户可以通过填写文本字段来绘制这样的行:







现在让用户想要删除红色系列我想要的是用户点击它,点击删除按钮后它会删除这样的红色系列:





<到目前为止,我已经尝试过这个:

  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;

公共类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);

}


//按钮添加功能
@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));
}


//将系列添加到AreaChart。
areaChart.getData()。add(series);

//鼠标点击甚至是系列
setOnMouseEventsOnSeries(series.getNode(),
areaChart,点击系列);
}


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

}
}

FXML文件:

 <?xml version =1.0encoding =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 =CENTERprefHeight =800.0prefWidth =800.0xmlns =http://javafx.com/javafx/8.0.111xmlns:fx =http: //javafx.com/fxml/1fx:controller =application.SampleController>
< children>
< AreaChart fx:id =areaChartprefHeight =799.0prefWidth =800.0VBox.vgrow =ALWAYS>
< xAxis>
< NumberAxis autoRanging =falseminorTickCount =1minorTickLength =1.0side =BOTTOMtickLabelGap =1.0tickLength =1.0tickUnit =1.0upperBound =24.0fx:id =xAxis/>
< / xAxis>
< yAxis>
< NumberAxis fx:id =yAxisautoRanging =falseminorTickLength =1.0side =LEFTtickLabelGap =1.0tickUnit =1.0upperBound =10.0/>
< / yAxis>
< / AreaChart>
< HBox alignment =CENTERprefHeight =193.0prefWidth =800.0>
< children>
< TextField fx:id =txtStpromptText =Start Value/>
< TextField fx:id =txtEtpromptText =End Value/>
< TextField fx:id =txtNbpromptText =员工人数/>
< / children>
< / HBox>
< HBox alignment =CENTERprefHeight =71.0prefWidth =800.0>
< children>
< Button mnemonicParsing =falseonAction =#generateGraphprefHeight =31.0prefWidth =137.0text =Add/>
< Button layoutX =342.0layoutY =12.0mnemonicParsing =falseprefHeight =31.0prefWidth =137.0text =Delete/>
< Button layoutX =410.0layoutY =12.0mnemonicParsing =falseprefHeight =31.0prefWidth =137.0text =Undo/>
< / children>
< / HBox>
< / children>
< / VBox>

请有人指导我如何实现这些功能。

解决方案

这应该可以帮助您入门。我添加了一个 ArrayList 来跟上系列,它们被添加到 Chart 。评论在代码中。您可以弄清楚如何从 ArrayList 和/或图表中删除​​/删除项目,或者如何从 ArrayList 然后更新图表

  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
* /
公共类FXMLDocumentController实现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(); //使用ArrayList来保存新系列!


//按钮添加功能
@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));
}


//将系列添加到系列容器中。
seriesContainer.add(系列);

//只为AreaChart
添加新系列(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);
}
}


I am working with Area Chart of JavaFX. I want to add series dynamically after user will enter values in text fields and press Add button. I also want to add delete and undo functionality in it. Delete functionality working would be like for instance if there are several lines on the Area Chart each line represents series, user can delete any line he want by clicking on that line and after clicking on delete button. I also want to add undo functionality so user can undo his actions.

The interface is like this:

For example user can draw line like this by filling text fields:

Now let say the user want to delete the series which is in red color what I want is user click on it and after click delete button it'll delete the red series like this:

So far I've tried this:

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

        }
}

FXML file:

<?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>

Please someone guide me how can I achieve these functionalities.

解决方案

This should help you get started. I added an ArrayList to keep up with Series that are added to the Chart. Comments are in the code. You can figure out how to delete/remove items from the ArrayList and/or Chart or how to remove items from the ArrayList then update the 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");
    }
}

这篇关于JavaFX:如何在区域图表上动态添加几个系列并从图表中删除行(系列)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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