Diagramma a torta

Siano dati un insieme di percentuali. Si vuole realizzare il loro diagramma a torta, che è costituito da un cerchio diviso in tanti settori quante sono le percentuali. Ogni arco ha un angolo che è proporzionale alla corrispondente percentuale. Per rendere più chiaro il diagramma, i vari settori devono essere colorati con colori diversi.

Si suppone che le percentuali siano memorizzate in un vettore di interi, per esempio:

    int percentuali[]={10, 15, 30, 25, 20};

L'istruzione fondamentale è chiaramente quella di disegno di un angolo riempito fillArc, insieme a quella di cambiamento del colore. Concentriamoci per il momento sul disegno dei settori, rimandando il cambiamento di colore a un secondo momento.

Come si è detto, ogni settore deve avere un angolo proporzionale a una percentuale. Per esempio, il primo settore deve avere un angolo proporzionale a percentuali[0]. Quanto deve essere grande esattamente questo angolo? In tutti i casi in cui occorre stabilire una relazione lineare tre due grandezze, è sufficiente considerare i due casi estremi:

Ora, diciamo che a è l'angolo e p è la percentuale. Sappiamo che a deve essere proporzionale a p, quindi una relazione lineare intercorre fra loro:
a = x * p + y

Per trovare i valori delle costanti x e y, usiamo i due casi estremi, che diventano:

0 = x * 0 + y
360 = x * 100 + y

Dalla prima equazione si ricava y=0, per cui la seconda equazione diventa 360 = x * 100, ossia x=360/100. Quindi, data una percentuale p, l'angolo a si ricava dalla equazione:

a = (360/100)*p

Parte del problema è quindi risolto: ora sappiamo quanto è grande ogni angolo che va disegnato. Manca ora da specificare quale è il suo punto di partenza. Per il primo angolo questo è ovvio: il punto di partenza si trova a 0 gradi. Il punto di partenza del secondo arco si trova esattamente dove finisce il primo, il terzo dove finisce il secondo, ecc. La regola è quindi semplice: il punto d'inizio dell'i-esimo arco è il punto finale dell'arco disegnato precedentemente. Basta quindi memorizzare in una variabile il punto in cui l'arco corrente finisce, e questo sarà il punto di inizio dell'arco successivo. Il punto di fine di ogni arco si trova sommando l'ampiezza dell'arco al punto in cui l'arco inizia. Usiamo la variabile fine per indicare l'angolo a cui ogni arco finisce (e quindi il successivo inizia). Il disegno degli archi si può quindi effettuare con il codice seguente:

    int i;
    int fine;

    fine=0;

    for(i=0; i<=percentuali.length-1; i++) {
      g.fillArc(100,100, 300, 300, fine, percentuali[i]*360/100);

      fine=fine+percentuali[i]*360/100;
    }
A parole: si usa una variabile i per scandire il vettore delle percentuali. La variabile fine indica l'angolo a cui inizia il settore successivo, e quindi parte a 0. Ad ogni passo, si disegna un nuovo settore, e si aggiorna il punto in cui il nuovo settore deve cominciare.

Veniamo ora alla questione dei colori. Supponiamo che le percentuali da visualizzare siano solo cinque, per cui bastano cinque colori diversi. Supponiamo quindi di voler usare, per le varie percentuali, i seguenti colori:

Color.green, Color.red, Color.blue, Color.yellow, Color.orange, Color.gray

L'ideale sarebbe poter mettere una istruzione setColor all'interno del ciclo, in modo tale che quando i vale 0 si esegue g.setColor(Color.green), quando i vale 1 si esegue g.setColor(Color.red), quando i vale 2 si esegue g.setColor(Color.yellow), ecc.

In effetti, conosciamo un modo per associare un valore a dei numeri interi: i vettori. In questo caso, per i=0 ci serve Color.green, per i=0 ci serve Color.red, ecc. Quindi, usiamo un vettore in cui memorizziamo Color.green nella posizione 0, Color.red nella posizione 1, ecc. Ad ogni passo, basta cambiare il valore corrente usando il contenuto di una delle celle che costituiscono il vettore colori.

Il programma Torta.java è stato realizzato a partire dalle considerazioni riportate sopra.

import java.awt.*;

public class Torta extends java.applet.Applet {
  public void paint (Graphics g) {
    int percentuali[]={10, 15, 30, 25, 20};
    Color colori[]={Color.green, Color.red, Color.blue, Color.yellow,
                    Color.orange, Color.gray };
    int i;
    int fine;

    fine=0;

    for(i=0; i<=percentuali.length-1; i++) {
      g.setColor(colori[i]);

      g.fillArc(100,100, 300, 300, fine, percentuali[i]*360/100);

      fine=fine+percentuali[i]*360/100;
    }
  }
}

Il grafico delle percentuali viene visualizzato come segue.