如何使用数字或字符串轴创建通用JavaFX XYChart?

时间:2015-04-05 22:01:55

标签: java javafx javafx-8

现在我正在使用JavaFX图表,但我需要为每种图表类型创建一个通用类。例如,我需要创建一个ScatterChart,我可以从这个类创建一个ScatterChart,X = Number和Y = Number轴,X = String和Y = Number轴,X = Number和Y = String轴或X = String和Y = String,但我发现在使用Chart之前必须定义Chart的类型,并且不可能在同一个图表中更改轴的类型。

我试图做到这一点,但操纵数据的方法不起作用:

    public class JFXPanelScatterChartNS extends JFXPanel....
.....
private ScatterChart chart;
.......
public JFXPanelScatterChartNS(String[] xAxisCategories, String[] yAxisCategories ){

        if(xAxisCategories != null && yAxisCategories != null){
            xAxisCategory = new CategoryAxis(FXCollections.observableList(Arrays.asList(xAxisCategories))); 
            yAxisCategory = new CategoryAxis(FXCollections.observableList(Arrays.asList(yAxisCategories)));
            chart = new ScatterChart<String, String>(xAxisCategory, yAxisCategory);
        }else if(xAxisCategories != null){
            xAxisCategory = new CategoryAxis(FXCollections.observableList(Arrays.asList(xAxisCategories))); 
            yAxis = new NumberAxis(0.0,10.0,1.0);
            chart = new ScatterChart<String, Number>(xAxisCategory, yAxis);
        }else if(yAxisCategories != null){
            xAxis = new NumberAxis(0.0,10.0,1.0);
            yAxisCategory = new CategoryAxis(FXCollections.observableList(Arrays.asList(yAxisCategories)));
            chart = new ScatterChart<Number, String>(xAxis, yAxisCategory);
        }else{
            xAxis = new NumberAxis(0.0,10.0,1.0);
            yAxis = new NumberAxis(0.0,10.0,1.0);
            chart = new ScatterChart<Number, Number>(xAxis, yAxisCategory);
        }

        Platform.runLater(() -> {
            createScene(withDragAndDrop);
        });
    }

感谢您的帮助!!

现在我如何使用操作同一类中的数据的方法? 在下面的示例中,ScatterChar仅适用于X轴= Number和Y轴= String。

我目前的方法是:

public void addSeries(String idSeries, String nameSeries, final Number xIni, final String yIni){        
        final XYChart.Series<Number,String> newSeries;
        //Valido si el Id ya existe
        final boolean seriesExist = seriesMap.containsKey(idSeries);
        //si no existe el ID entonces creo la nueva serie
        if(!seriesExist){
            newSeries = new XYChart.Series<>();
            ObservableList<XYChart.Data<Number, String>> listaSerie;
            listaSerie = FXCollections.synchronizedObservableList(FXCollections.observableList(new ArrayList<XYChart.Data<Number, String>>()));
            newSeries.setData(listaSerie);
            newSeries.setName(nameSeries);
            newSeries.getData().add(new XYChart.Data<>(xIni,yIni));

            Platform.runLater(() -> {
                //Genero el index para la nueva serie
                Integer newIndex = new Integer(chart.getData().size());
                chart.getData().add(newIndex.intValue(), newSeries);
                seriesMap.put(idSeries, newIndex);
            });
        }
    }

    public void setData(final String idSeries, final int index, final Number x, final String y){
        //valido que exista la serie
        boolean seriesExist = seriesMap.containsKey(idSeries);
        //obtengo el index de la serie, como fue almacenada en la grafica
        Integer indexSerie =  seriesMap.get(idSeries);
        if(seriesExist){
            Platform.runLater(() -> {
                XYChart.Series<Number,String> currentSeries = null;
                currentSeries = chart.getData().get(indexSerie.intValue());
                currentSeries.getData().set(index,new XYChart.Data<>(x,y));
            });
        }
    }

1 个答案:

答案 0 :(得分:1)

考虑使用工厂方法而不是public构造函数,并对您拥有的方法进行一致化:

import java.util.Arrays;

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.embed.swing.JFXPanel;
import javafx.scene.chart.Axis;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.ScatterChart;


