Criando Gráficos com o Google Chart e PHP

Artigo que explica como um script PHP pode gerar gráficos utilizando o Google Chart de forma simples.

Introdução

Atenção: o "Image Chart" mostrado neste artigo foi depreciado pelo Google em 2012. Um artigo mais recente sobre o assunto apresenta o novo recurso para Gerar Gráficos em PHP com o Google Charts.

Google Chart é um serviço do Google que provê a criação de gráficos dinamicamente. O funcionamento é simples: o programador faz uma requisição ao site do Google Chart com os parâmetros desejados (através da própria URL); e o Google devolve uma imagem com os dados plotados na forma de gráfico. Normalmente o programador cria uma tag <img> com o atributo src apontando para uma URL gerada dinamicamente e o resultado já é visto no HTML. Outra alternativa é o programador realizar a requisição, recuperar a imagem em formato binário, salvá-la em algum lugar, depois exibí-la quando quiser.

Para obter todos detalhes sobre o funcionamento da ferramenta, recomendo que leia a API do Google Chart. Neste artigo vou mostrar apenas o básico.

O uso da ferramenta é, a princípio, irrestrito. O Google apenas se reserva o direito de bloquear acessos que lhe pareçam abusivos. Também orientam que seja enviada a estimativa de uso do recurso por e-mail, caso seja esperado mais de 250.000 requisições por dia.


Exemplo

Vejamos a própria URL de exemplo da API e o significado de cada parâmetro:

https://chart.googleapis.com/chart?cht=p3&chs=250x100&chd=t:60,40&chl=HTML|CSS

cht - Tipo de gráfico (p3 é o tipo "torta 3D");

chs - Largura x Altura da imagem gerada;

chd - São os dados do gráfico ("t" é o tipo de empacotamento dos dados e "60" e "40" são os dados propriamente ditos);

chl - São os labels (legendas) de cada item do gráfico (separados por "|" e codificadas em UTF-8).

O resultado é este: Gráfico de Exemplo

A URL usada para greração dos gráficos é https://chart.googleapis.com/chart, mas pode-se usar os sub-domínios numéricos (0, 1, 2, etc.) quando deseja mostrar vários gráficos em uma única página. Para evitar a sobrecarga de um único servidor, estes sub-domínios encaminham a requisição para outros servidores. Exemplo:

http://0.chart.googleapis.com/chart?...
http://1.chart.googleapis.com/chart?...
http://2.chart.googleapis.com/chart?...
...

Google Chart via PHP

Para gerar gráficos dinamicamente via PHP, a principal preocupação do programador é a geração da URL corretamente. Para tanto, é importante conhecer algumas funções: urlencode e http_build_query.

urlencode serve para codificar o valor de um parâmetro para ser colocado em uma URL.

http_build_query serve para montar uma query string de uma URL a partir de um array associativo de chaves/valores. É uma forma simplificada de usar urlencode sobre vários elementos de um array e concatenar estes dados na forma de query string.

Na prática, a função http_build_query já é suficiente montar uma URL a ser passada para o Google Chart. Veja um exemplo do mesmo gráfico gerado via PHP:

// Dados do gráfico
$tipo = 'p3';
$largura = 250;
$altura = 100;
$dados = array(
    'HTML' => 60,
    'CSS'  => 40
);

// Gerando a URL dinamicamente
$labels = array_keys($dados);
$valores = array_values($dados);

$grafico = array(
   'cht' => $tipo,
   'chs' => $largura.'x'.$altura,
   'chd' => 't:'.implode(',', $valores),
   'chl' => implode('|', $labels)
);
$url = 'https://chart.googleapis.com/chart?'.http_build_query($grafico, '', '&amp;');

// Imprimindo o gráfico
printf('<img src="%s" width="%d" height="%d" alt="%s" />',
    $url, $largura, $altura, htmlentities('Gráfico de Exemplo', ENT_COMPAT, 'UTF-8'));

Outra alternativa é procurar alguma classe que já ofereça uma interface de criação de gráficos do Google Chart. Por exemplo, buscando "Google Chart" no site http://www.phpclasses.org/

Embora a forma apresentada seja passando os dados via GET, é possível passá-los via POST. Neste caso, é necessário algum mecanismo para enviar os dados dinamicamente e receber o resultado. Por exemplo, usando cURL.

Abaixo é apresentada uma lista com os principais tipos de gráficos:

  • Gráficos de barra:
    • bhs - Barra horizontal simples;
    • bvs - Barra vertical simples;
    • bvo - Barra vertical em pilha
    • bhg - Barra horizontal com itens de comparação dispostos de forma paralela;
    • bvg - Barra vertical com itens de comparação dispostos de forma paralela;
  • Gráficos de linha:
    • lc - Gráfico de linha simples com as coordenadas x e y;
    • ls - Gráfico de linha simples sem as coordenadas;
    • lxy - Gráfico de linha onde se especifica as coordenadas x e y de cada ponto;
  • Gráficos de Pizza (ou torta):
    • p - Pizza normal;
    • p3 - Pizza em 3D;
    • pc - Vários dados concentricos;
  • Gráficos de ponto:
    • s - Plotagem de pontos.

Gerando Gráfico com dados do BD (MySQL)

Segue um exemplo de como gerar um gráfico com o Google Chart coletando dados do MySQL (usando PDO). A função é específica para gerar um gráfico de torta, mas serve para ilustrar um exemplo real:

