Gabriele Ferri

info@gabrieleferri.it :: mobile: +39 346 8642134

home » laboratorio » Creare un grafico a barre orizzontali con pChart

:: Creare un grafico a barre orizzontali con pChart

La libreria pChart mette a disposizione una serie di metodi per creare un istogramma e gestire le funzionalità essenziali come ad esempio la media, le serie multiple, il valore massimo e minimo in ordinata e così via.
Purtroppo in questa libreria, non è stata prevista la possibilità di creare un istogramma orizzontale.
Ho deciso di scrivere questo articolo da quando sono stato informato che la mia estensione è stata inserita, integrata e corretta in Goolge Code e segnalata in alcune piattaforme di software collaborativo come Chamilo.
L'estensione che presento, si integra alla libreria esistente e permette di creare un grafico a barre orizzonatli utilizzando la stessa logica di pChart.

L'istogramma verticale

Realizzare un grafico a barre verticali con pChart è molto semplice; partendo dalla documentazione e dagli esempi di base, utilizzando i metodi già messi a disposizione è possibile fare grafici di questo tipo: grafico a barre verticali (istogramma) con una label col testo molto lungo

La necessità di realizzare un istogramma orizzontale può sorgere per diversi motivi: ci potrebbero essere molte barre da visualizzare e alcuni layout non permettono di generare grafici lunghi (come questo sito) con la conseguenza che il grafico potrebbe diventare illeggibile. Come in questo caso, anche le label con i testi molto lunghi potrebbero essere un problema.

La realizzazione di un istogramma orizzontale potrebbe risolvere buona parte dei nostri problemi, ma la libreria pChart non è in grado di disegnarla.

Estensione della classe pChart

Da una prima analisi, si nota che non è opportuno effettuare l'override dei metodi principali che realizzano l'istogramma veritcale per cui ho proceduto a creare nuovi metodi che tengano conto delle necessità che possono sorgere nella realizzazione di un grafico a barre orizzontali.
I metodi creati sono:

Il metodo che invece è stato ridefinito è drawTreshold solitamente utilizzato per segnare la media dei valori rappresentati dalle seire di barre.
A questo metodo sono stati aggiunti tre parametri ($Angle, $LabelMarginX, $LabelMarginY) che servono per disporre meglio il relativo valore.
Grazie anche al contributo di Julio Montoya che ha apportato alcune modifiche al mio codice originale, il metodo risulta così definito: function drawTreshold($Value,$R,$G,$B,$ShowLabel=FALSE,$ShowOnBottom=FALSE,$TickWidth=4,$FreeText=NULL,$Angle=0,$LabelMarginX=0,$LabelMarginY=0) { if ( $R < 0 ) { $R = 0; } if ( $R > 255 ) { $R = 255; } if ( $G < 0 ) { $G = 0; } if ( $G > 255 ) { $G = 255; } if ( $B < 0 ) { $B = 0; } if ( $B > 255 ) { $B = 255; } $C_TextColor =$this->AllocateColor($this->Picture,$R,$G,$B); $X = $this->GArea_X1 + ($Value - $this->VMin) * $this->DivisionRatio; if ( $X <= $this->GArea_X1 || $X >= $this->GArea_X2 ) return(-1); if ( $TickWidth == 0 ) $this->drawLine($X,$this->GArea_Y1,$X,$this->GArea_Y2,$R,$G,$B); else $this->drawDottedLine($X,$this->GArea_Y1,$X,$this->GArea_Y2,$TickWidth,$R,$G,$B); if ( $ShowLabel ) { if ( $FreeText == NULL ) { $Label = $Value; } else { $Label = $FreeText; } $Position = imageftbbox($this->FontSize,$Angle,$this->FontName,$Label); $TextWidth = abs($Position[2])-abs($Position[0]); $TextLeft = abs($Position[3])-abs($Position[1]); if ( $ShowOnBottom ) imagettftext($this->Picture,$this->FontSize,$Angle,$X+$LabelMarginX,$this->GArea_Y2+$LabelMarginY,$C_TextColor,$this->FontName,$Label); else imagettftext($this->Picture,$this->FontSize,$Angle,$X+$LabelMarginX,$this->GArea_Y1-$TextWidth+$LabelMarginY,$C_TextColor,$this->FontName,$Label); } }

