[PHP] Libchart – Creare grafici con PHP

LibchartE dopo la libreria per la creazione facile di file in PDF via PHP, oggi vediamo come creare grafici con PHP ottenendoli come output immagine!

E’ proprio quello che fa Libchart. Ottimo prodotto open source, facile da usare e molto versatile.
Premetto che per un corretto utilizzo delle funzioni comprese in Libchart è necessario aver installato e configurato a dovere la libreria GD.

Cosa è possibile fare?
Di seguito una lista delle funzioni principali (per nulla esaustiva):

  • Grafici a linea continua;
  • Grafici ad Istogramma verticale e orizzontale;
  • Grafici a torta (!!!);
  • Inserimento di un titolo in ogni grafico;
  • Inserimento coordinate X – Y in formato testo.

Come la utilizzo?
La semplicità è quasi disarmante. Basta includere il core file della libreria nel file che creerà l’output e mandare in loading la classe di riferimento del tipo di grafico che volete produrre.

include ‘libchart/libchart.php’;
$chart = new VerticalChart;    //Istogramma verticale
$chart = new LineChart;        //Grafico a linea
$chart = new PieChart;         //Grafico a torta
$chart = new HorizontalChart;  //Istogramma orizzontale

Già da qui è possibile specificare le dimensioni che deve avere l’immagine risultante. Se volete ottenere un grafico a torta di dimensioni 300X300 pixel scriverete.

include ‘libchart/libchart.php’;
$chart = new PieChart(300,300);

Come aggiungo un punto nel grafico?
Si utilizza addpoint e la classe Point. E’ possibile inserire non solo il valore del punto di riferimento, ma anche il riferimento testuale. Ipotizzando di studiare il fatturato dei primi 4 mesi dell’anno, andrete a scrivere qualcosa del genere.

    $chart->addPoint(new Point("Gennaio 2007", 1000));
    $chart->addPoint(new Point("Febbraio 2007", 1780));
    $chart->addPoint(new Point("Marzo 2007", 3498));
    $chart->addPoint(new Point("Aprile 2007", 30));

Se voglio dare un titolo al grafico?
Niente di più semplice ๐Ÿ™‚ . Basterà un:

    $chart->setTitle("Fatturato primo quadrimestre 2007");

Come creo l’immagine vera e propria?
Si utilizzerà la funzione render(). Questa prevede una doppia opzione di output:

1 – File PHP come output diretto immagine.
Ovvero nel caso in cui vogliamo che l’output corrisponda al file php. In questo caso useremo il render in default con:

    $chart->render();

Badate bene però che in questo caso è necessario aver inviato un header coerente con l’output desiderato. Nello specifico:

    header(‘Content-Type: image/png’);

2 – Salvataggio dell’output in file separato dallo script.
Con questa seconda opzione possiamo decidere di salvare il file di output in una directory a nostra scelta. L’uso di render() sarà il seguente:

    $chart->render("grafici/grafico1.png");

Ovviamente la directory di destinazione deve avere i permessi di scrittura debitamente settati.

I due casi in concreto.
Vediamo ora di riepilogare il tutto scrivendo per intero il codice relativo ai due casi proposti.

1 – Generazione diretta e volatile

    header(‘Content-Type: image/png’);
    include "libchart/libchart.php";

    $chart = new HorizontalChart(300, 300);
    $chart->addPoint(new Point("Gennaio 2007", 1000));
    $chart->addPoint(new Point("Febbraio 2007", 1780));
    $chart->addPoint(new Point("Marzo 2007", 3498));
    $chart->addPoint(new Point("Aprile 2007", 3000));
    $chart->setTitle("Fatturato primo quadrimestre 2007");
    $chart->render();

Al loading del file via richiesta http visualizzeremo il grafico.

2 – Salvataggio del grafico in directory

    include "libchart/libchart.php";

    $chart = new HorizontalChart(300, 300);
    $chart->addPoint(new Point("Gennaio 2007", 1000));
    $chart->addPoint(new Point("Febbraio 2007", 1780));
    $chart->addPoint(new Point("Marzo 2007", 3498));
    $chart->addPoint(new Point("Aprile 2007", 3000));
    $chart->setTitle("Fatturato primo quadrimestre 2007");
    $chart->render("grafici/grafico1.png");

    echo ‘<img src="grafici/grafico1.png" alt="grafico" />’;

