ASP .NET MVC 3 - Usando o HTML Chart Helper


Se você precisa ou pretende exibir os seus dados em um formato gráfico em aplicações ASP .NET pode utilizar os recursos do componente Html Chart Helper.

O Html Chart Helper pode renderizar imagens que exibem os dados em uma variedade de tipos de gráficos dando suporte a muitos opções de formatação. O componente pode renderizar mais de 30 tipos de gráficos, incluindo os formatos mais familiares já existentes em ferramentas como o Microsoft Excel como: gráficos de barra, de área, de pizza, de linha, etc.

Além disso o componente possui recursos para exibir nos gráficos outros elementos como legendas, eixos, séries, etc. Os dados exibidos nos gráficos podem vir de diversas fontes como : arrays, arquivos XML, banco de dados, arquivos texto, etc.

Neste artigo eu vou apresentar o componente e mostrar como usar os seus recursos básicos em aplicações ASP .NET MVC.

Eu vou usar o Visual Web Developer 2010 Express Edition em todos os exemplos usados neste artigo.

Criando o projeto MVC

Vamos criar um novo projeto usando o Visual Web Developer 2010 Express Edition.

No menu File -> New Project selecione/informe :

A seguir selecione o template Internet Application e o View Engine Razor e clique em OK;

Na janela solution explorer veremos a estrutura do projeto criado que iremos usar para criar nossos gráficos:

Criando um gráfico com dados

Vamos iniciar criando um gráfico de barras bem simples e para isso vamos usar o arquivo About.cshtml da pasta Views->Home alterando o seu código para:

@{
    ViewBag.Title = "Usando Chart Helper";
}
<h2>About</h2>
<p>
     @{
    var macChart = new Chart(width: 600, height: 400)
           .AddTitle("Campeonato Paulista - 2012")
           .AddSeries(
            name: "CampeonatoPaulista",
            xValue: new[] {  "São Paulo", "Corinthians", "Palmeiras", "Santos", "Mogi Mirim" },
            yValues: new[] { "34", "34", "32", "30", "30" })
        .Write();
}
</p>
About.cshtml

O código acima mostra como é simples criar um gráfico para isso basta criar uma instância da classe Chart e definir as dimensões do gráfico :

ar macChart = new Chart(width: 600, height: 400)

A seguir usamos os métodos da classe Chart :

Para exibir o gráfico no navegador usamos o método Write(): Ex: Write() ou Write(format : "gif")

Altere também o arquivo _Layout.cshtml para exibir o texto Gráfico no menu About:

.....
<div id="menucontainer">
  <ul id="menu">
   <li>@Html.ActionLink("Home", "Index", "Home")</li>
   <li>@Html.ActionLink("Gráfico", "About", "Home")</li>
 </ul>
</div>
....
_Layout.cshtml

Agora já podemos executar o projeto de onde iremos obter:

Observe o menu Gráfico que quando clicado irá executar a Action About que irá acionar a view About.cshtml onde incluímos o código para gerar o gráfico que será exibido ao usuário.

Muito simples, não é mesmo ?

Vamos melhorar um pouco o nosso exemplo e mostrar também como alterar o tipo de gráfico gerado.

Do jeito que esta estamos exibindo o gráfico diretamente a partir da View About.cshtml vamos criar uma Action no controller HomeController para renderizar o gráfico e aproveitar para alterar o tipo do gráfico para pie (gráfico de pizza)

Abra o arquivo HomeController.cs da pasta Controllers e altere o seu código conforme abaixo:

using System.Web.Mvc;
using System.Web.Helpers;

namespace UsandoChartHelper.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Usando Chart Helper";
            return View();
        }

        public ActionResult About()
        {
            return View();
        }

        public ActionResult getGrafico()
        {
            var myChart = new Chart(width: 600, height: 400)
           .AddTitle("Campeonato Paulista - 2012")
           .AddSeries(
               name: "CampeonatoPaulista",
            
  chartType: "Pie",
               legend : "Campeonato Paulista",

               xValue: new[] { "São Paulo", "Corinthians", "Palmeiras", "Santos", "Mogi Mirim" },
               yValues: new[] { "34", "34", "32", "30", "30" })
           .Write();

            return null;
        }
    }
}

Agora vamos criar uma View para exibir o gráfico.

Clique com o botão direito sobre a Action getGrafico() e selecione a opção Add View e infrme o nome getGrafico e clique no botão Add;

A seguir inclua o código abaixo no arquivo getGrafico.cshtml que será criado na pasta Views->Home:

@{
    ViewBag.Title = "getGrafico";
}

<h2>getGrafico</h2>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Index</title>
</head>
<body>
      <h1>Usando Chart Help</h1>
   <div>
           
<img src="/Home/getGrafico" />
    </div>
