Creare un grafico con il componente gb.chart

Da Gambas-it.org - Wikipedia.

Introduzione

gb.chart di Fabien Bodard è un componente instabile un tantinello buggato, praticamente abbandonato perché l’autore si è ripromesso di rifarlo da capo. Nell’attesa del nuovo vediamo come possiamo usare al meglio quello che abbiamo e che comunque soddisfa molto il sottoscritto. Di seguito creeremo un grafico sia a colonne che a linee (di confronto mese per mese) sul fatturato degli ultimi dieci anni di un’ipotetica azienda, alla fine invieremo il o i grafici a gb.report per la stampa. Vi invito a visionare il test di esempio (FTest) scritto da Bodard stesso presente all’interno del componente che ne affronta tutti gli aspetti e non solo una parte come invece fa questo progetto.

 Nota: nella Software farm è presente il progetto qui descritto.


Progetto ChartReport

Avviamo Gambas e creiamo un progetto grafico nominandolo ChartReport (questo è il nome nella farm) o in qualunque altro modo vi aggrada. In Progetto > Proprietà > Componenti mettiamo la spunta a gb.chart e a gb.report2.

Il funzionamento dell'applicazione

Per meglio comprendere il codice vediamo una breve spiegazione sul funzionamento. All’apertura si crea il grafico a colonna se i colori vanno bene lo salviamo oppure prima di farlo cambiamo i colori di default con quelli personalizzati, possiamo volendo creare anche il grafico a linee e salvarlo. Alla fine agiamo sul pulsante anteprima di stampa che manda il o i grafici al report.

Il disegno della finestra FMain

Nella scheda Fmain.form della IDE, in Proprietà impostiamo: Arrangement = Vertical.

Dalla scheda Container posta al disotto delle proprietà clicchiamo su Panel per poi disegnarlo sulla finestra, lasciando un pò di spazio in basso per potervi disegnare una HBox con dei pulsanti, e lo impostiamo:

Arrangement = Horizontal
Expand = True

Come detto, prelevandolo dalla scheda Container, disegniamo sotto il Panel un HBox con altezza 32.

Sempre dalla scheda Container disegnamo all’interno di Hbox partendo da sinistra uno Spring, in alternativa potete disegnare un Panel con proprietà: Expand = True.

Prelevandoli dalla scheda Form, continuiamo disegnando quattro pulsanti con rispettivamente le seguenti proprietà:

Primo pulsante da sinistra:

Name = btnPrint
Autoresize = True
Picture = icon:/small/preview
Text = Print
ToolTip = Print preview

Secondo pulsante:

Name = btnSavePicture
Autoresize = True
Text = Save chart
ToolTip = Save current chart

Terzo pulsante:

Name = btnColors
Autoresize = True
ToolTip = ChangeColors

Quarto pulsante

Name = btnType
Autoresize = True
ToolTip = Change view

Per finire disegnamo in senso orizzontale un separatore fra il Panel e Hbox lasciando l’altezza predefinita (8).


Il codice della finestra Fmain

