2014-11-07 19 views
9

Ho creato un grafico a dispersione con due serie di dati; il primo set è il dato reale (x = anno e y = pence) e il secondo set produce gli stessi punti ma per la linea di regressione. Tuttavia il problema che sto avendo è che entrambi i gruppi di dati sono mostrati come punti di dispersione. Voglio mostrare il primo set come punti di dispersione e avere il secondo set sullo stesso grafico ma mostrare come una linea. Ci sono stato per molto tempo ma non riesco a trovare un modo per farlo.Come combinare il grafico a dispersione con il grafico a linee per mostrare la linea di regressione? JavaFX

il codice del grafico a dispersione è mostrato su Oracle; http://docs.oracle.com/javafx/2/charts/scatter-chart.htm

Per esempio, ho cercato di fare questo:

final ScatterChart<Number,Number> sc = new 
     ScatterChart<Number,Number>(xAxis,yAxis); 
final LineChart<Number,Number> lc = new 
     LineChart<Number,Number>(xAxis,yAxis); 

XYChart.Series series1 = new XYChart.Series(); 
    series1.setName("Equities"); 
    series1.getData().add(new XYChart.Data(4.2, 193.2)); 
    series1.getData().add(new XYChart.Data(2.8, 33.6)); 

XYChart.Series series2 = new XYChart.Series(); 
    series2.setName("Mutual funds"); 
    series2.getData().add(new XYChart.Data(5.2, 229.2)); 
    series2.getData().add(new XYChart.Data(2.4, 37.6)); 

    sc.getData().addAll(series1); 
    lc.getData(0.addAll(series2); 
    Scene scene = new Scene(sc, 500, 400); 
    stage.setScene(scene); 
    stage.show(); 
} 

public static void main(String[] args) { 
    launch(args); 
} 

Il problema è che la scena può essere impostato solo a uno sc o LC, non entrambi. C'è qualcosa che posso fare o è semplicemente impossibile?

Grazie

+0

Vedere anche alcuni [codice di esempio per chars in pila e collegamenti ai relativi post del forum Oracle JavaFX] (https://gist.github.com/jewelsea/3668862) e [RT-12170 chart API - più tipi di grafici sul stesso asse] (http://javafx-jira.kenai.com/browse/RT-12710). – jewelsea

risposta

13

Mentre soluzione @Mailkov è soddisfacente, presenta alcuni inconvenienti (sovrapposti legende, tooltips ...).

Solo per mescolare un grafico a dispersione con un grafico a linee nello stesso grafico c'è un modo molto semplice, con css.

Creiamo uno LineChart con due serie. Diciamo che il primo è lo scatter, e il secondo la linea, e con css ci sbarazziamo della linea per il primo, mentre (questo è opzionale) togliamo i simboli del secondo e manteniamo entrambe le leggende.

Usando questo css (chart.css):

.default-color0.chart-series-line { -fx-stroke: transparent; } 
.default-color1.chart-series-line { -fx-stroke: red; } 

.default-color0.chart-line-symbol { 
    -fx-background-color: white, green; 
} 
.default-color1.chart-line-symbol { 
    -fx-background-color: transparent, transparent; 
} 

.default-color0.chart-legend-item-symbol{ 
    -fx-background-color: green; 
} 
.default-color1.chart-legend-item-symbol{ 
    -fx-background-color: red; 
} 

e questo codice:

@Override 
public void start(Stage stage) { 
    final LineChart<Number,Number> sc = new LineChart<>(new NumberAxis(),new NumberAxis()); 

    XYChart.Series series1 = new XYChart.Series(); 
    series1.setName("Equities"); 
    series1.getData().add(new XYChart.Data(4.2, 193.2)); 
    series1.getData().add(new XYChart.Data(2.8, 33.6)); 
    series1.getData().add(new XYChart.Data(6.8, 23.6)); 

    XYChart.Series series2 = new XYChart.Series(); 
    series2.setName("Mutual funds"); 
    series2.getData().add(new XYChart.Data(5.2, 229.2)); 
    series2.getData().add(new XYChart.Data(2.4, 37.6)); 
    series2.getData().add(new XYChart.Data(6.4, 15.6)); 

    sc.setAnimated(false); 
    sc.setCreateSymbols(true); 

    sc.getData().addAll(series1, series2); 

    Scene scene = new Scene(sc, 500, 400); 
    scene.getStylesheets().add(getClass().getResource("root.css").toExternalForm()); 
    stage.setScene(scene); 
    stage.show(); 
} 

avremo una semplice tabella con due diverse serie:

scatter and line chart

0

aggiungo Pane due ScatterChart e ho impostato l'opacità a (0,5) provarlo.

Spero di aver aiutato.

final ScatterChart<Number,Number> sc = new 
    ScatterChart<Number,Number>(xAxis,yAxis); 
final LineChart<Number,Number> lc = new 
    LineChart<Number,Number>(xAxis,yAxis); 

XYChart.Series series1 = new XYChart.Series(); 
series1.setName("Equities"); 
series1.getData().add(new XYChart.Data(4.2, 193.2)); 
series1.getData().add(new XYChart.Data(2.8, 33.6)); 

XYChart.Series series2 = new XYChart.Series(); 
series2.setName("Mutual funds"); 
series2.getData().add(new XYChart.Data(5.2, 229.2)); 
series2.getData().add(new XYChart.Data(2.4, 37.6)); 

sc.getData().addAll(series1); 
lc.getData().addAll(series2); 

Pane pane=new Pane(); 
pane.getChildren().add(sc); 
pane.getChildren().add(lc); 

lc.setOpacity(0.5); 

Scene scene = new Scene(pane, 500, 400); 
stage.setScene(scene); 
stage.show(); 
} 