</body>

</html>

Altere também o arquivo _Layout.cshtml para exibir o texto Gráfico no menu About:

.....
<div id="menucontainer">
  <ul id="menu">
   <li>@Html.ActionLink("Home", "Index", "Home")</li>
   <li>@Html.ActionLink("Gráfico", "getGrafico", "Home")</li>
 </ul>
</div>
....

Agora é só alegria...

Execute o projeto e clique no menu Gráfico, isso irá acionar a Action getGrafico e a respectiva view. O resultado pode ser visto nas figuras abaixo:

Muito bem !!!

Podemos também exibir a imagem resultante em outra página. Para exibir a imagem você pode usar um elemento img HTML, da mesma forma que você faria para exibir qualquer imagem. No entanto, em vez de fazer referência a um arquivo .jpg ou .png, o elemento <img> referencia o arquivo .cshtml que contém o chart helper que cria o gráfico. Quando a página de exibição for executada, o elemento <img> obtém a saída do chart helper e processa o gráfico.

No exemplo acima para obter este resultado faríamos assim:

1 - Altere o conteúdo do arquivo getGrafico.cshtml conforme abaixo:


@{
    ViewBag.Title = "getGrafico";
}

<h2>getGrafico</h2>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Index</title>
</head>
<body>
      <h1>Test Chart</h1>
   <div>
            <img src="About.cshtml" />
    </div>
</body>

</html> 

Neste arquivo a tag : <img src="About.cshtml" /> aproveita o conteúdo do arquivo About.cshtml (que usamos no início do artigo para exibir o gráfico) e exibe a imagem do gráfico.

Mas e seu eu quiser obter dados de um fonte de dados como um banco de dados ?

Nestes casos podemos usar o método DataBindingTable que aceita qualquer valor que retorna um objeto IEnumerable.

Vamos então, usando o exemplo acima, definir um Model em nossa aplicação para acessar o banco de dados Northwind.mdf e acessar os dados da tabela Products, exibindo o nome e preço de 5 produtos em um gráfico. Para isso vamos criar duas classes na pasta Models:

  1. Produtos.cs - representa o nosso domínio que é o produto;
  2. ProdutosModel.cs - Realiza o acesso a tabela Products e retorna uma lista de 5 produtos;

Clique com o botão direito sobre a pasta Models e selecione Add Class informando o nome Produtos.cs e a seguir defina o seguinte código neste arquivo:

namespace UsandoChartHelper.Models
{
    public class Produtos
    {
        public object ProductName { get; set; }
        public object UnitPrice { get; set; }
    }
}

A seguir repeita o procedimento e crie a classe ProdutosModel na mesma pasta e defina o código abaixo neste arquivo:

Obs: Você deve incluir uma referência no projeto ao namespace System.Web.Configuration para poder usar a classe WebConfigurationManager para acessar a string de conexão do arquivo web.config;

Outra providência que deveremos tomar é incluir a string de conexão no arquivo Web.Config Incluindo na seção <connectionStrings> a linha abaixo:

<add name="conexaoNorthwind" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True" />

Código do arquivo ProdutosModel:

using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Web.Configuration;

namespace UsandoChartHelper.Models
{
    public class ProdutosModel
    {
        public IList<Produtos> getProdutos()
        {
            string constr = WebConfigurationManager.ConnectionStrings["conexaoNorthwind"].ConnectionString;
          
 string sqlstr = "Select top 5 ProductName, UnitPrice from Products";
            SqlDataReader sqldr = null;
            SqlCommand sqlcmd = null;
            List<Produtos> listaProdutos = null;

            listaProdutos = new List<Produtos>();
            using (SqlConnection sqlcon = new SqlConnection(constr))
            {
                sqlcmd = new SqlCommand(sqlstr, sqlcon);
                sqlcon.Open();
                sqldr = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection);
                while ((sqldr.Read()))
                {
                    Produtos produto = new Produtos();
                
   produto.ProductName = sqldr.GetString(0).ToString();
                    produto.UnitPrice = sqldr.GetDecimal(1);

                    listaProdutos.Add(produto);
                }
            }
            return listaProdutos;
        }
    }
}

Vamos agora abrir o arquivo HomeController na pasta Controllers e definir uma Action getGraficoDB que obtém a lista de produtos e gera o gráfico conforme o código abaixo:

using System.Web.Mvc;
using System.Web.Helpers;
using UsandoChartHelper.Models;

namespace UsandoChartHelper.Controllers
{
    public class HomeController : Controller
    {
      
 public ActionResult Index()
        {
            ViewBag.Message = "Usando Chart Helper";
            return View();
        }