Come si utilizza la nuova estensione

La classe estesa HorizontalBar è pronta per essere utilizzata tenendo presente che ora sarà necessario includere nello script php la nuova classe e si dovrà istanziare la classe estesa.
Bisognerà inoltre ricordarsi di utilizzare i nuovi metodi specifici descritti sopra, per disegnare l'istogramma orizzontale: <?php define("LIBS_PATH",'your pChart direcotry'); // Standard inclusions include_once(LIBS_PATH."/pChart/pData.class"); include_once(LIBS_PATH."/pChart/pChart.class"); include_once(LIBS_PATH."/pChart/HorizontalBar.class"); // Dataset definition $DataSet = new pData; $DataSet->AddPoint(array("Label 1","Label 2 con testo lungo","Label 3","Label 4","Label 5","Label 6","Label 7"),"Label"); $DataSet->SetAbsciseLabelSerie("Label"); $serie1 = array(1,4,3,2,1,3,2); $serie2 = array(3,3,2,1,3.73,2,1); $serie3 = array(4,1,2,1,4.5,2,3); $serie4 = array(3,1.5,4,2,4.7,3,4); $average = round(array_sum($serie1)/count($serie1), 2); $DataSet->AddPoint($serie1,"Serie1"); $DataSet->AddSerie("Serie1"); $DataSet->SetSerieName("1a serie","Serie1"); $DataSet->AddPoint($serie2,"Serie2"); $DataSet->AddSerie("Serie2"); $DataSet->SetSerieName("2a serie","Serie2"); $DataSet->AddPoint($serie3,"Serie3"); $DataSet->AddSerie("Serie3"); $DataSet->SetSerieName("3a serie","Serie3"); $DataSet->AddPoint($serie4,"Serie4"); $DataSet->AddSerie("Serie4"); $DataSet->SetSerieName("4a serie","Serie4"); $average = round(($average + round(array_sum($serie2)/count($serie2), 2) + round(array_sum($serie3)/count($serie3), 2) + round(array_sum($serie4)/count($serie4), 2))/4, 2); // Initialise the graph $Test = new HorizontalBar(500,700); $Test->setFontProperties(LIBS_PATH."/Fonts/tahoma.ttf",8); $Test->setGraphArea(120,60,450,650); $Test->setFixedScale(0,5,5,0,0,0); $Test->drawFilledRoundedRectangle(7,7,493,693,5,240,240,240); $Test->drawRoundedRectangle(5,5,495,695,5,230,230,230); $Test->drawGraphArea(255,255,255,TRUE); $Test->drawHorScale($DataSet->GetData(),$DataSet->GetDataDescription(),SCALE_NORMAL,150,150,150,TRUE,0,2,TRUE); $Test->drawHorGrid(10,TRUE,230,230,230,50); // Draw the 0 line $Test->setFontProperties(LIBS_PATH."/Fonts/tahoma.ttf",6); $Test->drawTreshold($average,143,55,72,TRUE,FALSE,2,null,90,3,-3); // Draw the bar graph $Test->drawHorBarGraph($DataSet->GetData(),$DataSet->GetDataDescription(),FALSE); // Finish the graph $Test->setFontProperties(LIBS_PATH."/Fonts/tahoma.ttf",8); $Test->drawLegend(15,15,$DataSet->GetDataDescription(),255,255,255); $Test->setFontProperties(LIBS_PATH."/Fonts/tahoma.ttf",10); $Test->drawTitle(170,27,"Confronto evoluzione",50,50,50,-1); $Test->Stroke(); ?>

Il risultato è il seguente: grafico a barre orizzontali (istogramma) con una label col testo molto lungo