13 04 2016
Trabalhando com gráficos no Report Viewer
O sucesso de um sistema depende, muitas vezes, da aprovação do nível gerencial da empresa que vai utilizá-lo. Nesse nível da hierarquia empresarial, os relatórios e ferramentas de análise disponíveis no aplicativo fazem uma grande diferença. E sabe o que vai impressionar mais ainda os gerentes e diretores que possivelmente farão uso da aplicação? Gráficos. Muitos gráficos.
Não existe uma maneira mais fácil de interpretarmos dados estatísticos do que através da utilização de gráficos. Se você não está levando em consideração essa funcionalidade nos seus relatórios, você está deixando na mesa uma grande porcentagem da aprovação do seu sistema. Para te ajudar nessa empreitada, no artigo de hoje eu mostrarei como é fácil trabalharmos com gráficos no Report Viewer.
Criando o projeto de exemplo
Para demonstrar a utilização de gráficos no Report Viewer, vamos supor que você tenha um aplicativo que gerencia vendas. Nessa aplicação, em um dos módulos, você armazena as vendas feitas de cada produto, por cada vendedor, em cada área geográfica.
Vamos começar criando um projeto do tipo “Windows Forms Application“. Poderíamos criar qualquer tipo de projeto, uma vez que o Report Viewer funciona também no WPF e em aplicações web. Porém, como é mais fácil explicar com o Windows Forms, (além dessa plataforma já estar extremamente estável – diferente do MVC, por exemplo, que traz grandes mudanças a cada nova versão), escolhi demonstrar esse relatório dessa forma.
Feito isso, a fim de simplificar o nosso exemplo, vamos criar uma classe especial que trará as informações de cada venda em um só lugar (comprador, vendedor, região, produto, data e valor da venda). Chamaremos essa classe de “DadosRelatorioVenda“:
// C# public class DadosRelatorioVenda { public string NomeComprador { get; set; } public string NomeVendedor { get; set; } public string RegiaoVenda { get; set; } public string CategoriaProduto { get; set; } public DateTime DataVenda { get; set; } public double ValorVenda { get; set; } }
' VB.NET Public Class DadosRelatorioVenda Public Property NomeComprador As String Public Property NomeVendedor As String Public Property RegiaoVenda As String Public Property CategoriaProduto As String Public Property DataVenda As DateTime Public Property ValorVenda As Double End Class
Logo após a criação dessa classe, compile o projeto. Caso esqueçamos desse passo, a engine do Report Viewer não detectará a sua existência e, por consequência, não conseguiremos criar um novo relatório com ela.
Criando o relatório com gráficos
Agora que já temos a classe que servirá de fonte de dados para o nosso relatório, podemos prosseguir com a sua criação. Para isso, adicione um novo item do tipo “Report” no projeto, dando o nome de “RelatorioVenda“:
Com o relatório adicionado, clique com o botão direito na “área externa” do relatório e escolha a opção para adicionarmos um cabeçalho no relatório:
Dentro do cabeçalho, vamos adicionar um título para o relatório – “Dashboard de Vendas“:
Adicionado o cabeçalho, vamos agora adicionar uma fonte de dados para o relatório. Para isso, na janela “Report Data“, clique com o botão direito sobre “Datasets” e escolha a opção “Add Dataset“:
Na janela que se abre, escolha a opção “Object” para o tipo de fonte de dados do Dataset:
Finalmente, encontre a classe “DadosRelatorioVenda” na lista de classes do projeto e finalize o assistente:
Feito isso, chegou a hora de começarmos a criar os nossos gráficos. Para adicionarmos um novo gráfico nos nossos relatórios do Report Viewer, a primeira opção é arrastarmos esse tipo de controle da caixa de ferramentas para dentro do nosso relatório. Já a segunda opção é clicarmos com o botão direito sobre o relatório e escolhermos a opção “Insert => Chart“:
Independentemente da opção que escolhermos, ao adicionarmos um gráfico no Report Viewer, o Visual Studio nos perguntará qual o tipo de gráfico queremos criar. Veja que podemos criar inúmeros tipos de gráficos com o Report Viewer:
Vamos começar com um gráfico de pizza 3d. Para configurarmos os gráficos no Report Viewer, temos que clicar sobre eles e escolhermos as opções na smart tag “Chart Data“. Podemos configurar esse gráfico de pizza para mostrarmos, por exemplo, o total de vendas por região, escolhendo o somatório de “ValorVenda” na parte de “Valores” e a coluna “RegiaoVenda” na parte de “Grupos de Categorias“:
O título do relatório pode ser alterado clicando duas vezes sobre ele. Altere o título para “Vendas por Região“:
Algo muito comum em gráficos de pizza é a exibição de rótulos para as fatias do gráfico. Os rótulos podem ser facilmente adicionados clicando com o botão direito sobre uma das fatias do gráfico e escolhendo “Show Data Labels“:
Por padrão, o Report Viewer mostra o valor da série como rótulo (ou seja, no nosso caso, o somatório de vendas de cada região). Para alterar o valor que será exibido nas fatias, clique com o botão direito sobre um dos rótulos e escolha a opção “Series Label Properties“:
Para mostrarmos a porcentagem de vendas de cada região, podemos escolher a opção “#PERCENT“:
Ao fazermos isso, o Report Viewer perguntará se queremos alterar a propriedade “UseValueAsLabel” para false, uma vez que só é possível exibirmos a porcentagem caso essa propriedade esteja configurada como false. Dessa forma, quando o Report Viewer fizer essa pergunta, confirme o diálogo:
Feito isso, que tal deixarmos o nosso relatório mais rico adicionando mais alguns gráficos? Adicione um gráfico do tipo “funil 3D” para exibirmos as “Top categorias de produtos“:
Depois, um gráfico de linhas com marcadores para mostrarmos as “Vendas por dia“:
E, finalmente, um gráfico do tipo “colunas 3D empilhadas” para mostrarmos as vendas por Vendedores e Produtos:
Veja o layout final do relatório com todos os gráficos adicionados:
Exibindo o relatório
OK, agora que já temos o relatório com os gráficos, como é que exibimos esse relatório? Simples! Vamos até o nosso formulário, abrimos a caixa de ferramentas e arrastamos um controle do tipo “Report Viewer” para dentro do formulário. Na smart tag do controle, escolhermos o nosso relatório e “dockamos” o controle no formulário:
Em teoria, ao fazermos isso, o relatório está pronto para ser exibido. Porém, como não temos nenhum dado de vendas criado até o momento, os gráficos aparecerão vazios. Dessa forma, nessa etapa, precisamos adicionar os dados de vendas para que o relatório possua algum valor.
Normalmente, nesse momento nós carregaríamos os dados das vendas do nosso banco de dados. Porém, como não temos dados “de verdade“, vamos criar alguns dados de exemplo aleatórios. Para isso, adicione o método “GerarExemplo” na classe “DadosRelatorioVenda“:
// C# public class DadosRelatorioVenda { public string NomeComprador { get; set; } public string NomeVendedor { get; set; } public string RegiaoVenda { get; set; } public string CategoriaProduto { get; set; } public DateTime DataVenda { get; set; } public double ValorVenda { get; set; } private static Random _rand = new Random(); public static DadosRelatorioVenda GerarExemplo() { var compradores = new string[] { "Lojinha do Zé", "Mercearia da Esquina", "Tabacaria Top" }; var vendedores = new string[] { "Fulaninho de Tal", "Beltrano Vende Tudo", "João do Caminhão" }; var regioes = new string[] { "Norte", "Sul", "Leste", "Oeste", "Centro" }; var categorias = new string[] { "Doce", "Salgado", "Perecível", "Bebida" }; return new DadosRelatorioVenda() { NomeComprador = compradores[_rand.Next(3)], NomeVendedor = vendedores[_rand.Next(3)], RegiaoVenda = regioes[_rand.Next(5)], CategoriaProduto = categorias[_rand.Next(4)], DataVenda = DateTime.Now.AddDays(_rand.Next(30)), ValorVenda = _rand.Next(1000) }; } }
' VB.NET Public Class DadosRelatorioVenda Public Property NomeComprador As String Public Property NomeVendedor As String Public Property RegiaoVenda As String Public Property CategoriaProduto As String Public Property DataVenda As DateTime Public Property ValorVenda As Double Private Shared Rand As New Random() Public Shared Function GerarExemplo() As DadosRelatorioVenda Dim Compradores = New String() {"Lojinha do Zé", "Mercearia da Esquina", "Tabacaria Top"} Dim Vendedores = New String() {"Fulaninho de Tal", "Beltrano Vende Tudo", "João do Caminhão"} Dim Regioes = New String() {"Norte", "Sul", "Leste", "Oeste", "Centro"} Dim Categorias = New String() {"Doce", "Salgado", "Perecível", "Bebida"} Return New DadosRelatorioVenda() With { _ .NomeComprador = Compradores(Rand.[Next](3)), _ .NomeVendedor = Vendedores(Rand.[Next](3)), _ .RegiaoVenda = Regioes(Rand.[Next](5)), _ .CategoriaProduto = Categorias(Rand.[Next](4)), _ .DataVenda = DateTime.Now.AddDays(Rand.[Next](30)), _ .ValorVenda = Rand.[Next](1000) _ } End Function End Class
Por fim, vamos até o code-behind do nosso formulário e vamos fazer um “for” de zero até trinta adicionando dados de exemplo no nosso BindingSource:
// C# private void Form1_Load(object sender, EventArgs e) { for (int cont = 0; cont <= 30; cont++) { DadosRelatorioVendaBindingSource.Add(DadosRelatorioVenda.GerarExemplo()); } this.reportViewer1.RefreshReport(); }
' VB.NET Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load For cont As Integer = 0 To 30 DadosRelatorioVendaBindingSource.Add(DadosRelatorioVenda.GerarExemplo()) Next Me.ReportViewer1.RefreshReport() End Sub
Pronto! Execute o projeto e veja o resultado:
Concluindo
Um dos artifícios para deixarmos os nossos relatórios mais atraentes é a utilização de gráficos. Nesse artigo você conferiu como é fácil acrescentar vários tipos de gráficos nos relatórios do Report Viewer. Agora que você aprendeu como fazer, não perca essa oportunidade de impressionar os seus usuários. Ah, e depois volte aqui nos comentários e conte para gente quais foram os tipos de gráficos que você adicionou nos seus relatórios.
Antes de me despedir, convido você a inscrever-se na minha newsletter. Ao fazer isso, você receberá um e-mail toda semana sobre o artigo publicado, ficará sabendo em primeira mão sobre o artigo da próxima semana e receberá também dicas “bônus” que eu só compartilho por e-mail. Além disso, você já deve ter percebido que eu recebo muitas sugestões de temas e eu costumo dar prioridade às sugestões vindas de inscritos da minha newsletter. Inscreva-se utilizando o formulário logo abaixo.
Até a próxima!
André Lima
Image by Pixabay used under Creative Commons
https://pixabay.com/en/graph-pie-chart-business-finance-963016/
Application Insights no Windows Forms Trabalhando com o Report Viewer no WPF
Excelente artigo André. Parabéns!
Olá Paulo!
Muito obrigado! Fico feliz que você tenha gostado..
Um grande abraço!
André Lima
Olá André, tudo certo?
Parabéns pelo excelente artigo!
Obrigado por dispor do seu tempo para compartilhar seus conhecimentos!
Olá Ednilson!
Magina, acho que compartilhar nossos conhecimentos faz com que aprendamos mais ainda.. Ensinar é a melhor forma de aprender.. Obrigado pelo elogio..
Grande abraço!
André Lima
Muito top cara
Valeu Jonathas! Fico feliz que você tenha gostado!
Abraço!
André Lima
Parabéns pelo artigo, claro e objetivo!
Fiz um Report com gráfico de Pizza, mas quando os valores que são visualizados no gráfico são muito pequenos, por exemplo, 0.5% e 0.8%, as ‘labels’ aparecem sobrepostos. Já teve esse problema?
Olá Fabio, obrigado pelo comentário!
Se você estiver trabalhando com um gráfico de pizza “flat” (sem 3D), aí as labels podem acabar se sobrepondo em algumas situações mesmo.. O jeito é trabalhar com o gráfico em pizza 3D e configurar a propriedade CustomAttributes.PileLabelStyle como “Outside”.. Aí os labels serão colocados do lado de fora do gráfico sem sobreposição:
Caso você realmente não queira trabalhar com gráfico de pizza 3D, você pode ir nas propriedades do gráfico, deixar como 3D, mas, configurar a inclinação e rotação como zero graus.. O único problema nesse caso é que as cores ficarão um pouco mais claras do que o normal:
Abraço!
André Lima
Infelizmente eu não estou conseguindo achar esta opção CustomAttributes.PileLabelStyle para modificar. Onde encontro esta propriedade?
Olá Rafael!
Você tme que clicar na seção de valores e, na janela de propriedades, expandir o nó “CustomAttributes”:
Abraço!
André Lima
[…] (se não a melhor) é através de gráficos. Umas semanas atrás eu mostrei para você como trabalhar com gráficos no Report Viewer. Mas, como é que ficam as pessoas que trabalham com o Crystal Reports? Será que a criação de […]
Excelente muy bien explicado, muchas gracias por emplear tu tiempo para compartir tus conocimientos con nosotros.
Bendiciones un saludo desde Colombia.
Hola Edward! Muchas gracias!
Saludos,
André Lima
Muito obrigado por passar seu conhecimento.
Existe a possibilidade de gerar o relatório PDF na Horizontal(paisagem)A4?
Olá Everton!
Nas propriedades do relatório você consegue configurar as opções de impressão, como orientação e tamanho da página.. Essas informações são utilizadas quando você gera o PDF.. Você chegou a dar uma olhada nessas opções?
Abraço!
André Lima
Era isso mesmo André!Muito Obrigado!
Como eu inserir uma imagem do tamanho A4(paisagem) no relatório, quando eu clicava aparecia somente a Propriedade da imagem, depois de um tempo eu percebi que tinha que clicar no espaço preto entre a imagem e a janela, ai apareceu a propriedade do Report onde consegui fazer as alterações.
Olá Everton!
Maravilha! Que bom que você conseguiu resolver o problema.. Qualquer outra dificuldade, entre em contato novamente..
Abraço!
André Lima
Bom dia Muito boa sua explicação, uma pergunta estou criando um grafico com o eixo X com as datas de pagto, gostaria de saber pq aparece as datas que não estao no Banco de dados. EX: pagto dia 06/11/2016 e 28/11/2016 – aparece varias datas que nao esta no bd
Olá Ivair, obrigado pelo comentário!
Não consegui entender direito o que está acontecendo no seu relatório.. Será que você poderia me mandar uns screenshots da aplicação em execução e dos dados que estão sendo utilizados para alimentar o relatório? O meu e-mail é: contato [arroba] andrealveslima [ponto] com [ponto] br..
Abraço!
André Lima
Olá!
Como eu poderia proceder para exibir em um gráfico os valores que estão em um determinado textBox?
Olá Elisangela, obrigado pelo comentário!
Você poderia explicar melhor? Como assim exibir os valores de um TextBox em um gráfico? Normalmente gráficos possuem múltiplos valores.. Que valores você tem nesse TextBox e qual tipo de gráfico exatamente você está querendo construir?
Abraço!
André Lima
Estou desenvolvendo um sistema supervisório que tem como intuito apresentar ao usuário dados de um sistema embarcado. Estes dados são recebidos pela porta serial e apresentados em tempo real em diferentes textBox. Por exemplo, um dado de temperatura é exibido no seu respectivo textBox e atualizado a cada 5 segundos. No entanto, gostaria de elaborar um relatório de dados com gráficos que apresentam o comportamento da variável de interesse ao longo do dia (como por exemplo, o comportamento da temperatura naquele dia) para que o usuário possa visualizar/salvar este tipo de informação. Desta forma, necessito que este gráfico seja capaz de “buscar” o valor que está sendo apresentado no textBox e usá-lo como o valor a ser exibido na série. Você acha que isso é possível?
Olá Elisangela!
Agora entendi.. Acredito que seja possível.. Porém, você terá que armazenar em algum lugar esses valores que forem sendo lidos ao longo do dia (em um banco de dados, por exemplo).. Você ainda não está armazenando esses valores em lugar nenhum? Se você ainda não tem um banco de dados para a sua aplicação, recomendo que você crie um bem simples (utilizando SQLite, por exemplo, como eu ensinei neste artigo) para armazenar essas informações.. Aí o relatório não tem segredo.. Você só terá que ler os dados do banco e exibir no gráfico..
Conseguiu entender a ideia? Se ficar com alguma dúvida específica nesse processo, me avisa que eu tento te explicar de outra maneira ou te mando materiais que possam te ajudar com um tópico específico que você esteja tendo dificuldade..
Abraço!
André Lima
Obrigada pela dica André!
Abraço!
Magina Elisangela! Qualquer dificuldade no processo é só entrar em contato novamente..
Abraço!
André Lima
Olá Elisangela!
Conseguiu evoluir aí com essa questão do gráfico?
Abraço!
André Lima
Qual arquivo devo distribuir junto com o executável para visualizar os gráficos?
Olá Claudio!
Para a listagem das dlls necessárias no deployment de aplicações que utilizam o Report Viewer, confira este outro artigo:
Como distribuir aplicações com o Report Viewer?
Abraço!
André Lima
Bom dia, estou com um problema na montagem de um relatório que contém gráficos e matriz.
Aparentemente a matriz distorce a posição dos outros componentes no layout no momento da impressão. (vide imagens abaixo)
Como as inserir as imagens aqui?
Consegui resolver, bastou colocar os outros componentes dentro de um box retângulo.
Maravilha, Thiago! Que bom que você conseguiu resolver.. De vez em quando é necessário fazer essa gambi de colocar os controles dentro de um Rectangle no Report Viewer mesmo..
Abraço!
André Lima
Boa tarde Jovem
Estou fazendo uma aplicação que msotra valores analogicos em graficos sparklines, os dados estão armazenados em um BD, gostaria de saber como faço para o usuario escolher os dados a serem mostrados em um unico relatorio, por exemplo, eu crio uma 5 checkbox, Temp1, Temp2, Temp3, Temp4 e Temp5, e o usuario quer geram um grafico apenas com as Temp2 e Temp3 para comparar elas…como faço?/
Olá Eduardo!
Sinceramente não consegui entender o que você está querendo fazer.. Será que você poderia mandar mais detalhes? De preferência utilizando screenshots com maiores explicações.. Se preferir, pode me enviar por e-mail: contato [arroba] andrealveslima [ponto] com [ponto] br..
Abraço!
André Lima
Olá André!
Meu “chart bar” funcionou, porem quando tenho muitos itens queria que o gráfico expandisse conforme quantidade de itens. Igual uma tabela que se expande as linhas conforme quantidade de itens.
Existe alguma propriedade que faça essa função dinamicamente?
Agradeço desde já
Olá Mario!
Como assim “expandir conforme a quantidade de itens”? Você quer dizer o tamanho do controle do gráfico? Caso seja isso, como é que ficaria na hora da impressão? O gráfico não caberia na página..
Você poderia explicar melhor o que você está querendo fazer? De preferência com screenshots..
Abraço!
André Lima
Em um gráfico de colunas horizontais por exemplo quando tenho 6 colunas o ele fica perfeito porem se o gráfico tiver 50 itens o ele não expande verticalmente assim o mesmo fica todo desconfigurado. Enviei algumas imagens no seu email.
Agradeço desde já.
Olá Mario!
Você pode resolver isso com as propriedades “DynamicHeight” e “DynamicWidth” do gráfico.. Veja se este artigo te ajuda:
Charts with Dynamic Height or Width based on Categories/Data
Abraço!
André Lima
Olá André!
Funcionou perfeitamente, porem surgiu outra questão, os labels do axis properties aparecem apenas em coluna sim e outra não. Preciso que todas as colunas tenha a identificação.
Se puder me ajudar agradeço desde já.
Olá Mario!
Respondi a dúvida lá no e-mail que você me mandou.. O que você deve fazer é ir nas propriedades do eixo (botão direito, XX Axis Properties) e alterar o Interval em Axis Range and interval para “1”..
Abraço!
André Lima
Olá André!
Tenho alguns gráficos de Linha onde tenho aclives e declives. Porem o chart parece estar ordenando alfabeticamente os valores tornando uma linha crescente mesmo tendo varias no meio do caminho.
EX 1, 10, 3, 7 (seria um grafico zigzag) e ele esta ordenado os dados fazendo ficar 1, 3, 7, 10 (grafico crescente).
Tem alguma idéia do que pode ser.
Agradeço desde já
Olá Mario!
As séries dos gráficos têm a opção de ordenação.. Você já não deu uma olhada lá para ver se a ordenação não está sendo feita da maneira crescente? Se nenhuma ordenação estiver configurada, os dados deveriam ser exibidos no gráfico utilizando a mesma ordem em que eles se encontram no Data Source..
Abraço!
André Lima
ok. perfeito André