        public ActionResult About()
        {
            return View();
        }


   
    public ActionResult getGrafico()
        {
            var myChart = new Chart(width: 600, height: 400)
           .AddTitle("Campeonato Paulista - 2012")
           .AddSeries(
               name: "CampeonatoPaulista",
               chartType: "Pie",
               legend : "Campeonato Paulista",
               xValue: new[] { "São Paulo", "Corinthians", "Palmeiras", "Santos", "Mogi Mirim" },
               yValues: new[] { "34", "34", "32", "30", "30" })
           .Write();

            return null;
        }


        public ActionResult getGraficoDB()
        {
            ProdutosModel produtosDB = new ProdutosModel();
            var produtos = produtosDB.getProdutos();

            var myChart = new Chart(width: 600, height: 400, theme: ChartTheme.Yellow )
             .AddTitle("Os 5 Produtos Vendidos")
         
   .DataBindTable(dataSource: produtos, xField: "ProductName")
             .Write();

            return null;
        }

    }
}

A action getGraficoDB() cria uma instância da classe ProdutosModel() e usando o método getProdutos().

Note a utilização do método DataBindTable onde definimos a fonte de dados através da propriedade datasource e o campo que iremos usar no eixo x que é o nome do produto;

Obs: O método DataBindTable cria e vincula os dados da série com a tabela de dados especificada e, opcionalmente, preenche vários valores de x.

Agora para criar a nossa view clique com o botão direito sobre o método getGraficoDB e selecione Add View e na janela Add View aceite o nome getGraficoDB e clique no botão Add;

A seguir defina o código abaixo no arquivo getGraficoDB.cshtml gerado na pasta Views->Home:

@{
    ViewBag.Title = "getGraficoDB";
}
<h2>getGraficoDB</h2>

<h2>getGrafico</h2>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Index</title>
</head>
<body>
      <h1>Testando Chart Helper</h1>
   <div>
        <img src="/Home/getGraficoDB" />
    </div>
</body>
</html>

Na view estamos usando a tag <img> para chamar a action getGraficoDB que acionará a view getGraficoDB.cshtml exibindo a imagem.

Obs: Para poder exibir o menu com todas as opções da figura temos que alterar o arquivo incluindo os ActionLinks conforme código abaixo:

.....
<div id="menucontainer">
    <ul id="menu">
      <li>@Html.ActionLink("Home", "Index", "Home")</li>
      <li>@Html.ActionLink("Gráfico", "GetGrafico", "Home")</li>
      <li>@Html.ActionLink("Gráfico DB", "GetGraficoDB", "Home")</li>
      <li>@Html.ActionLink("About", "About", "Home")</li>
    </ul>
</div>
.....

Executando o projeto iremos obter:

Se você quiser salvar o gráfico gerado basta usar o méto Save(). No exemplo acima vamos fazer isso alterando o código da Action getGraficoDB do arquivo HomeController.cs para:

     public ActionResult getGraficoDB()
        {
            ProdutosModel produtosDB = new ProdutosModel();
            var produtos = produtosDB.getProdutos();

            var myChart = new Chart(width: 600, height: 400, theme: ChartTheme.Yellow )
             .AddTitle("Os 5 Produtos Vendidos")
             .DataBindTable(dataSource: produtos, xField: "ProductName")
             .Save(@"c:\dados\graficoDB_Macoratti.jpg")
             .Write();

            return null;
        }

Este código irá salvar o gráfico na pasta c:\dados com o nome graficoDB_Macoratti.jpg.

Outra opção é salvar o gráfico como um documento XML usando o método SaveXml(). Para realizar esta tarefa o código ficaria assim:

       public ActionResult getGraficoDB()
        {
            var arquivoXML = "/graficoDB.xml";
            ProdutosModel produtosDB = new ProdutosModel();
            var produtos = produtosDB.getProdutos();

            var myChart = new Chart(width: 600, height: 400, theme: ChartTheme.Yellow )
             .AddTitle("Os 5 Produtos Vendidos")
             .DataBindTable(dataSource: produtos, xField: "ProductName")
             .SaveXml(path:Server.MapPath(arquivoXML))
             .Write();

            return null;
        }

Executando o projeto veremos que foi salvo o arquivo graficoDB.xml na raiz do projeto onde abaixo vemos o seu conteúdo:

O componente Chart Helper é muito valioso e ainda existem outros recursos do componente mas eu vou parando por aqui.

Pegue o projeto completo aqui: UsandoChartHelper.zip

Gál 3:13 Cristo nos resgatou da maldição da lei, fazendo-se maldição por nós; porque está escrito: Maldito todo aquele que for pendurado no madeiro;
Gál 3:14
para que aos gentios viesse a bênção de Abraão em Jesus Cristo, a fim de que nós recebêssemos pela fé a promessa do Espírito.

Referências:


José Carlos Macoratti