Que o GD tem mil e uma utilidade, isso você já sabe. Que ele é chatinho de trabalhar, isso provavelmente você também já descobriu. Mas apesar de tudo isso, é uma das formas mais rápidas de se criar imagens 100% baseadas em script.
É o caso do gerador de relatórios de gráficos que vamos ver a seguir.
Utilizando PHP e GD, vamos criar um relatório de vendas, baseado na quantidade de vendas de cada vendedor. De posse desses valores, vamos gerar um gráfico em formato pizza, com as porcentagens de vendas.
O exemplo deste código, está aqui: http://www.flaviajobs.com.br/sistemas/revistaphp/graficopizza1.php
Inclui o exemplo de preenchimento. Preencha e gere o gráfico para ver como funciona. J
Primeiramente, criei o formulário que você viu aí em cima. Ele apenas informa ao script php, o que tem que ser feito.
No arquivo: graficopizza1.php, temos o form:
<form id="form1" name="form1" method="post" action="graficopizza.php">
<span class="style1">Relatório de vendas</span><br />
<br />
<span class="style1">Nome do relatório:</span>
<label>
<input name="titulo" type="text" id="titulo" size="40" />
</label>
<br />
<span class="style1">Cor do fundo do relatório:</span>
<label>
<input name="fundo" type="text" id="fundo" />
</label>
<span class="style3">(no formato rgb, separado por traços: 255-255-255-255 )</span><br />
<br />
<span class="style1">Vendedores:</span><br />
<label>
<textarea name="usuarios" cols="30" rows="4" id="usuarios"></textarea>
<span class="style1">(nomes separados por virgulas) </span></label>
<p><span class="style1">Quantidades de vendas de cada vendedor acima (na ordem dada acima):</span><br />
<label>
<input name="valores" type="text" id="valores" size="40" />
</label>
<span class="style3">(separar por virgula)</span> <br />
</p>
<label>
<input name="Submit" type="submit" class="style1" value="Gerar gráfico" />
</label>
</form>
Informei na action deste form, o método POST de envio , e o arquivo graficopizza.php, e é dele que vamos falar agora.
graficopizza.php
Primeiro vamos pegar os dados principais do form, que são: os nomes dos vendedores, e a quantidade de vendas de cada um deles.
No meu caso, tanto os nomes dos vendedores quanto as quantidades de vendas, são passadas separadas por vírgula. Fiz isso pra facilitar minha vida, mas você pode implementar como achar melhor.
<?php // verificando os nomes dos usuários e os valores passados pelo form
if (isset($_REQUEST["usuarios"])) $dp = explode(",",$_REQUEST["usuarios"]);
if (!isset($_REQUEST["valores"]));
// separando os valores das vendas de cada usuário, com virgula
$valores = explode(",",$_REQUEST["valores"]);
// contando os valores. neste script, setei para que o limite fosse 100 valores
// ou seja, 100 usuários, com seus respsctivos 100 valores.
$n_valores = count($valores);
if ($n_valores > 100) $n_valores = 100;
$total = 0;
for ($z=0; $z<$n_valores; $z++) {
if ($parte[$z]<0);
$w=$z+1;
$parte[$w] = $valores[$z];
$total += $valores[$z];
}
Feito isso, começo a pré-montar o gráfico, com base nas informações conseguidas acima
// calculando o diametro da pizza, no caso, 200 pixels
$d = Array();
$diametro = 200;
$radius = $diametro/2;
// convertendo os valores, para graus, afinal, o negócio é redondo..rs
for ($y=1; $y<=$n_valores; $y++) $d[$y] = ($parte[$y]/$total) * 360;
$im = ImageCreate(450, 300);
// cores que serão utilizadas nas fatias do gráfico
$preto = ImageColorAllocate($im, 0, 0, 0);
$branco = ImageColorAllocate($im, 255, 255, 255);
$verde = ImageColorAllocate($im, 0, 255, 0);
$rosa = ImageColorAllocate($im, 255, 128, 128);
$amarelo = ImageColorAllocate($im, 255, 255, 128);
$vermelho = ImageColorAllocate($im, 255, 0, 0);
$lilas = ImageColorAllocate($im, 128, 128, 192);
$marrom = ImageColorAllocate($im, 128, 64, 64);
$laranja = ImageColorAllocate($im, 255, 128, 64);
$vinho = ImageColorAllocate($im, 64, 0, 64);
$gelo = ImageColorAllocate($im, 210, 210, 210);
$azul = ImageColorAllocate($im, 0, 0, 255);
$cinza = ImageColorAllocate($im, 102, 102, 102);
$amarelo2 = ImageColorAllocate($im, 255, 255, 0);
$vermelho2 = ImageColorAllocate($im, 126, 14, 1);
Pegando mais dados informados no form, no caso, o fundo, pra continuar montando o relatório.
// verificando se foi passada a variável fundo, através do form
// no formato rgb, separados por traço: 255-255-255-255
// se foi, mostra a cor, senão, deixa em branco.
$e=0;
if (isset($_REQUEST["fundo"])) {
$r = explode("-",$_REQUEST["fundo"]);
for ($z=0; $z<3; $z++) {
if (is_numeric($r[$z])) {
if ($r[$z] >= 0) {
if ($r[$z] <= 255) $e++;
}
}
}
}
Você deve estar se perguntando porque o script pega alguns dados do form, muito depois de ter começado a montar o relatório. Isso se deve mais ao fato organizacional do que qualquer outra coisa. Eu prefiro solicitar os dados que já foram passados, somente no momento em que vou utiliza-los, evitando carregar todos eles no inicio do arquivo.
Bem, vamos continuar montando o gráfico, agora montando a parte mais ‘bonitinha’.
$cor[] = $branco;
$cor[] = $verde;
$cor[] = $rosa;
$cor[] = $amarelo;
$cor[] = $vermelho;
$cor[] = $lilas;
$cor[] = $marrom;
$cor[] = $gelo;
$cor[] = $azul;
$cor[] = $cinza;
$cor[] = $laranja;
$cor[] = $vinho;
$cor[] = $amarelo2;
$cor[] = $vermelho2;
$cor[] = $preto;
// preenchendo o fundo da imagem, com a cor informada no form, ou deixando em branco
ImageFill($im, 0, 0, $fundo);
// desenhando a linha de base
ImageArc($im, 153, 153, $diametro, $diametro, 315, 135, $preto);
$u_angulo = 0;
for ($z=1; $z<=$n_valores; $z++) {
// calculando o arco do gráfico
ImageArc($im, 150, 150, $diametro, $diametro, $u_angulo,($u_angulo+$d[$z]), $preto);
$u_angulo = $u_angulo + $d[$z];
$end_x = round(150 + ($radius * cos($u_angulo*pi()/180)));
$end_y = round(150 + ($radius * sin($u_angulo*pi()/180)));
ImageLine($im, 150, 150, $end_x, $end_y, $preto);
}
$a_angulo = 0;
for ($z=1; $z<=$n_valores; $z++) {
$ponteiro = $a_angulo + $d[$z];
$e_angulo = ($a_angulo + $ponteiro) / 2;
$a_angulo = $ponteiro;
$end_x = round(150 + ($radius * cos($e_angulo*pi()/180)));
$end_y = round(150 + ($radius * sin($e_angulo*pi()/180)));
$mid_x = round((150+($end_x))/2);
$mid_y = round((150+($end_y))/2);
ImageFillToBorder($im,$mid_x,$mid_y,$preto,$cor[$z]);
}
Agora vamos formatar a legenda lateral. Nela está contidos os nomes dos vendedores, e a porcentagem de vendas de cada um, com base nos valores previamente informados no formulário.
if ($e == 3)
$fundo = ImageColorAllocate($im, $r[0], $r[1], $r[2]);
else
// sequencia de cores, que serão utilizadas nas fatias do gráfico
$fundo = $branco;
$sombra = $cinza;
// parâmetros da legenda lateral
// distancia horizontal
$r_x=300;
// distancia vertical
$r_y=3;
$e = 280/($n_valores+1);
// desenhando os quadradinhos
for ($z=1; $z<=$n_valores; $z++) {
$w_x = $r_x;
$w_y = $r_y + ($z * $e);
$parte[$z] = round($parte[$z]/$total * 100,1);
imagefilledrectangle($im, $w_x,$w_y,$w_x+15,$w_y+15,$sombra);
imagerectangle($im,$w_x-3,$w_y-3,$w_x+12,$w_y+12,$preto);
imagefilltoborder($im,$w_x-1,$w_y+11,$preto,$cor[$z]);
$w = $z - 1;
if (isset($dp[$w])) $w = "% " . substr($dp[$w],0,12);
else $w = "%";
imagestring($im,3,$w_x+20,$w_y,$parte[$z].$w,$preto);
}
Agora sim, podemos finalizar o relatório, pegando o título informado no form, e desenhando o circulo por fora da pizza, que agora está completa.
// criando a sombra do circulo da pizza
ImageFillToBorder($im, 150 + 72, 150 + 72, $preto, $sombra);
ImageArc($im, 153, 153, $diametro, $diametro,315,135,$sombra);
// verifica se foi passado um titulo através do form
// se foi, mostra
if (isset($_REQUEST["titulo"])) {
$x = strlen($_REQUEST["titulo"]);
if ($x > 100) $w = substr($_REQUEST["titulo"],0,100);
else {
$w = "";
for ($z=1; $z<((30-$x)/2); $z++) $w.=" ";
$w.=$_REQUEST["titulo"];
}
// cor do titulo
ImageString($im, 5, 20, 10, $w, $preto);
}
Feito isso, acabou-se o trabalho, vamos apenas imprimir TUDO isso que fizemos, na tela, em formato de imagem, que no meu caso, usei PNG. (quem viu meu outro tutorial de GD, deve ter visto que também usei PNG lá. Eu prefiro png, por ser muito mais leve, e por costume mesmo... :). E já que sempre que preciso fazer transparências, acabo apanhando do gif, optei por fazer tudo em PNG! J )
// impressão de tudo o que foi feito acima, em png
Header("Content-Type: image/png");
ImagePNG($im); ?>
Bem, acredito que mesmo os trechos de código, estão muito bem explicadinhos, mas se você não entendeu alguma parte, pode me escrever no fjferr@gmail.com ou então, comente aqui.