Database
 sql >> Database >  >> RDS >> Database

Lavorare con le API dei grafici JavaFX

Uno degli aspetti più importanti del report è rendere il contenuto il più visibile possibile in modo che l'essenza delle informazioni contenute nel report raggiunga il suo pubblico in modo rapido e semplice. I grafici svolgono un ruolo cruciale in questo senso. Presentare dati grezzi e cercare di immaginare lo scenario associato ai dati non è molto semplice, ma i grafici rappresentano un'essenza pittorica dei dati e aiutano lo spettatore a cogliere l'idea alla base dei dati grezzi molto rapidamente. JavaFX ha un supporto integrato per presentare dinamicamente i dati grezzi in una forma pittoresca. L'API ha due aspetti:uno può estendere le classi API e creare un grafico personalizzato da zero, oppure utilizzare le classi specifiche del grafico disponibili per creare un grafico con un codice minimo. Questo articolo approfondisce gli aspetti chiave delle API dei grafici di JavaFX e mostra come implementarli. Vengono forniti brevi esempi per assisterti.

Grafici JavaFX

I grafici JavaFX non sono solo facili da integrare con altre parti dell'applicazione, ma sono anche assorbiti dalla politica estensibile della tecnologia orientata agli oggetti che può essere personalizzata in base alle esigenze dello sviluppatore. Questa non è una cosa nuova, perché i progetti orientati agli oggetti sono sempre pensati per essere estensibili, ma la parte interessante dell'API dei grafici JavaFX è che ci sono molte classi di grafici già pronte che possono essere istanziate con una piccola o nessuna modifica nella sua proprietà per ottenere grafici dall'aspetto professionale. Queste classi di grafici sono le più comuni, personalizzabili e soddisfano quasi tutte le esigenze dello sviluppatore. Nella maggior parte dei casi, non è quasi necessario creare da zero un grafico personalizzato.

JavaFX fornisce otto di questi tipi di grafici nella libreria API con le loro funzionalità integrate. Sebbene ci siano molte classi e interfacce di supporto nella libreria dell'API dei grafici JavaFX, l'implementazione concreta otto è organizzata gerarchicamente come segue.


Figura 1: Il grafico della gerarchia della libreria dell'API dei grafici JavaFX

Pertanto, gli otto tipi comuni di grafico sono:grafico a torta , grafico a barre , grafico ad area , grafico a linee , grafico a dispersione , grafico a bolle , grafico ad area in pila e grafico a barre in pila .

Il grafico a torta

Il grafico a torta è un formato grafico comune in cui le informazioni vengono visualizzate in una tipica struttura a torta. Ogni fetta di torta rappresenta il valore proporzionale dei dati. Il modo più semplice per creare un grafico a torta in JavaFX è creare un'istanza di PieChart classe e impostare i dati come segue:

PieChart pie=new PieChart();

Possiamo impostare i dati per un grafico a torta con l'aiuto di setData() metodo, che accetta un parametro di tipo ObservableList . L'istanza di PieChart.Data è in realtà una classe nidificata di PieChart ed esegue il rendering di una fetta dei dati della torta. Il costruttore accetta due parametri, come segue:

PieChart.Data(String title, Double value)

Ecco un rapido esempio per creare un grafico a torta.

package org.mano.example;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {

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

   @Override
   public void start(Stage stage) throws Exception {
      stage.setTitle("JavaFX Chart Demo");
      StackPane pane = new StackPane();
      pane.getChildren().add(createPieChart());
      stage.setScene(new Scene(pane, 400, 200));
      stage.show();
   }

   public PieChart createPieChart() {
      PieChart pie = new PieChart();
      ObservableList<PieChart.Data> data =
         FXCollections.observableArrayList();
      data.addAll(new PieChart.Data("Asia", 30.0),
         new PieChart.Data("Africa", 20.3),
         new PieChart.Data("North America", 16.3),
         new PieChart.Data("South America", 12.0),
         new PieChart.Data("Antartica", 8.9),
         new PieChart.Data("Europe", 6.7),
         new PieChart.Data("Australia", 5.2));

      pie.setData(data);
      pie.setTitle("The Continents: Land Area");
      return pie;
   }
}

Uscita


Figura 2: Il grafico a torta finito dal codice precedente

Il grafico XY