In questo caso l’ultima riga è necessaria per visualizzare il risultato finale, dato che impostando il render() sull’output esterno, l’output dello script php rimarrà di base http.

Esempi pratici

1 – Istogramma Orizzontale

    header(‘Content-Type: image/png’);
    include "libchart/libchart.php";

    $chart = new HorizontalChart(500, 250);
    $chart->addPoint(new Point("Gennaio 2007", 1000));
    $chart->addPoint(new Point("Febbraio 2007", 1780));
    $chart->addPoint(new Point("Marzo 2007", 3498));
    $chart->addPoint(new Point("Aprile 2007", 3000));
    $chart->setTitle("Fatturato primo quadrimestre 2007");
    $chart->render();

libciart

2 – Istogramma Verticale

    header(‘Content-Type: image/png’);
    include "libchart/libchart.php";

    $chart = new VerticalChart(500, 250);
    $chart->addPoint(new Point("Gennaio 2007", 1000));
    $chart->addPoint(new Point("Febbraio 2007", 1780));
    $chart->addPoint(new Point("Marzo 2007", 3498));
    $chart->addPoint(new Point("Aprile 2007", 3000));
    $chart->setTitle("Fatturato primo quadrimestre 2007");
    $chart->render();

vertical

3 – Linea

    header(‘Content-Type: image/png’);
    include "libchart/libchart.php";

    $chart = new LineChart(500, 250);
    $chart->addPoint(new Point("Gennaio 2007", 1000));
    $chart->addPoint(new Point("Febbraio 2007", 1780));
    $chart->addPoint(new Point("Marzo 2007", 3498));
    $chart->addPoint(new Point("Aprile 2007", 3000));
    $chart->setTitle("Fatturato primo quadrimestre 2007");
    $chart->render();

line

4 – Torta

    header(‘Content-Type: image/png’);
    include "libchart/libchart.php";

    $chart = new PieChart(500, 250);
    $chart->addPoint(new Point("Gennaio 2007", 1000));
    $chart->addPoint(new Point("Febbraio 2007", 1780));
    $chart->addPoint(new Point("Marzo 2007", 3498));
    $chart->addPoint(new Point("Aprile 2007", 3000));
    $chart->setTitle("Fatturato primo quadrimestre 2007");
    $chart->render();

torta

Gli esempi proposti sono di pura accademia. Sta a voi, con riferimento ai dati che volete elaborare, impostare uno script che aggiunga dinamicamente i punti del grafico.

Io l’ho trovato molto utile. Riesco facilmente a sapere in ogni momento:

  • Il fatturato mensile in termini di andamento (grafico linea);
  • Il fatturato per responsabile (torta);
  • Il fatturato per macrocategorie di clienti (torta);
  • Classifica prodotti venduti (istogramma verticale);
  • Classifica clienti più danarosi (istogramma orizzontale).

Buon divertimanto ๐Ÿ™‚

