sql >> Base de Datos >  >> RDS >> Database

Trabajar con las API de gráfico de JavaFX

Uno de los aspectos más importantes de los informes es hacer que el contenido sea lo más visible posible para que la esencia de la información contenida en el informe llegue a su audiencia de forma rápida y sin esfuerzo. Los gráficos juegan un papel crucial en este sentido. Presentar datos sin procesar e intentar imaginar el escenario asociado con los datos no es muy fácil, pero los gráficos representan una esencia pictórica de los datos y ayudan al espectador a captar la idea detrás de los datos sin procesar muy rápidamente. JavaFX tiene soporte incorporado para presentar datos crudos en forma dinámica de forma pintoresca. La API tiene dos facetas:una puede extender las clases de API y crear un gráfico personalizado desde cero, o usar las clases específicas de gráficos disponibles para crear un gráfico con un código mínimo. Este artículo profundiza en los aspectos clave de las API de gráficos de JavaFX y muestra cómo implementarlas. Se proporcionan ejemplos rápidos para ayudarlo.

Gráficos de JavaFX

Los gráficos JavaFX no solo son fáciles de integrar con otras partes de la aplicación, sino que también están imbuidos de la política extensible de la tecnología orientada a objetos que se puede personalizar según las necesidades del desarrollador. Esto no es algo nuevo, porque los diseños orientados a objetos siempre están destinados a ser extensibles, pero la parte interesante de la API de gráficos de JavaFX es que hay muchas clases de gráficos listas para usar que se pueden instanciar con un pequeño o ningún cambio en su propiedades para obtener gráficos de aspecto profesional. Estas clases de gráficos son las más comunes, personalizables y se adaptan a casi todas las necesidades del desarrollador. En la mayoría de los casos, apenas hay necesidad de crear un gráfico personalizado desde cero.

JavaFX proporciona ocho tipos de gráficos de este tipo en la biblioteca API con su funcionalidad integrada. Aunque hay muchas clases e interfaces de soporte en la biblioteca API de gráfico de JavaFX, la implementación concreta ocho está organizada jerárquicamente de la siguiente manera.


Figura 1: El gráfico de jerarquía de la biblioteca de la API del gráfico JavaFX

Por lo tanto, los ocho tipos comunes de gráficos son:gráfico circular , gráfico de barras , gráfico de áreas , gráfico de líneas , gráfico de dispersión , gráfico de burbujas , gráfico de áreas apiladas y gráfico de barras apiladas .

El gráfico circular

El gráfico circular es un formato de gráfico común en el que la información se representa en una estructura típica de sectores circulares. Cada sector circular representa el valor proporcional de los datos. La forma más fácil de crear un gráfico circular en JavaFX es instanciar el PieChart clase y establezca los datos de la siguiente manera:

PieChart pie=new PieChart();

Podemos configurar los datos para un gráfico circular con la ayuda de setData() método, que toma un parámetro de tipo ObservableList . La instancia de PieChart.Data es en realidad una clase anidada de PieChart y representa una porción de los datos circulares. El constructor toma dos parámetros, como sigue:

PieChart.Data(String title, Double value)

Este es un ejemplo rápido para crear un gráfico circular.

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

Salida


Figura 2: El gráfico circular terminado del código anterior

El gráfico XY

El gráfico XY es una clase abstracta que forma la base de todos los gráficos de dos ejes en JavaFX. Los gráficos de dos ejes son aquellos en los que normalmente un solo elemento representa un par y se traza en un área de coordenadas cartesianas marcada por el eje x como columnas y el eje y como filas. Los derivados concretos de esta clase abstracta son:BarChart , Gráfico de áreas , Gráfico de burbujas , Gráfico de Líneas , Gráfico de dispersión , Gráfico de áreas apiladas y Gráfico de barras apiladas . A diferencia de XYChart , el Gráfico circular no establece datos en un formato de eje x e y. Esta es la principal diferencia entre un PieChart y un gráfico XY . Los datos en un XYChart se ordena en serie. Sin embargo, la forma en que se representará esta serie de datos depende de la implementación o el tipo de XYChart. realmente instanciado.