public static void main(String[] args) { 
    launch(args); 
} 
0

Non ho abbastanza "reputazione" per aggiungere un commento sotto Mailkov risposta, ma penso che ci sia un problema con la risposta proposta.

1) In effetti, i punti arancioni completi del grafico a dispersione non sono dove dovrebbero essere (x = 2.8 e x = 4.2).

enter image description here

import javafx.scene.layout.Pane; 
import javafx.stage.Stage; 

public class Exemple158bis_JavaFX_Overlaid_Stacked_Charts extends Application { 

@Override 
public void start(Stage stage) throws Exception { 

    NumberAxis xAxis = new NumberAxis(); 
    NumberAxis yAxis = new NumberAxis(); 

    final ScatterChart<Number, Number> sc = new ScatterChart<>(xAxis, yAxis); 
    final LineChart<Number, Number> lc = new LineChart<>(xAxis, yAxis); 

    XYChart.Series series1 = new XYChart.Series(); 
    series1.setName("Equities"); 
    series1.getData().add(new XYChart.Data(4.2, 193.2)); 
    series1.getData().add(new XYChart.Data(2.8, 33.6)); 

    XYChart.Series series2 = new XYChart.Series(); 
    series2.setName("Mutual funds"); 
    series2.getData().add(new XYChart.Data(5.2, 229.2)); 
    series2.getData().add(new XYChart.Data(2.4, 37.6)); 

    sc.getData().addAll(series1); 
    lc.getData().addAll(series2); 

    Pane pane = new Pane(); 
    pane.getChildren().add(sc); 
    pane.getChildren().add(lc); 

    lc.setOpacity(0.5); 

    Scene scene = new Scene(pane, 800, 600); 
    stage.setScene(scene); 
    stage.show(); 
} 

public static void main(String[] args) { 
    launch(args); 
} 

} 

2) Una soluzione è quella di impostare i limiti dell'asse dall'inizio:

NumberAxis xAxis = new NumberAxis(0, 5.5, 0.5); 
NumberAxis yAxis = new NumberAxis(0, 240, 10); 

enter image description here

0

Un modo più semplice potrebbe essere semplicemente utilizzare LineChart per tutte le serie e quindi aggiungere la riga sottostante per qualsiasi serie in cui si non si desidera tracciare le linee. La riga in basso modifica la serie 0 per non avere alcuna linea, ma per le altre serie è sufficiente modificare il numero (colore predefinito XX) per definire quale serie.

sc.lookup(".default-color0.chart-series-line").setStyle("-fxstroke: transparent"); 

Molto simile a @ José Pereda ma forse un po 'più semplice che fare casino con i file CSS.

Problemi correlati