La Carta XY è una classe astratta che costituisce la base di tutti i grafici a due assi in JavaFX. I grafici a due assi sono quelli in cui tipicamente un singolo elemento rappresenta una coppia ed è tracciato in un'area di coordinate cartesiane contrassegnata dall'asse x come colonne e dall'asse y come righe. I derivati ​​concreti di questa classe astratta sono:BarChart , Grafico ad area , Grafico a bolle , Grafico a linee , Grafico a dispersione , StackedAreaChart e StackedBarChart . A differenza di XYChart , il Grafico a torta non stabilisce i dati in un formato degli assi x e y. Questa è la differenza principale tra un Grafico a torta e un XYChart . I dati in un XYChart è ordinato in serie. Tuttavia, il modo in cui questa serie di dati verrà visualizzata dipende dall'implementazione o dal tipo di XYChart effettivamente istanziato.

Perché XYChart è rappresentato in un formato degli assi xey, il costruttore di XYChart è il seguente.

XYChart(Axis<X> xAxis, Axis<Y> yAxis)

Asse è una classe astratta che estende Region . Esistono due sottoclassi concrete di questa classe, chiamate CategoryAxis e ValueAxis . L'Asse Categoria viene istanziata per rendere le etichette del grafico in formato stringa mentre ValueAxis esegue il rendering delle voci di dati in Numero formato. Il Numero è anche una classe astratta che costituisce la classe base per tutti i tipi numerici in Java come le classi wrapper:Double , Intero , Mobile , Lungo , Breve , e così via.

Esempio di grafico a barre

Un grafico a barre viene in genere utilizzato per mostrare la differenza relativa tra le diverse serie di una determinata categoria. L'esempio seguente illustra come crearne uno in Java.

package org.mano.example;

import java.util.*;

import javafx.application.Application;
import javafx.collections.*;
import javafx.scene.Scene;
import javafx.scene.chart.*;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {

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

   @Override
   public void start(Stage stage) throws Exception {
      stage.setTitle("JavaFX Chart Demo");
      StackPane pane = new StackPane();
      pane.getChildren().add(createBarChart());
      stage.setScene(new Scene(pane, 400, 200));
      stage.show();
   }

   public ObservableList<XYChart.Series<String, Double>>
         getDummyChartData() {
      ObservableList<XYChart.Series<String, Double>> data =
         FXCollections.observableArrayList();
      Series<String, Double> as = new Series<>();
      Series<String, Double> bs = new Series<>();
      Series<String, Double> cs = new Series<>();
      Series<String, Double> ds = new Series<>();
      Series<String, Double> es = new Series<>();
      Series<String, Double> fs = new Series<>();
      as.setName("A-Series");
      bs.setName("B-Series");
      cs.setName("C-Series");
      ds.setName("D-Series");
      es.setName("E-Series");
      fs.setName("F-Series");

      Random r = new Random();

      for (int i = 1900; i < 2017; i += 10) {

         as.getData().add(new XYChart.Data<>
         (Integer.toString(i), r.nextDouble()));
         bs.getData().add(new XYChart.Data<>
         (Integer.toString(i), r.nextDouble()));
         cs.getData().add(new XYChart.Data<>
         (Integer.toString(i), r.nextDouble()));
         ds.getData().add(new XYChart.Data<>
         (Integer.toString(i), r.nextDouble()));
         es.getData().add(new XYChart.Data<>
         (Integer.toString(i), r.nextDouble()));
         fs.getData().add(new XYChart.Data<>
         (Integer.toString(i), r.nextDouble()));
      }
      data.addAll(as, bs, cs, ds, es, fs);
      return data;
   }

   public XYChart<CategoryAxis, NumberAxis>
         createBarChart() {
      CategoryAxis xAxis = new CategoryAxis();
      NumberAxis yAxis = new NumberAxis();
      BarChart bc = new BarChart<>(xAxis, yAxis);
      bc.setData(getDummyChartData());
      bc.setTitle("Bar Chart on Random Number");
      return bc;
   }
}

Uscita


Figura 3: Il grafico a barre finito dal codice precedente

Esempio di grafico a dispersione

Gli elementi di dati in un grafico a dispersione sono rappresentati come simboli all'interno dell'area dell'asse XY. Il codice del grafico a barre precedente può essere facilmente convertito per creare un grafico a dispersione apportando le seguenti modifiche.

package org.mano.example;

import java.util.*;

import javafx.application.Application;
import javafx.collections.*;
import javafx.scene.Scene;
import javafx.scene.chart.*;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;

public class Main extends Application {

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

   @Override
   public void start(Stage stage) throws Exception {
      stage.setTitle("JavaFX Chart Demo");
      StackPane pane = new StackPane();
      pane.getChildren().add(createScatterChart());
      stage.setScene(new Scene(pane, 400, 200));
      stage.show();
   }

   public ObservableList<XYChart.Series<String, Double>>
         getDummyChartData() {
      // ... Same as above
   }