Porque gráfico XY se representa en un formato de eje x e y, el constructor de XYChart es el siguiente.

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

Eje es una clase abstracta que extiende Region . Hay dos subclases concretas de esta clase, llamadas CategoryAxis y Eje de valor . El Eje de categorías se crea una instancia para representar las etiquetas del gráfico en formato de cadena, mientras que el ValueAxis representa las entradas de datos en Número formato. El Número también es una clase abstracta que forma la clase base para todos los tipos numéricos en Java, como las clases contenedoras:Double , Entero , Flotar , Largo , Corto , y así sucesivamente.

Ejemplo de gráfico de barras

Un gráfico de barras se usa típicamente para mostrar la diferencia relativa entre las diferentes series de una categoría determinada. El siguiente ejemplo ilustra cómo crear uno en 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;
   }
}

Salida


Figura 3: El gráfico de barras terminado del código anterior

Ejemplo de gráfico de dispersión

Los elementos de datos en un gráfico de dispersión se representan como símbolos dentro del área del eje XY. El código del gráfico de barras anterior se puede convertir fácilmente para crear un gráfico de dispersión realizando los siguientes cambios.

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

Salida


Figura 4: El gráfico de dispersión terminado del código anterior

Ejemplo de gráfico de líneas

Como podemos ver, los elementos de datos en el gráfico de dispersión se representan con la ayuda de puntos o símbolos. A veces, es conveniente conectar los puntos. Esto mejora la visibilidad del cambio en las tendencias de un punto marcado a otro. El gráfico de líneas hace exactamente esto. El siguiente ejemplo ilustra la 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;
   }
}

Salida


Figura 5: El gráfico de líneas terminado del código anterior

Ejemplo de gráfico de barras apiladas

El Gráfico de barras apiladas es otra versión del BarChart en el sentido de que aquí, en lugar de representar diferentes barras una al lado de la otra, el StackedBarChart apila las categorías una encima de otra.

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

Salida


Figura 6: El gráfico de barras apiladas terminado del código anterior

Ejemplo de gráfico de área

En un AreaChart , la región debajo de las líneas que conectan los puntos se rellena para representar una categoría.

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;

   }
}

Salida


Figura 7: El gráfico de área terminado del código anterior

Ejemplo de gráfico de áreas apiladas

El gráfico de áreas apiladas muestra la suma de los valores de la misma categoría y no muestra áreas individuales como el AreaChart hace. Esta es, en esencia, otra versión del 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;
   }
}

Salida


Figura 8: El gráfico de áreas apiladas terminado del código anterior

Ejemplo de gráfico de burbujas

El gráfico de burbujas traza burbujas para puntos de datos en la serie. Esta variación del XYChart utiliza las propiedades adicionales de XYChart.Data clase en el sentido de que es un XYChart especial implementación entre todas las subclases del XYChart . Aquí, un elemento de datos se indica mediante dos o tres parámetros, como el valor x, el valor y y, opcionalmente, el valor que representa el radio de la burbuja. Aquí hay un ejemplo para ilustrar cómo crear uno en 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;
   }
}

Salida


Figura 9: El gráfico de burbujas terminado del código anterior

Conclusión

Se pueden usar hojas de estilo en cascada (CSS) para modificar la apariencia predeterminada de los gráficos JavaFX, como alterar el esquema de color, modificar sus leyendas y ejes o símbolos de gráficos, etc. JavaFX proporciona muchas etiquetas CSS específicas de gráficos para lograr esto. La parte más importante de la API de gráficos JavaFX es que proporciona diferentes variaciones de tipos de gráficos listos para usar. Depende de los desarrolladores elegir el tipo correcto de gráfico que mejor se adapte a su esquema de informes de datos.