28 thoughts on “[PHP] Libchart – Creare grafici con PHP”

  1. senza offesa… ma dove si scarica questa cavolo di libreria che non trovo da nessuna parte??? : - (

  2. I dati dal database li puoi estrapolare con un driver adeguato.

    Gli esempi riportati sono solo dimostrativi. Normale che poi si dovrà fare in modo di evocare le funzioni passandogli i dati dei risultati di una query.

  3. pheeego accidenti… il problema è che quando mi sono ritrovato a genreare in maniera dinamica le immagini, il mio allegro firefox si è messo a dirmi che l'immagine non può essere visualizzata in quanto contiene degli errori……….

    Mica hai un esempio di creazione dinamica dei grafici funzionante???

    GRazie

  4. Uno dei migliori debug in questo caso è visualizzare il sorgente della pagina, anche se è un'immagine.

    Dovresti leggere warning ed errori php in chiaro.

  5. Ciao
    volevo portarvi all'attenzione un altra libreria in PHP per creare grafici che ho recensito nel mio blog molto comoda per creare grafici dinamici direttamente da dati provenienti anche da un database MySql, senza il logo dell'autore come in questa e con molte possibilità di personalizzazione.
    Comunque ottima guida Ciao

  6. Salve a tutti!

    Sto provando a generare un grafico con la suddetta libreria…

    Prendo i dati dei punti da db senza problemi….poi però quando genero il grafico ricevo un errore che recita:

    " l'immagine non può essere visualizzata in quanto contiene degli errori………."

    Avete per caso idea di cosa si tratti?

    Grazie mille e buone ferie!

  7. Risolto!

    Per chi avesse lo stesso errore….bisogna far generare il grafico a un file php tipo generaGrafico.php e poi usare il tag img in questo modo

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

    <html xmlns="http://www.w3.org/1999/xhtml"&gt;

    <head>

    <title>Libchart line demonstration</title>

    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-15" />

    </head>

    <body>

    <img alt="Line chart" src="generaGrafico.php" style="border: 1px solid gray;"/>

    </body>

    </html>

    Ciao ciao!

  8. Ciao a tutti, ho provato a utilizzare questo tutorial. Ho notato difficoltà con l'ultima versione di libchart e allora ho provato con una più vecchia che sembra andare, solo che non ho la possibilità di usare la Linechart. Credo che si tratti di compatibilità tra versioni php.

    Detto questo, ho implementato il tutto con php e chiedo a voi se la procedura che ho eseguito è corretta.

    Avevo la necessità di visualizzare il totale delle prenotazioni divise per mese e in funzione della data del primo contatto ricevuto il quale ha poi portato alla successiva prenotazione.

    ho scritto così

    ======================================

    include "libchart1/libchart.php";

    $chart = new VerticalChart();

    $mesi = 1;

    do {

    $query = "SELECT * FROM contatti WHERE data_ricezione_richiesta>='".mktime(2,0,0,$mesi,1,2009)."' AND data_ricezione_richiesta<='".mktime(23,59,0,$mesi+1,0,2009)."' AND stato='3'";

    $result = mysql_query($query) or die (mysql_error());

    $quota = $num_rows = mysql_num_rows($result);

    $chart->addPoint(new Point(date ("F", mktime(2,0,0,$mesi,1,2009)), $quota));

    $mesi++;

    } while ($mesi <= 12);

    $chart->setLowerBound(0); // Y-Axis starts from 0

    $chart->setTitle("Prenotazioni per Mese ANNO 2009");

    $chart->render("libchart1/demo1.png");

    echo "<img alt='Vertical bars chart' src='libchart1/demo1.png' style='border: 0px solid gray;' />";

    ======================================

    La visualizzazione a me sembra corretta

    Come vi sembra il codice? Grazie dei consigli.

  9. Ciao Daniele,

    Se il risultato ti soddisfa allora è ben scritto.

    Sai, difficile giudicare il codice altrui leggendolo a spezzoni e senza conoscere il vero intento.
    L'unica cosa che posso consigliarti è separare completamente la fase di coding puro con quella di rendering del HTML. Così in caso di cambiamenti vai a modificare solo file di sistema e puoi gestire il layout autotomamente, ma è solo un consiglio spassionato.

    Per la versione di libchart, mi sembra che le ultime siano scritte esplicitamente per PHP5.

  10. Ciao,

    chiedo scusa, ma da ignorante in materia PHP, nei miei primi approcci all'export grafico mi appare il seguente errore: "l'immagine non può essere visualizzata in quanto contiene degli errori", lo stesso esplicato da Valentina al post n.12.

    Dato che non ho capito come é stato risolto, qualcuno me lo puó spiegare? grazie tanto ๐Ÿ˜‰

  11. scusate, forse la versione che ho scaricato io non è la stessa di cui parlate o ho letto male il blog, ma nella mia versione il metodo

    addPoint()

    non appartiene a nessuna delle sottoclassi Chart (es. PieChart), bensì alla classe DataSet. tant'è che nella doc ufficiale addPoint viene chiamato da un oggetto DataSet, non da $chart.


    $chart = new PieChart(500, 250);
    $dataSet = new XYDataSet();
    $dataSet->addPoint(new Point("Jan 2005", 273));

    dopodichè si passa l'oggetto DataSet all ogg Chart

    $chart->setDataSet($dataSet);
    

    lo segnalo nel caso possa essere utile, se era spiegato nel post e l'ho perso io, allora mi scuso

  12. Ciao a tutti,

    non riesco a risolvere questo dilemma,

    se esguo la query

    $lugl = "SELECT SUM(riservato) AS sumtotale FROM conforder WHERE (mm='07' AND anno='$anno'";

    funziona tutto, ma aggiungendo un AND

    $lugl = "SELECT SUM(riservato) AS sumtotale FROM conforder WHERE (mm='07' AND anno='$anno' AND agente=$utente";

    mi da un errore

    <b>Warning</b>: Division by zero in <b>/web/htdocs/www.ibixordini.eu/home/analisi/classes/Axis.php</b> on line <b>56</b><br />

    QUALCUNO PUO' AIUTARMI

    VI RINGRAZIO

  13. Ciao,

    ho provato questa libreria e l'ho adattata per ricevere dati da query su MySql.

    In locale funziona, ma appena la eseguo su un server con il database online e non in locale mi appare il seguente errore:

    Warning: imagepng() [function.imagepng]: Unable to open 'http://sito/grafico.png&#039; for writing: Invalid argument in D:sitolibchartclassesviewplotPlot.php on line 256

    Invece se da locale cerco di accedere al database online mi viene restituito un errore di connessione al database.

    Sapete come risolvere questo problema?

    Grazie, Ciao

  14. Ciao,

    Bellissima libreria che fa proprio al caso mio.

    Io uso Easy-PHP, ho copiato la cartellina libchart nella cartellina principale ed ho provato a fare un copia e incolla di una demo che si trova dal file .rar ma mi da questi errori.

    Warning: main(../libchart/classes/libchart.php): failed to open stream: No such file or directory in c:programmieasyphp1-8wwwgrafici.php on line 25

    Warning: main(): Failed opening '../libchart/classes/libchart.php' for inclusion (include_path='.;C:/Programmi/EasyPHP1-8phppear') in c:programmieasyphp1-8wwwgrafici.php on line 25

    Fatal error: Cannot instantiate non-existent class: verticalbarchart in c:programmieasyphp1-8wwwgrafici.php on line 27

    Le linee interessate sono:

    Linea 25:

    include "../libchart/classes/libchart.php";

    Linea 27:

    $chart = new VerticalBarChart();

    Voi sapreste aiutarmi???

    aspetto vostre risposte grazie mille

  15. ma per sovrapporre due grafici come si fa ? Cioè ho un primo dato contente 1,2,3 e un secondo 3,4,5 per far apparire questi valori su unoi stesso grafico, magari differenziando poi per colori come si fa ?

  16. prova questo:

    $serie1 = new XYDataSet();
    $serie1->addPoint(new Point("06-01", 273));
    $serie1->addPoint(new Point("06-02", 421));
    $serie1->addPoint(new Point("06-03", 642));
    $serie1->addPoint(new Point("06-04", 799));
    $serie1->addPoint(new Point("06-05", 1009));
    $serie1->addPoint(new Point("06-06", 1106));

    $serie2 = new XYDataSet();
    $serie2->addPoint(new Point("06-01", 280));
    $serie2->addPoint(new Point("06-02", 300));
    $serie2->addPoint(new Point("06-03", 212));
    $serie2->addPoint(new Point("06-04", 542));
    $serie2->addPoint(new Point("06-05", 600));
    $serie2->addPoint(new Point("06-06", 850));

    $dataSet = new XYSeriesDataSet();
    $dataSet->addSerie("Product 1", $serie1);
    $dataSet->addSerie("Product 2", $serie2);
    $chart->setDataSet($dataSet);

    oppure puoi guardare qui:

    http://naku.dohcrew.com/libchart/pages/samplecode/

  17. Ciao sono riuscito a implementare la classe ed a stampare il grafico, solo che non adatta il grafico alla dimensione massima. Cosa può essere successo?grazie

  18. Salve , vorrei stampare + grafici con dati presi da un'array nella stessa pagina, ma mi restituisce solo l'immagine con l'ultimo dato che riceve , dove sbaglio, se faccio il print funziona tutto , ma in formato testo

    Mirko

Comments are closed.