VB - Exibindo seus dados em Gráficos


Hoje você vai aprender como exibir seus dados em gráficos. Se você consultar o site vai encontrar dois artigos que tocam no assunto , mas falam sobre o MSChart. Neste artigo eu vou estar usando outra OCX : a ocx GRAPH32.OCX.

O controle GRAPH32.OCX foi distribuído até a versão 5 do VB , e mesmo nesta versão , ele não era instalado por padrão. Para instalar o controle procure no seu CD do VB5 na pasta Tools\Controls e copie o arquivo do CD para o seu sistema e registre a ocx usando o arquivo vbctrl.reg.

Para usar o controle instalado basta incluir o componente no seu projeto através do Menu Project opção Components .

O nome do controle é Pinnacle-BPS Graph Control

Feito isto você esta pronto para criar gráficos usando o controle Graph32.ocx. É o que vamos fazer a partir de agora..

Este componente possui muitas propriedades que podemos usar para criar e personalizar gráficos no VB. Podemos definir vários tipos de gráficos , títulos , cores , pontos , etc...

Podemos definir entre diversos tipos de gráficos usando a propriedade GraphType. Para ver as opções vamos criar um projeto padrão EXE no VB e inserir o Componente no formulário padrão. Abaixo temos a figura do controle no formulário e a relação de algumas de suas propriedades . Estamos exibindo também os tipos de gráficos na propriedade GraphType.

Para exibir dados no controle você deve carregá-los no controle. E como é que o controle faz o tratamento dos dados ?

O controle exige que os dados estejam organizados em conjunto de pontos pois ele precisa saber quantos pontos de dados existem em cada conjunto cujo gráfico você quer exibir. Inicialmente você tem um único conjunto de dados com múltiplos pontos. Assim se você deseja exibir o gráfico das vendas de uma empresa para os últimos 12 meses, você terá um único conjunto de dados com 12 pontos, um para cada mês.

Você pode definir as propriedades NumSets e NumPoints para informar ao controle como os dados estão organizados. Para o exemplo acima mencionado NumSets seria definido como sendo igual a 1 e NumPoints como igual a 12.

No controle Graph1 ao lado temos definido as seguintes propriedades:

- GraphType = 2- GphBar2D

- NumSets = 1

- NumPoints = 12

Após fazer esta configuração temos que incluir os dados para exibir o gráfico. Para incluir dados no gráfico siga os seguintes passos:

Como não é muito eficiente entrar com dados em tempo de desenvolvimento vamos mostrar como alimentar os dados em tempo de execução. Vamos criar um novo Projeto do tipo STANDARD EXE , incluir o controle Graph no formulário e incluir também um botão de comando chamado cmdVendas .

A seguir insira o código ao lado da figura no evento Click do botão cmdVendas e execute o projeto.

Private Sub cmdVendas_Click()
Dim i As Integer
'limpa o controle 
Graph1.DataReset = gphAllData
'define o tipo de grafico
Graph1.GraphType = gphBar3D
'define o conjunto de pontos e dados
Graph1.NumSets = 1
Graph1.NumPoints = 12
'incluindo os dados em tempo de execução
For i = 1 To 12
    Graph1.ThisPoint = 1
    Graph1.GraphData = 1
Next
    
'força o VB a redesenhar o gráfico
Graph1.DrawMode = gphDraw
End Sub

 

O projeto em tempo de desenho O código do evento Click de CommandButton O resultado da execução do projeto

Uma outra forma de obter o mesmo resultado mas com um melhor desempenho é definir a propriedade AutoInc como igual a 1 de forma que o controle irá incrementar automaticamente a propriedade NumPoints.  O trecho de código a alterar seria :

Nota: Ao usar a propriedade AutoInc o VB irá sugerir  "gphOff" ou "gphOn" mas isto irá gerar um erro. Informe o valor 1 para contornar o problema.

'incluindo os dados em tempo de execução
Graph1.AutoInc = 1

For i = 1 To 12
    Graph1.GraphData = i
Next