   public XYChart<CategoryAxis, NumberAxis>
         createScatterChart() {

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

      ScatterChart sc = new ScatterChart<>(xAxis, yAxis);
      sc.setData(getDummyChartData());
      sc.setTitle("Scatter chart on random data");

      return sc;
   }
}

Uscita


Figura 4: Il grafico a dispersione finito dal codice precedente

Esempio di grafico a linee

Come possiamo vedere, gli elementi di dati nel grafico a dispersione sono rappresentati con l'aiuto di punti o simboli. A volte, è conveniente unire i punti. Ciò migliora la visibilità del cambiamento nelle tendenze da un punto segnato all'altro. Il grafico a linee fa esattamente questo. Il prossimo esempio illustra l'idea.

package org.mano.example;

// ... Import statements same as above

public class Main extends Application {

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

   @Override
   public void start(Stage stage) throws Exception {
      stage.setTitle("JavaFX Chart Demo");
      StackPane pane = new StackPane();
      pane.getChildren().add(createLineChart());
      stage.setScene(new Scene(pane, 400, 200));
      stage.show();
   }

   public ObservableList<XYChart.Series<String, Double>>
         getDummyChartData() {

      // ... Same as above
   }

   public XYChart<CategoryAxis, NumberAxis> createLineChart() {
      CategoryAxis xAxis = new CategoryAxis();
      NumberAxis yAxis = new NumberAxis();
      LineChart lc = new LineChart<>(xAxis, yAxis);
      lc.setData(getDummyChartData());
      lc.setTitle("Line chart on random data");
      return lc;
   }
}

Uscita


Figura 5: Il grafico a linee finito dal codice precedente

Esempio StackedBarChart

Il grafico a barre impilate è un'altra versione di BarChart nel senso che qui, invece di rappresentare barre diverse una accanto all'altra, lo StackedBarChart impila le categorie una sopra l'altra.

package org.mano.example;

// ... Import statements same as above

public class Main extends Application {

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

   @Override
   public void start(Stage stage) throws Exception {
      stage.setTitle("JavaFX Chart Demo");
      StackPane pane = new StackPane();
      pane.getChildren().add(createStackedBarChart());
      stage.setScene(new Scene(pane, 400, 200));
      stage.show();
   }

   public ObservableList<XYChart.Series<String, Double>>
         getDummyChartData() {

      // ... Same as above
   }

   public XYChart<CategoryAxis, NumberAxis>
         createStackedBarChart() {
      CategoryAxis xAxis = new CategoryAxis();
      NumberAxis yAxis = new NumberAxis();
      StackedBarChart sbc = new StackedBarChart<>(xAxis, yAxis);
      sbc.setData(getDummyChartData());
      sbc.setTitle("Stacked bar chart on random data");
      return sbc;
   }
}

Uscita


Figura 6: Il grafico a barre in pila finito dal codice precedente

Esempio di grafico ad area

In un AreaChart , la regione sotto le linee che collegano i punti viene riempita per rappresentare una categoria.

package org.mano.example;

// ... Import statements same as above

public class Main extends Application {

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

   @Override
   public void start(Stage stage) throws Exception {
      stage.setTitle("JavaFX Chart Demo");
      StackPane pane = new StackPane();
      pane.getChildren().add(createAreaChart());
      stage.setScene(new Scene(pane, 400, 200));
      stage.show();
   }

   public ObservableList<XYChart.Series<String, Double>>
      getDummyChartData() {

      // ... Same as above
   }

   public XYChart<CategoryAxis, NumberAxis> createAreaChart() {
      CategoryAxis xAxis = new CategoryAxis();
      NumberAxis yAxis = new NumberAxis();
      AreaChart ac = new AreaChart<>(xAxis, yAxis);
      ac.setData(getDummyChartData());
      ac.setTitle("Area chart on random data");
      return ac;

   }
}

Uscita


Figura 7: Il grafico ad area finito dal codice precedente

Esempio grafico StackedArea

Il StackedAreaChart mostra la somma dei valori della stessa categoria e non mostra le singole aree come l'AreaChart fa. Questa è in sostanza un'altra versione di AreaChart .

package org.mano.example;

// ... Import statements same as above

public class Main extends Application {

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

   @Override
   public void start(Stage stage) throws Exception {
      stage.setTitle("JavaFX Chart Demo");
      StackPane pane = new StackPane();
      pane.getChildren().add(createStackedAreaChart());
      stage.setScene(new Scene(pane, 400, 200));
      stage.show();
   }

   public ObservableList<XYChart.Series<String, Double>>
         getDummyChartData() {

      // ... Same as above
   }