Nella scheda Fmain.class della IDE scriviamo questo codice:

 Property Read sHead As String
 Property Read sPicPaths As String[]
 Private $sPicPaths As New String[]
 Private $sHead As String
 
 Public Sub Form_Open()
 
   Dim aMonths As String[] = [("January"), ("February"), ("March"), ("April"), ("May"), ("June"), ("July"), ("August"), ("September"), ("October"), ("November"), ("December")]
   Dim aTurn2009 As Float[] = ReturnTurnover(54000.00, 55999.00)
   Dim aTurn2010 As Float[] = ReturnTurnover(55620.00, 57120.00)
   Dim aTurn2011 As Float[] = ReturnTurnover(56732.00, 58800.00)
   Dim aTurn2012 As Float[] = ReturnTurnover(58434.00, 60000.00)
   Dim aTurn2013 As Float[] = ReturnTurnover(59603.00, 61200.00)
   Dim aTurn2014 As Float[] = ReturnTurnover(60795.00, 62500.00)
   Dim aTurn2015 As Float[] = ReturnTurnover(62618.00, 63600.00)
   Dim aTurn2016 As Float[] = ReturnTurnover(63871.00, 64989.00)
   Dim aTurn2017 As Float[] = ReturnTurnover(65150.00, 66300.00)
   Dim aTurn2018 As Float[] = ReturnTurnover(66450.00, 67700.00)
 
   $sHead = ("Report 2019")
   DeletePic
   Me.Width = Screen.Width - 200
   Me.Height = Screen.Height - 200
   Chart.CountDataSets = 10
   Chart.XAxe.Font = Font["Sans Serif,10"]
   Chart.YAxe.Font = Font["Sans Serif,6"]
   Chart.YAxe.MinValue = 22000.00
   Chart.YAxe.MaxValue = 68000.00
   Chart.YAxe.Step = 2000
   With Chart.Colors.Values
     .Add(Color.Red)
     .Add(Color.Blue)
     .Add(Color.Green)
     .Add(Color.Cyan)
     .Add(Color.Orange)
     .Add(Color.Gray)
     .Add(Color.DarkBlue)
     .Add(Color.Yellow)
     .Add(Color.Violet)
     .Add(Color.Pink)
     .Add(Color.LightGray)
     .Add(Color.DarkGreen)
   End With
   btnColors_Click
   Chart.Headers.Values = aMonths
   Chart[0].Values = aTurn2009
   Chart[0].Text = "2009"
   Chart[1].Values = aTurn2010
   Chart[1].Text = "2010"
   Chart[2].Values = aTurn2011
   Chart[2].Text = "2011"
   Chart[3].Values = aTurn2012
   Chart[3].Text = "2012"
   Chart[4].Values = aTurn2013
   Chart[4].Text = "2013"
   Chart[5].Values = aTurn2014
   Chart[5].Text = "2014"
   Chart[6].Values = aTurn2015
   Chart[6].Text = "2015"
   Chart[7].Values = aTurn2016
   Chart[7].Text = "2016"
   Chart[8].Values = aTurn2017
   Chart[8].Text = "2017"
   Chart[9].Values = aTurn2018
   Chart[9].Text = "2018"
   Chart.Title.Font = Font["Sans Serif,24,Bold"]
   Chart.Title.Text = ("Turnover 2009 - 2018")
   Chart.Legend.Visible = True
   Chart.Legend.Font = Font["Sans Serif,12"]
   Chart.Legend.Position = Align.Bottom
   Chart.YAxe.ShowIntervalLines = True
   Chart.BackGround = Color.RGB(176, 220, 241)
   btnType_Click
 
 End
 
 Public Sub DrawingArea1_Draw()
 
   Chart.Width = DrawingArea1.ClientWidth
   Chart.Height = DrawingArea1.ClientHeight
   Chart.Draw()
 
 End
 
 Private Function ReturnTurnover(fMin As Float, fMax As Float) As Float[]
 
   Dim aTurnover As New Float[]
   Dim fRes As Float
 
   Randomize
   For i As Integer = 1 To 12
     fRes = Rnd(fMin, fMax)
     If i = 2 Then
       fRes = fRes - ((fRes / 100) * 6)
     Else If i = 8 Then
       fRes = fRes - ((fRes / 100) * 50)
     Endif
     aTurnover.Add(Round(fRes, -2))
   Next
   Return aTurnover
 
 End
 
 Public Sub btnType_Click()
 
   If btnType.Text = ("Lines") Then
     Chart.Legend.Title = ("The color of the years")
     Chart.Type = ChartType.Lines
     btnType.Text = ("Columns")
   Else
     Chart.Legend.Title = ("The color of the months")
     Chart.Type = ChartType.Columns
     btnType.Text = ("Lines")
   Endif
   DrawingArea1.Refresh()
 
 End
 
 Public Sub btnColors_Click()
 
   If btnColors.Text = ("Custom colors") Then
     Chart.Colors.Style = Chart.Colors.Custom
     btnColors.Text = ("Default colors")
   Else
     Chart.Colors.Style = Chart.Colors.Auto
     btnColors.Text = ("Custom colors")
   Endif
   DrawingArea1.Refresh()
 
 End
 
 Private Function sPicPaths_Read() As String[]
 
   Return $sPicPaths
 
 End
 
 Public Sub btnSavePicture_Click()
   ' Vuott tip
   Dim pic As Picture
 
   pic = Desktop.Screenshot(DrawingArea1.ScreenX, DrawingArea1.ScreenY, DrawingArea1.Width, DrawingArea1.Height)
   $sPicPaths.Push("/tmp/chart-pic" & CStr($sPicPaths.Count + 1) & ".png")
   pic.Save($sPicPaths[$sPicPaths.Max], 50)
 
 End
 
 Public Sub btnPrint_Click()
 
   If $sPicPaths.Count > 0 Then
     Report1.Preview
     DeletePic
     Me.Close
   Endif
 
 End
 
 Private Sub DeletePic()
 
   Dim s As String
 
   For Each s In Dir("/tmp", "chart-pic*.png", gb.File)
     Try Kill "/tmp" &/ s
   Next
 
 End
 
 
 Private Function sHead_Read() As String
 
   Return $sHead
 
 End


Diamo uno sguardo a quanto abbiamo appena scritto:

Per prima cosa abbiamo creato due proprietà di sola lettura per poter passare al report il titolo della relazione e le path delle immagini del o dei grafici.
Qui viene tutto simulato attraverso il codice ma nella realtà i dati saranno il frutto di interrogazioni a un database o qualcosa di simile.
Pertanto, all’apertura, attraverso la funzione ReturTurnover creiamo i fatturati mese per mese e li assegnamo ai rispettivi vettori (array).
Anche se non dovrebbe servire in quanto lo facciamo già in btnPrint_Click(), attraverso la routine DeletePic eliminiamo eventuali immagini di grafici presenti nella cartella tmp.
Impostiamo il grafico per 10 set di dati (i dieci anni confrontati).
Impostiamo i font e i valori minimo e massimo (di anni e fatturato) per gli assi del grafico orizzontale (ascisse) e verticale (ordinate).
Impostiamo l’intervallo dei valori in base al quale verrà suddiviso il fatturato e lo sfondo.
Per avere i colori personalizzati uno differente dall’altro, occorre impostarli sui dati più alti mostrati dai grafici in questo caso i 12 mesi.
Agendo sul pulsante btnColors impostiamo i colori di default e la scritta del pulsante stesso.
Passiamo il vettore dei mesi come valori per l’asse delle ascisse.
E passiamo i vettori degli anni come valori per l’asse delle ordinate.
Impostiamo il font del titolo e passiamo il valore.
Mostriamo la leggenda alla base del grafico impostandone il font.
Mostriamo le linee degli intervalli di valore.
Diamo un colore allo sfondo.
E alla fine dell’evento Open solleviamo l’evento btnType_Click per mostrare il grafico a colonne.
Infatti btnType_click alterna la creazione dei grafici a colonna e a linee a seconda di quanto scritto nella proprietà Text, alla fine attiva l’evento DrawingArea_Draw con DrawingArea1.Refresh.
Ogni volta che agiamo sul pulsante btnSavePicture per salvare le immagini nella cartella tmp, usiamo uno dei codici suggeriti da vuott in questa pagina:
https://www.gambas-it.org/wiki/index.php?title=Generare_un_file_immagine_da_una_DrawingArea
btnPrint_Click apre l’anteprima del Report, come detto cancella le immagini inviate al report e alla chiusura della finestra report chiude l’applicazione.

Le scritte in inglese sono avvolte da parentesi per poterle tradurre e creare un progetto internazionale. Per renderlo tale, al momento della creazione del progetto basta spuntare la casella Il progetto è traducibile, se non lo abbiamo fatto basta andare al menu Progetto > Proprietà > Opzioni e swithcciare su Il progetto è traducibile, nella IDE appare il nuovo pulsante Traduci e se ci clicchiamo sopra possiamo tradurre le scritte fra parentesi nell’apposita finestra.


Il disegno della finestra Report

Nel browser sulla sinistra della IDE clicchiamo col tasto destro del mouse sulla cartella Sorgenti > Nuovo > Report… e scegliamo OK nella finestra che appare e propone Report1. Doppio click su Report1 per farne apparire la finestra.

Dalla ToolBox scheda Report scegliamo una ReportLabel e disegnamola sulla finestra. Diamogli le proprietà:

Alignement = Center
Fixed = True (serve a ripetere il contenuto della label su tutte le pagine)
Height = 10mm

Dalla scheda Container scegliamo un ReportVBox e disegnamolo appena sotto la label dando True alla proprietà Expand.

Appena sotto disegnamo un’altra label con le stesse proprietà della prima ma con in più:

Text = ="Page " & page & " on " & pages (la scritta deve comprendere = il quale indica al report che trattasi di funzione).


Il codice del Report

Agiamo sulla freccia oppure sul tasto funzione F12 per passare a Report1.class e scriviamo:

 Public Sub Report_Open()
 
   Dim s As String
   Dim hRepIm As ReportImage
 
   ReportLabel1.Text = FMain.sHead
   If FMain.sPicPaths.Count > 1 Then
     Report1.Orientation = Printer.Portrait
     For i As Integer = 0 To FMain.sPicPaths.Max
       s = FMain.sPicPaths[i]
       hRepIm = New ReportImage(ReportVBox1)
       hRepIm.Alignment = Align.Center
       hRepIm.Height = "11cm"
       hRepIm.Stretch = Report.Proportional
       hRepIm.Image = Image.Load(s)
     Next
   Else
     Report1.Orientation = Printer.Landscape
     s = FMain.sPicPaths[0]
     hRepIm = New ReportImage(ReportVBox1)
     hRepIm.Alignment = Align.Center
     hRepIm.Expand = True
     hRepIm.Stretch = Report.Proportional
     hRepIm.Image = Image.Load(s)
   Endif
 
 End


Anche qui diamo uno sguardo a quanto abbiamo appena scritto.

Nell’evento di apertura del report passiamo alla prima label il testo per l’intestazione del report. Se abbiamo disegnato più di un grafico allora la pagina del report si posiziona in verticale altrimenti in orizzontale. Per ogni percorso di immagine di grafico disegnamo nel ReportVBox una ReportImage con le seguenti proprietà:

Alignement = Align.Center
Expand = True
Stretch = Report.Proportional
Image = Image.Load(<percorso/immagine>)

Fatto, ora possiamo avviare il progetto per constatarne il corretto funzionamento.

vedi anche
gb.report2


Riferimenti