Outra forma de alimentar com dados o controle é usar a propriedade QuickData. Esta propriedade aceita uma string que contém todos os conjuntos de dados e pontos. Cada conjunto de dados deve ser separado por um marcador de carriage return/line feed (vbCrLf ) ; e cada ponto de dado deve vir separado por um caracter Tab (vbTab ).

Ao utilizar esta propriedade você não precisa configurar qualquer das propriedades que tratam os conjuntos de dados ou pontos nem precisa realizar nenhum loop.

Inicie um novo Projeto tipo STANDARD EXE e no formulário padrão inclua o controle Graph e um botão de comando. A seguir no evento Click do botão de comando insira o código abaixo:

Private Sub Command2_Click()
Dim strDados As String
'vamos criar 3 conjuntos de dados com 5 pontos
strDados = "10" & vbTab & "15" & vbTab & "20" & vbTab & "25" & vbTab & "30" & vbCrLf
strDados = strDados & "40" & vbTab & "45" & vbTab & "50" & vbTab & "55" & vbTab & "60" & vbCrLf
strDados = strDados & "70" & vbTab & "75" & vbTab & "80" & vbTab & "85" & vbTab & "90" & vbCrLf
'definindo o tipo de gráfico - gráfico de linhas
Graph1.GraphType = gphLine

'define a cor do fundo do gráfico
Graph1.Background = 0

'limpa o controle
Graph1.DataReset = gphAllData

'atribui os dados na propriedade Quickdata
'(a propriedade não vai aparece na lista mas digite-a assim mesmo)
Graph1.QuickData = strDados
'exibe o gráfico
Graph1.DrawMode = gphDraw
End Sub
O código para alimentar com dados o gráfico usando QuickData O resultado obtido

Note que não precisamos definir as propriedades NumPoints e NumSets a propriedade QuickData faz isto automaticamente.

Qual a vantagem de usar QuickData ? Bem , deixa eu achar uma ...

O QuickData aceita dados de várias planilhas usando as operações de Recortar e Colar e você pode dados delimitados por Tab no ClipBoard e usá-los como dados alimentado a propriedade. Você pode usar o NotePad , Word ou qualquer editor de texto para colocar valores delimitados por Tab em um arquivo de disco e a seguir ler o arquivo e alimentar com dados a propriedade QuickData.

Vamos então criar no NotePad um conjunto de dados conforme a figura abaixo. Você informa um valor e tecla TAB , para terminar a linha de dados tecle ENTER. Assim teremos 4 conjunto de dados com 5 pontos cada.

Inicie um novo Projeto tipo STANDARD EXE e no formulário padrão inclua o controle Graph e um botão de comando. A seguir no evento Click do botão de comando insira o código abaixo:

Private Sub Command3_Click()
Dim strLinha As String
Dim strDados As String
Dim strArquivo As String
Dim iArquivo As Integer
'define o caminho do arquivo
strArquivo = App.Path & "\tabDados.txt"
iArquivo = FreeFile
'abre o arquivo para leitura e linha a linha para a variavel strdados
Open strArquivo For Input As iArquivo
  Do While Not EOF(iArquivo)
     Line Input #1, strLinha
     strDados = strDados & strLinha & vbCrLf
  Loop
Close #iArquivo
'definindo o tipo de gráfico - gráfico de linhas
Graph1.GraphType = gphLine
'define a cor do fundo do gráfico
Graph1.Background = 0
'limpa o controle
Graph1.DataReset = gphAllData
'atribui os dados na propriedade Quickdata
'(a propriedade não vai aparece na lista mas digite-a assim mesmo)
Graph1.QuickData = strDados

'exibe o gráfico
Graph1.DrawMode = gphDraw
End Sub

O resultado da execução do código acima é mostrada na figura abaixo:

Podemos melhorar o visual dos nossos gráficos incluindo , títulos , etiquetas e legendas , facilitando assim a leitura e o entendimento dos gráficos. Fazemos isto usando as propriedades : GraphTitle , LegendText e LabelText. Vamos ao exemplo:

Inicie um novo Projeto tipo STANDARD EXE e no formulário padrão inclua o controle Graph e um botão de comando. A seguir no evento Click do botão de comando insira o código abaixo:

Private Sub Command1_Click()
Dim i As Integer
'define o tipo de grafico
Graph1.DataReset = gphAllData
Graph1.GraphType = gphBar3D
'incluindo titulo no grafico
Graph1.GraphTitle = "Título do Grafico"
Graph1.BottomTitle = "Título da base do gráfico"
Graph1.LeftTitle = "Título da esquerda"
'incluindo legendas
Graph1.AutoInc = 1
For i = 1 To 12
    Graph1.LegendText = "L" & CStr(i)
Next
'incluindo etiquetas
Graph1.AutoInc = 1
For i = 1 To 12
    Graph1.LabelText = "E" & CStr(i)
Next
'define o conjunto de pontos e dados
Graph1.NumSets = 1
Graph1.NumPoints = 12
'incluindo os dados em tempo de execução
Graph1.AutoInc = 1
For i = 1 To 12
    Graph1.GraphData = i
Next  
'exibe o gráfico
Graph1.DrawMode = gphDraw
End Sub

A figura acima mostra o resultado da execução do código ao lado.

As vezes é necessário aumentar o tamanho que o controle ocupa no formulário para poder tornar visível algumas das opções do gráfico.

 

Um recurso interessante que o controle oferece é que podemos enviar o gráfico para um arquivo (imagem) , para o clipboard ou para a impressora.. A seguir mostramos o código que você pode usar para cada uma destas opções:

Salvando o gráfico como um arquivo

Para salvar o gráfico como um arquivo imagem , vou usar um controle CommonDialog a fim de automatizar a tarefa de escolha do local e do nome do arquivo do gráfico a ser gerado. Para atingir este objetivo usamos a propriedade DrawMode definida para gphBlit e gphWrite.

O código para salvar o gráfico como um arquivo é dado a seguir :

Private Sub Command1_Click()
Dim strArquivo As String
CommonDialog1.DefaultExt = ".bmp"
CommonDialog1.DialogTitle = "Salvar Gráfico"
CommonDialog1.Filter = "BitMap Files | *.bmp"
CommonDialog1.ShowSave
'define o nome do arquivo a ser salvo
strArquivo = CommonDialog1.FileName
If Trim(strArquivo) <> "" Then
 Graph1.DrawMode = gphBlit       'define modo como bitmap
 Graph1.ImageFile = strArquivo  
 Graph1.DrawMode = gphWrite    'força a saida para um arquivo
 Graph1.DrawMode = gphDraw     'redesenha o controle
End If

End Sub

Copiando o gráfico para o ClipBoard

A cópia do gráfico para a área de transferência é feita usando a propriedade DrawMode definida para gphCopy.

Para copiar o gráfico para o clipboard use o código abaixo:

Private Sub Command5_Click()
 Graph1.DrawMode = gphBlit            'define modo como bitmap
 Graph1.DrawMode = gphCopy       'copia o gráfico para o clipboard
 Graph1.DrawMode = gphDraw          'redesenha o controle   
MsgBox "O gráfico foi copiado para o ClipBoard", vbInformation, "Copia Gráfico"
End Sub

Para encerrar este artigo a seguir vou mostrar como você pode criar gráficos a partir de tabelas de um banco de dados Access.

Vou usar o banco de dados Nwind.mdb que vem com o Visual Basic para exibir o gráfico das vendas por categoria para o ano de 1995.

A string SQL que irá realizar a consulta e gerar a tabela com os dados que vamos exibir é a seguinte :

SELECT DISTINCTROW [Product Sales for 1995].CategoryName, Sum([Product Sales for 1995].ProductSales) AS VendasPorCategoria From [Product Sales for 1995] GROUP BY [Product Sales for 1995].CategoryName;

Executando esta consulta iremos obter a seguinte tabela:

Inicie agora um novo projeto no VB e no formulário padrão inclua o controle Graph32.ocx e um Menu com uma opção conforme figura abaixo:

O código completo do projeto é dado a seguir:

Option Explicit
'define varivaveis globais
Private intTipoGrafico As Integer
Private strNomeDB As String
Private strSQL As String
' define objetos de dados
Private ws As Workspace
Private db As Database
Private rs As Recordset
Private lngNumPontos As Long
Private lngLoop As Long

Private Sub Form_Load()
    'define o tamanho inicial do formulário
    If Me.WindowState = vbNormal Then
        Me.Width = Screen.Width * 0.6
        Me.Height = Screen.Height * 0.6
    End If
    intTipoGrafico = 3
End Sub

Private Sub Form_Resize()
    ' faz o grafico preencher o formulário
    Graph1.Left = 1
    Graph1.Top = 1
    Graph1.Width = Me.ScaleWidth
    Graph1.Height = Me.ScaleHeight
End Sub

Public Sub ExibeGrafico()

    ' exbie o grafico
    On Error GoTo LocalErr  
    Screen.MousePointer = vbHourglass
    AbrirBD
    IniciaGrafico
    CarregaDados
    Screen.MousePointer = vbNormal   
    Graph1.DrawMode = gphDraw
    Exit Sub    
LocalErr:
    Err.Raise vbObjectError + 4, App.EXEName, "Erro ao exibir os dados"   
End Sub
Private Sub AbrirBD()

    'abre o banco de dados e gera o recordset com base na consulta sql
    On Error GoTo LocalErr    
    strNomeDB = App.Path & "\NWIND.mdb"

    strSQL = "SELECT DISTINCTROW [Product Sales for 1995].CategoryName, Sum([Product Sales for 1995].ProductSales)_
    AS VendasPorCategoria From [Product Sales for 1995] GROUP BY [Product Sales for 1995].CategoryName;"
    
    Set ws = dbengine.Workspaces(0)
    Set db = ws.OpenDatabase(strNomeDB)
    Set rs = db.OpenRecordset(strSQL, dbOpenSnapshot)  
    Exit Sub
LocalErr:
    Err.Raise vbObjectError + 1, App.EXEName, "Erro ao criar o conjunto de dados"
End Sub
Private Sub IniciaGrafico()

    ' inica o formulario do grafico   
    On Error GoTo LocalErr    
    rs.MoveLast
    lngNumPontos = rs.RecordCount
    
    Graph1.Visible = True

    Graph1.GraphType = intTipoGrafico
    Graph1.GraphTitle = "Vendas por categoria - 1995"
    Graph1.BottomTitle = "Categorias"
    Graph1.LeftTitle = "R$"
    Graph1.NumSets = 1
    Graph1.NumPoints = lngNumPontos
    Graph1.AutoInc = 1    
    Exit Sub    
LocalErr:
    Err.Raise vbObjectError + 2, App.EXEName, "Erro ao inciar o gráfico"    
End Sub
Private Sub CarregaDados()
   
    ' preenche o grafico com dados  
    On Error GoTo LocalErr
    
    rs.MoveFirst
    For lngLoop = 1 To lngNumPontos
        Graph1.GraphData = rs.Fields(1)
        rs.MoveNext
    Next    
   'atribui legendas
    rs.MoveFirst
    For lngLoop = 1 To lngNumPontos
           Graph1.LegendText = rs.Fields(0)
        rs.MoveNext
    Next
   'atribui etiquetas
    rs.MoveFirst
    For lngLoop = 1 To lngNumPontos
           Graph1.LabelText = rs.Fields(0)
        rs.MoveNext
    Next    
  Exit Sub    
LocalErr:
    Err.Raise vbObjectError + 3, App.EXEName, "Erro ao carregar dados"    
End Sub
Private Sub mnufile_Click()
  ExibeGrafico
End Sub

 

Executando o projeto teremos:

E com isto encerro este artigo sobre como criar gráficos com o controle Graph32.ocx.

Até breve...


José Carlos Macoratti