   public XYChart<CategoryAxis, NumberAxis> createStackedAreaChart() {
      CategoryAxis xAxis = new CategoryAxis();
      NumberAxis yAxis = new NumberAxis();
      StackedAreaChart sac = new StackedAreaChart<>(xAxis, yAxis);
      sac.setData(getDummyChartData());
      sac.setTitle("Stacked area chart on random data");
      return sac;
   }
}

Uscita


Figura 8: Il grafico ad area in pila finito dal codice precedente

Esempio di grafico a bolle

Il Grafico a bolle traccia le bolle per i punti dati nella serie. Questa variazione della XYChart utilizza le proprietà aggiuntive di XYChart.Data classe nel senso che è una speciale XYChart implementazione tra tutte le sottoclassi di XYChart . Qui, un elemento di dati è indicato da due o tre parametri come il valore x, il valore y e, facoltativamente, il valore che indica il raggio della bolla. Ecco un esempio per illustrare come crearne uno in Java.

package org.mano.example;

import java.util.*;

import javafx.application.Application;
import javafx.collections.*;
import javafx.scene.Scene;
import javafx.scene.chart.*;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;

public class Main extends Application {

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

   @Override
   public void start(Stage stage) throws Exception {
      stage.setTitle("JavaFX Chart Demo");
      StackPane pane = new StackPane();
      pane.getChildren().add(createBubbleChart());
      stage.setScene(new Scene(pane, 400, 200));
      stage.show();
   }

   public ObservableList<XYChart.Series<Integer, Double>>
   getDummyChartData2() {
      ObservableList<XYChart.Series<Integer, Double>> data =
         FXCollections.observableArrayList();

      Series<Integer, Double> as = new Series<>();
      Series<Integer, Double> bs = new Series<>();
      Series<Integer, Double> cs = new Series<>();
      Series<Integer, Double> ds = new Series<>();
      Series<Integer, Double> es = new Series<>();
      Series<Integer, Double> fs = new Series<>();
      as.setName("A-Series");
      bs.setName("B-Series");
      cs.setName("C-Series");
      ds.setName("D-Series");
      es.setName("E-Series");
      fs.setName("F-Series");

      Random r = new Random();

      for (int i = 1900; i < 2017; i += 10) {
         double d = r.nextDouble();

         as.getData().add(new XYChart.Data<>
         (i, r.nextInt(32)+r.nextDouble(), 2 * d));
         bs.getData().add(new XYChart.Data<>
         (i,r.nextInt(32)+r.nextDouble(), 4 * d));
         cs.getData().add(new XYChart.Data<>
         (i,r.nextInt(32)+r.nextDouble(), 3 * d));
         ds.getData().add(new XYChart.Data<>
         (i,r.nextInt(32)+r.nextDouble(), 5 * d));
         es.getData().add(new XYChart.Data<>
         (i,r.nextInt(32)+r.nextDouble(), 1.5 * d));
         fs.getData().add(new XYChart.Data<>
         (i,r.nextInt(32)+r.nextDouble(), 1.7 * d));

      }

      data.addAll(as, bs, cs, ds, es, fs);
      return data;
   }

   public BubbleChart<Number, Number> createBubbleChart() {
      NumberAxis xAxis = new NumberAxis();
      NumberAxis yAxis = new NumberAxis();
      yAxis.setAutoRanging(false);
      yAxis.setLowerBound(0);
      yAxis.setUpperBound(30);

      xAxis.setAutoRanging(false);
      xAxis.setLowerBound(1900);
      xAxis.setUpperBound(2017);
      xAxis.setTickUnit(10);
      xAxis.setTickLabelFormatter(new StringConverter<Number>() {

         @Override
         public String toString(Number object) {
            return String.valueOf(object.intValue() / 10);
         }

         @Override
         public Number fromString(String string) {
            return Integer.valueOf(string) * 10;
         }
      });

      BubbleChart blc = new BubbleChart<>(xAxis, yAxis);
      blc.setData(getDummyChartData2());
      blc.setTitle("Bubble chart on random data");
      return blc;
   }
}

Uscita


Figura 9: Il grafico a bolle finito dal codice precedente

Conclusione

È possibile utilizzare Cascading Style Sheets (CSS) per modificare l'aspetto predefinito dei grafici JavaFX, come alterare la combinazione di colori, modificare le legende e gli assi o i simboli dei grafici e così via. JavaFX fornisce molti tag CSS specifici per i grafici per raggiungere questo obiettivo. La parte più importante dell'API dei grafici JavaFX è che fornisce diverse varianti di tipi di grafici pronti per l'uso. Spetta agli sviluppatori scegliere il giusto tipo di grafico che meglio si adatta al loro schema di reporting dei dati.