public class JFXPanelScatterChartNS<X,Y> extends JFXPanel {
    private ScatterChart<X,Y> chart ;

    private boolean withDragAndDrop = false ;

    private JFXPanelScatterChartNS(Axis<X> xAxis, Axis<Y> yAxis) {
        chart = new ScatterChart<>(xAxis, yAxis);
        Platform.runLater(() -> createScene(withDragAndDrop));
    }

    private void createScene(boolean withDragAndDrop) {
        // ...
    }

    public static JFXPanelScatterChartNS<String, String> createStringInstance(String[] xAxisCategories, String[] yAxisCategories) {
        Axis<String> xAxisCategory = new CategoryAxis(FXCollections.observableList(Arrays.asList(xAxisCategories))); 
        Axis<String> yAxisCategory = new CategoryAxis(FXCollections.observableList(Arrays.asList(yAxisCategories)));
        return new JFXPanelScatterChartNS<>(xAxisCategory, yAxisCategory);
    }

    public static JFXPanelScatterChartNS<String, Number> createStringNumberInstance(String[] xAxisCategories) {
        Axis<String> xAxisCategory = new CategoryAxis(FXCollections.observableList(Arrays.asList(xAxisCategories))); 
        return new JFXPanelScatterChartNS<String, Number>(xAxisCategory, new NumberAxis(0.0,10.0,1.0));
    }

    public static JFXPanelScatterChartNS<Number, String> createNumberStringInstance(String[] yAxisCategories) {
        Axis<String> yAxisCategory = new CategoryAxis(FXCollections.observableList(Arrays.asList(yAxisCategories))); 
        return new JFXPanelScatterChartNS<Number, String>(new NumberAxis(0.0,10.0,1.0), yAxisCategory);
    }

    public static JFXPanelScatterChartNS<Number, Number> createNumberInstance() {
        return new JFXPanelScatterChartNS<Number, Number>(new NumberAxis(0.0,10.0,1.0), new NumberAxis(0.0,10.0,1.0));        
    }

    public void addSeries(String idSeries, String nameSeries, final X xIni, final Y yIni){        
        final XYChart.Series<X,Y> newSeries;
        //Valido si el Id ya existe
        final boolean seriesExist = seriesMap.containsKey(idSeries);
        //si no existe el ID entonces creo la nueva serie
        if(!seriesExist){
            newSeries = new XYChart.Series<>();
            ObservableList<XYChart.Data<X, Y>> listaSerie;
            listaSerie = FXCollections.synchronizedObservableList(FXCollections.observableList(new ArrayList<XYChart.Data<X, Y>>()));
            newSeries.setData(listaSerie);
            newSeries.setName(nameSeries);
            newSeries.getData().add(new XYChart.Data<>(xIni,yIni));

            Platform.runLater(() -> {
                //Genero el index para la nueva serie
                Integer newIndex = new Integer(chart.getData().size());
                chart.getData().add(newIndex.intValue(), newSeries);

                seriesMap.put(idSeries, newIndex);
            });
        }
    }

    public void setData(final String idSeries, final int index, final X x, final Y y){
        //valido que exista la serie
        boolean seriesExist = seriesMap.containsKey(idSeries);
        //obtengo el index de la serie, como fue almacenada en la grafica
        Integer indexSerie =  seriesMap.get(idSeries);
        if(seriesExist){
            Platform.runLater(() -> {
                XYChart.Series<X,Y> currentSeries = null;
                currentSeries = chart.getData().get(indexSerie.intValue());
                currentSeries.getData().set(index,new XYChart.Data<>(x,y));
            });
        }
    }
}

现在您可以编写如下代码:

JFXPanelScatterChartNS<Number, String> chart = 
    JFXPanelScatterChartNS.createNumberStringInstance(new String[] {"A", "B", "C"});
chart.addSeries("Series1", "Series 1", 1, "A");

JFXPanelScatterChartNS<Number, Number> numberChart = 
    JFXPanelScatterChartNS.createNumberInstance();
numberChart.addSeries("Series2", "Series 2", 5, 3);