<?php
// Consultar dados
$dados = array();

$pdo = new PDO('mysql:host=localhost;dbname=teste', 'usuario', 'senha');
$sql = 'SELECT sexo, COUNT(*) as quantidade FROM pessoas GROUP BY sexo';
$stmt = $pdo->query($sql);
while ($obj = $stmt->fetchObject()) {
    switch ($obj->sexo) {
    case 'M':
        $dados['Homens'] = $obj->quantidade;
        break;
    case 'F':
        $dados['Mulheres'] = $obj->quantidade;
        break;
    }
}

echo gerar_grafico_torta($dados, 'Quantidade de Homens/Mulheres');
exit(0);

/**
 * Imprime um grafico de torta
 * @param array[string => int] $dados: Dados do Grafico
 * @param string $titulo: Titulo do grafico
 * @param int $largura: Largura do grafico
 * @param int $altura: Altura do grafico
 * @return string Tag IMG com o caminho para o grafico
 */
function gerar_grafico_torta($dados, $titulo, $largura = 250, $altura = 100) {

    // Gerando a URL dinamicamente
    $labels = array_keys($dados);
    $valores = array_values($dados);

    // Converter valores para porcentagens
    $soma = array_sum($valores);
    $percentual = array();
    foreach ($valores as $valor) {
        $percentual[] = round($valor * 100 / $soma);
    }

    $grafico = array(
        'cht'  => 'p3',
        'chs'  => $largura.'x'.$altura,
        'chd'  => 't:'.implode(',', $percentual),
        'chl'  => implode('|', $labels)
    );
    $url = 'https://chart.googleapis.com/chart?'.http_build_query($grafico, '', '&');

    // Imprimindo o gráfico
    return sprintf('<img src="%s" width="%d" height="%d" alt="%s" />',
        $url, $largura, $altura, htmlentities($titulo, ENT_COMPAT, 'UTF-8')
    );
}

17 comentários

rubS (autor do blog) disse...

Olá, Leo Mendes,

O que quis dizer com "em tempo real"? Consultando dados de uma base de dados e montando o gráfico? Há exemplos no próprio post, na parte "Gerando Gráfico com dados do BD (MySQL)".

Guilherme Caires disse...

Olá,

Tentei criar o gráfico com a opção de consulta ao banco de dados mysql e não consegui.

Adaptei para o que eu precisava mas não deu certo.

Então resolvi criar um banco de dados igual ao que fez no exemplo acima, mas continuou dando o mesmo erro conforme abaixo:

Fatal error: Call to a member function fetchObject() on a non-object in E:\xampp\htdocs\odonto\index5.php on line 8

Sabe o que pode estar acontecendo?
Desde já obrigado.

rubS (autor do blog) disse...

Olá, Guilherme
Provavelmente na linha 7, ao executar a query, o PDO não devolveu um objeto PDOStatement conforme esperado. Tente executar a SQL da linha 7 diretamente no BD para ver se está retornando os dados corretamente.

Anônimo disse...

Olá muito bom seu artigo, saberia me informar sobre as questões de termos de uso e licença para utilização do Google chart? Gostaria de utilizar em meu projeto de pesquisa da Universidade que estudo. Quais são as possibilidades para meu caso?

Rubens Takiguti Ribeiro (autor do blog) disse...

Olá, Anônimo,

Só para ressaltar, o "ImageCharts" já está depreciado em favor do novo "GoogleCharts". Veja um artigo sobre o novo recurso aqui:
http://rubsphp.blogspot.com.br/2013/05/gerar-graficos-em-php-com-o-google-charts.html

Mas respondendo à sua pergunta: eu me lembro que o ImageCharts tinha uma quantidade limite de requisições que você poderia fazer gratuitamente por dia, sem precisar notificar o Google e, se você achasse que iria precisar mais do que a quantidade, precisava entrar em contato com o Google para liberarem o acesso (não sei se cobram ou cobravam por isso).

Os termos e condições do novo GoogleCharts está aqui:
https://developers.google.com/chart/terms
https://developers.google.com/terms/

Sugiro que dê uma lida aprofundada para ter mais detalhes. Em todo caso, para uso acadêmico e "moderado", não acho que há nenhuma restrição.

Anônimo disse...

Muito obrigado por responder em tempo real Rubens, é de grande valia sua ajuda, é um projeto do governo federal e por isso tenho receio caso as informações sejam de alguma forma capturadas, mas creio que para fins de gráfico eu passaria apenas informações não sigilosas. Obrigado!!! o/

refinski disse...

Bom dia Rubens, gostaria de pedir uma ajuda, eu tenho aqui na minha empresa um site interno de abertura de chamados, e queria fazer uma relacao entre duas colunas do mysql, uma tem os setores id_setores e a outra o status, caso o chamado for finalizado ficaria `A`, minha ideia seria fazer um botao que na hora que eu clicasse emitisse um grafico na tela tipo pizza com os setores e o numero de chamados finalizados, acha que seria dificil fazer isso, grande abraco.

Rubens Takiguti Ribeiro (autor do blog) disse...

Olá, Refinski

Não sei se entendi direito, mas acho que seria uma consulta do tipo:
SELECT status, COUNT(*) AS total FROM chamados;

Ela vai devolver a quantidade total de chamados por status, por exemplo:
pendentes = 40
finalizados = 10

Depois, basta passar estes números para o gráfico.