No famoso Codeproject, existe um pedaço de código que me chamou a atenção pela sua forma simples de construir um gráfico de barras em bitmap em tempo real. Podem encontrar o código original aqui que foi desenvolvido por J A Srikanth.
Mas um destes dias e para as aplicações que desenvolvo no âmbito da consultoria, tive que fazer algumas alterações até porque o código estava em VB e só permitia números inteiros.
Bem a minha intenção era fazer um gráfico de barras que gerava as respostas ás perguntas que ficavam guardadas em XML. A partir daí foi só adaptar.
Neste método, basicamente construía as perguntas e dava o seu respectivo valor. Os valores podiam ser números de vírgula flutuante ou não. Apenas não eram aceites negativos.
private void valorRespostas()
{
ArrayList idperg = new ArrayList();
ArrayList valores = new ArrayList();
idperg.Add("P1");
idperg.Add("P2");
idperg.Add("P3");
idperg.Add("P4");
idperg.Add("P5");
idperg.Add("P6");
idperg.Add("P7");
idperg.Add("P8");
valores.Add(buscaValor("P1"));
valores.Add(buscaValor("P2"));
valores.Add(buscaValor("P3"));
valores.Add(buscaValor("P4"));
valores.Add(buscaValor("P5"));
valores.Add(buscaValor("P6"));
valores.Add(buscaValor("P7"));
valores.Add(buscaValor("P8"));
DesenharGrafico("Gráfico Perguntas", idperg, valores);
}
E pronto... a partir daqui era só desenhar o gráfico e pô-lo no site através do Response.Write ou como eu fiz (não sei se da melhor maneira) através do controlo Image.
private void DesenharGrafico(string titulo, ArrayList aX, ArrayList aY)
{
int iColWidth = 40, iColSpace = 20, iHeightSpace = 25, iXLegendSpace = 30;
int iMaxHeight = 400;
int iTitleSpace = 50;
int iMaxWidth = (iColWidth + iColSpace) * aX.Count + iColSpace;
int iMaxColHeight = 0;
int iTotalHeight = iMaxHeight + iXLegendSpace + iTitleSpace;
Bitmap objBitmap = new Bitmap(Convert.ToInt32(iMaxWidth), Convert.ToInt32(iTotalHeight));
Graphics objGraphics = Graphics.FromImage(objBitmap);
objGraphics.FillRectangle(new SolidBrush(Color.FromArgb(153,0,0)), 0, 0, Convert.ToInt32(iMaxWidth), Convert.ToInt32(iTotalHeight));
objGraphics.FillRectangle(new SolidBrush(Color.FromArgb(153, 0, 0)), 0, 0, Convert.ToInt32(iMaxWidth), Convert.ToInt32(iMaxHeight));
//Encontrar o maior valor
int iValue = 0;
foreach(string iValor in aY)
{
if (iValor.Contains(","))
iValue = Convert.ToInt32(iValor.Remove(iValor.IndexOf(",")));
else
iValue = Convert.ToInt32(iValor);
if (iValue > iMaxColHeight)
iMaxColHeight = iValue;
}
int iBarX = iColSpace;
int iCurrentHeight;
SolidBrush objBrush = new SolidBrush(Color.FromArgb(255, 251, 214));
Font fontLegenda = new Font("Century Gothic", 9);
Font fontValores = new Font("Century Gothic", 7);
//Font fontTitle = new Font("Tahoma", 20);
//objGraphics.DrawString(titulo, fontTitle, objBrush, ((iMaxWidth / 2) - titulo.Length * 6), (iMaxHeight + iXLegendSpace));
//Corre por cada valor e desenha cada barra
int i;
for (i = 0; i <= (aX.Count - 1); i++)
{
iCurrentHeight = Convert.ToInt32(((Convert.ToDouble(aY[i]) / Convert.ToDouble(iMaxColHeight)) * Convert.ToDouble(iMaxHeight - iHeightSpace)));
objGraphics.FillRectangle(objBrush, iBarX, (iMaxHeight - iCurrentHeight), iColWidth, iCurrentHeight);
objGraphics.DrawString(aX[i].ToString(), fontLegenda, objBrush, iBarX, iMaxHeight);
objGraphics.DrawString(aY[i].ToString(), fontValores, objBrush, iBarX, (iMaxHeight - iCurrentHeight - 15));
iBarX += (iColSpace + iColWidth);
}
FileInfo fi = new FileInfo(Server.MapPath("~/inqueritos/estatisticas/") + "graph.gif");
if (fi.Exists)//Se o ficheiro existe, apaga-o
{
fi.Delete();
}
objBitmap.Save(Server.MapPath("~/inqueritos/estatisticas/") + "graph.gif", System.Drawing.Imaging.ImageFormat.Gif);
statsimg.ImageUrl="~/inqueritos/estatisticas/graph.gif";
}
Aqui fica uma imagem de um dos gráficos que gerei com esse código. Já agora também podia flexibilizar as cores do gráfico, mas não foi estritamente necessário!

Espero que vos ajude nos casos mais simples e rápidos.
?>