Aproveite melhor os gráficos do SQL Server Reporting Services

Robert M. Bruckner

Publicado em: 10 de novembro de 2006

Aplica-se a:

  • Microsoft SQL Server 2005 Reporting Services

Resumo: Este white paper apresenta informações gerais, práticas recomendadas e dicas para criar gráficos nos relatórios do Microsoft SQL Server Reporting Services. Ele dá uma visão geral de alguns dos recursos do Reporting Services, responde questões comuns sobre design e recursos de gráficos e contém exemplos avançados de como criar gráficos melhores. (32 páginas impressas)

Clique aqui para fazer o download do código de exemplo associado: GetMoreChartsSamples.exe.

Clique aqui para fazer o download da versão deste artigo para Word: MoreSSRSCharts.doc.

Nesta página

Introdução Introdução
Preparação dos dados Preparação dos dados
Rótulos de gráficos Rótulos de gráficos
Exemplos de gráficos e relatórios Exemplos de gráficos e relatórios
Conclusão Conclusão

Introdução

Este white paper aborda como criar gráficos nos relatórios do Microsoft SQL Server Reporting Services. O artigo está dividido em várias seções e menciona exemplos de relatório específicos; eles se encontram no download do projeto de exemplo.

A primeira seção, Preparação dos dados, compreende informações específicas, dicas e idéias sobre a preparação dos dados. A segunda seção, Rótulos de gráficos, explica como aplicar configurações de rótulo para aprimorar seus gráficos e controlar a aparência e os efeitos visuais.

Exemplos de gráficos e relatórios contêm exemplos específicos e, às vezes, avançados de como aproveitar melhor a funcionalidade de gráficos interna do SQL Server Reporting Services. Alguns desses exemplos pedem um estudo cuidadoso das instruções passo a passo fornecidas. Foram incluídos, para sua conveniência, relatórios de exemplo totalmente funcionais. Os relatórios de exemplo se baseiam nos bancos de dados de exemplo Adventure Works, do SQL Server 2005, e Northwind.

As informações sobre preparação de dados e rótulos de gráficos lhe ajudarão a compreender melhor os exemplos. Pode ser útil, ocasionalmente, voltar aos tópicos específicos de rótulos de gráfico abordados nas primeiras seções ao estudar os exemplos.

Preparação dos dados

Um gráfico é uma forma de visualizar dados. Ele pode transmitir, com mais eficácia, informações que poderiam se estender por listas e listas de dados. Reservar um tempo para preparar os dados com cuidado e compreendê-los antes de criar um gráfico o ajudará a criar seus gráficos de modo rápido e eficiente. Os dados de gráficos do Reporting Services são organizados em três áreas: valores, grupos de categorias e grupos de séries. Para obter informações detalhadas, consulte Working with Chart Data Regions) (em inglês) na seção SQL Service Reporting Services 2005 Books Online.

Um gráfico é bastante similar a uma matriz:

  • Um grupo de categorias em um gráfico equivale a um grupo de colunas em uma matriz.

  • Um grupo de séries em um gráfico equivale a um grupo de linhas em uma matriz.

  • Um valor em um gráfico equivale a um grupo de linhas estáticas em uma matriz.

  • Um valor de dados, ou ponto de dados, em um gráfico equivale a uma célula em uma matriz.

Tenha em mente os seguintes pontos ao preparar a consulta de dataset para um gráfico:

  • Os valores do gráfico são mostrados ao longo do eixo y numérico. Certifique-se de que os campos usados como valores tenham tipos de dados numéricos (ao contrário de cadeias de caracteres, que contêm números formatados).

  • Os valores do eixo x são determinados com base nos valores de grupos de categorias do gráfico ou dos rótulos dos grupos, se estes estiverem definidos explicitamente. O eixo x aceita dois modos (discutidos detalhadamente em Modo categoria e modo escalar do eixo x). Se desejar usar o modo escalar do eixo x, certifique-se de que os campos e/ou expressões usados para a avaliação da expressão do grupo de categorias sejam de tipo de dados numéricos ou um objeto DateTime.

  • Você pode ter quantos gráficos necessitar em seu relatório. Um gráfico, como qualquer outra região de dados, como uma matriz ou tabela, está ligado a um determinado dataset. É possível usar junções e uniões na consulta de dataset para incluir todos os dados necessários no dataset.

  • Se um gráfico for colocado em um cabeçalho ou rodapé de um grupo de tabelas ou em uma célula de matriz, os dados transmitidos ao controle do gráfico estarão restritos ao subconjunto de dados que constituem esse grupo. Um gráfico não pode ser colocado na linha de detalhe de uma tabela, já que apenas uma linha de dados é mencionada.

  • Um gráfico com dados demais (por exemplo, vários milhares de pontos de dados) pode ser difícil de interpretar, a menos que você use um gráfico de dispersão para mostrar a distribuição dos valores e os clusters de pontos de dados. Considere pré-agregar os dados na consulta de dataset, caso não seja necessário, ou útil, um nível detalhado de granularidade de dados.

Rótulos de gráficos

Esta seção aborda os tópicos sobre rótulos de gráficos a seguir. Pode ser útil, ocasionalmente, voltar aos tópicos abordados nesta seção ao estudar os exemplos da seção seguinte.

  • Modo categoria e modo escalar do eixo x

    Esta seção explica as diferenças significativas entre os dois modos do eixo x. Você pode usar o relatório de exemplo CategoryAxisSettings como ponto de partida para seus experimentos.

  • Rótulos de eixo

    A seção rótulos de eixo examina profundamente os detalhes da aplicação de configurações de rótulo e seu impacto na aparência visual do gráfico em tempo de execução.

  • Rótulos de pontos de dados e rótulos de legendas

    Esta seção demonstra como melhorar seus gráficos adicionando rótulos de pontos de dados e rótulos de legendas.

Modo categoria e modo escalar do eixo x

O eixo x tem dois modos. O modo é definido por meio da opção Numeric or time-scale values (Valores numéricos ou de escala de tempo) na guia X Axis (Eixo X) da caixa de diálogo Chart Properties (Propriedades do Gráfico).

  • Modo categoria

    Os valores de expressão de grupo de categorias determinam as categorias individuais do eixo x. São exibidos os rótulos apenas das categorias reais presentes nos dados. A ordem de classificação dentro de um grupo e as expressões de classificação explícitas são importantes no modo categoria, já que o controle do gráfico não reordenará as categorias. O código de formato definido para o eixo x será aplicado somente se a expressão do grupo (ou a expressão do rótulo do grupo, caso explicitamente definida) for avaliada como um objeto que não seja uma cadeia de caracteres.

    As distribuições de agrupamentos serão exibidas para as categorias, se houver vários níveis de agrupamentos de categorias.

  • Modo escalar

    O intervalo de valores do eixo x é determinado pelos valores mínimo e máximo da expressão de grupo de categorias. Por conseqüência, os valores da expressão de grupo devem ser numéricos ou de DateTime, para efeito de comparação e classificação. As lacunas nos dados (por exemplo, usar um agrupamento de categorias do tipo DateTime e ter dados somente para julho e setembro) são exibidas no eixo x, já que as categorias são escaladas para um eixo numérico ou de DateTime. Apenas um agrupamento de categorias é permitido no modo escalar.

Os gráficos das Figuras 1A e 2A mostram as mesmas quatro semanas de dados de pedidos.

Figura 1A. Eixo x no modo categoria e distribuições de agrupamentos

Figura 2A. Eixo x no modo escalar

O modo categoria do eixo na Figura 1A

Uma vez que não há dados de pedido nos dias de final de semana (sábado e domingo) no dataset subjacente, as categorias não estão presentes na Figura 1A. O exemplo usa dois agrupamentos de categorias, como mostra a Figura 1B. A expressão do grupo interno usa

=Day(Fields!OrderDate.Value)

para agrupar por dia. A expressão do outro grupo usa FakePre-dcfdaddb2f5e438481930a6adacda5e1-ac965743923f451c8e8fb8ce0ebf5a8d para agrupar por mês.

Observação   A expressão de rótulo do grupo externo está definida como

=MonthName(Month(Fields!OrderDate.Value))

, o que faz com que o nome do mês seja usado como rótulo para a distribuição de agrupamentos.

Clique aqui para ver a imagem ampliada

Figura 1B. Eixo x no modo categoria com vários agrupamentos de categorias e distribuições (clique na imagem para ampliá-la)

As configurações das propriedades do eixo x são mostradas na Figura 1C. No modo categoria, a semântica de mínimo, máximo e intervalos se baseia no índice de categorias. Não especificar nenhuma propriedade de eixo explícita faz com que um rótulo seja mostrado para cada categoria de dados.

Clique aqui para ver a imagem ampliada

Figura 1C. Configurações do modo categoria do eixo x (clique na imagem para ampliá-la)

O modo escalar do eixo na Figura 2A

Um eixo x no modo escalar mostra valores numéricos ou de DateTime. O eixo x cobre o intervalo completo de valores entre o mínimo e o máximo. Conseqüentemente, a Figura 2A contém lacunas para os dias de final de semana, pois eles não têm dados de pedido.

Apenas um agrupamento de categorias é permitido quando se usa o eixo x no modo escalar. O valor do agrupamento de categorias deve ser avaliado como um valor numérico ou de DateTime. A formatação dos rótulos do eixo x é determinada pela configuração da cadeia de caracteres de formato no eixo x; neste exemplo, MMM dd. As configurações das propriedades do eixo x são mostradas na Figura 2B.

Clique aqui para ver a imagem ampliada

Figura 2B. Configurações do modo escalar do eixo x (clique na imagem para ampliá-la)

Para obter mais informações sobre cadeias de caracteres de formato DateTime, consulte as seguintes páginas no Guia do Desenvolvedor do .NET Framework na Microsoft Developer Network (MSDN):

Rótulos de eixo

Os rótulos do eixo y se baseiam sempre em valores numéricos. Se não forem especificadas configurações de eixo explícitas, o eixo y usará o modo de escala automática, da seguinte maneira:

  • O valor mínimo do eixo y é determinado com base no valor y mais baixo de todos os pontos de dados. Se esse valor mínimo não for um valor inteiro, mas duplo (como 3,75), e as margens laterais estiverem desativadas, poderão ser gerados rótulos de eixo y sem arredondamento para números inteiros (por exemplo, com um intervalo de um: 3,75, 4,75, 5,75 e assim por diante).

  • O valor máximo do eixo y é determinado automaticamente, com base no valor y mais alto de todos os pontos de dados, a menos que esteja explicitamente especificado.

  • O intervalo maior do eixo y é determinado automaticamente, com base nos valores dos dados (na Figura 3, o intervalo maior automático é 20).

  • O intervalo menor do eixo y divide o intervalo maior em dois segmentos (na Figura 3, o intervalo menor automático seria 4; daí que 20/4 = 5 segmentos de intervalo menor constituem um segmento do intervalo maior).

  • Uma vez que os valores do eixo y são sempre numéricos, é possível aplicar diretamente cadeias de caracteres de formato numérico. A configuração é aplicada a todos os rótulos de eixo y gerados.

Clique aqui para ver a imagem ampliada

Figura 3. Configurações do eixo y (clique na imagem para ampliá-la)

Modo do eixo x

Conforme discutimos na seção anterior, o eixo x tem vários modos. Dependendo do modo, opções diferentes de formatação são disponibilizadas e as configurações do eixo (Minimum, Maximum, Cross at e assim por diante) podem ser interpretadas diversamente. A seguir, apresentamos descrições das diferentes opções de formatação:

  • Modo escalar baseado em valores numéricos de grupo de categorias

    Com estas configurações, o eixo x torna-se muito similar ao eixo y. Configurações de eixo, como Minimum (Mínimo), Maximum (Máximo), Cross at (Cruzar em), Major interval (Intervalo maior) e Minor interval (Intervalo menor) são interpretados como valores inteiros ou duplos.

    Uma vez que os valores do eixo x são numéricos, é possível aplicar diretamente cadeias de caracteres de formato numérico.

  • Modo escalar baseado em valores DateTime de grupo de categorias

    Minimumdo eixo: Se o mínimo do eixo for definido como uma constante (como 2005) ou uma expressão com um resultado inteiro (por exemplo, =2005), o valor será interpretado como o primeiro dia daquele ano (como 1ojan, 2005).

    Maximum do eixo: A configuração de um inteiro é interpretada como o último dia daquele ano (como 31 dez, 2005).

    Cross at do eixo: A configuração é interpretada como o meio do ano.

    Major interval e Minor interval: As configurações de intervalo são interpretadas como dias (equivalente ao formato OADate). Por exemplo, 5 significa um intervalo de 5 dias e 0,5 significa um intervalo de metade de um dia (12 horas).

    Para a formatação de rótulos, é possível aplicar diretamente cadeias de caracteres de formato DateTime padrão.

  • Modo categoria (a opção “Numeric or time-scale values” não está selecionada)

    Com base nos valores de expressão de grupos de categorias, o controle do gráfico faz a correspondências das categorias nas várias séries (por exemplo, dados da categoria janeiro na série 2006 estarão no mesmo cluster que os dados da categoria janeiro da série 2007).

    As configurações de cadeias de caracteres de formato na guia X Axis não terão efeito a menos que a expressão de grupo de categorias (ou expressão de rótulo, como na Figura 4) seja avaliada como tipo de dados numérico ou de DateTime. Muitas vezes, quando você usa o modo categoria, a expressão de grupo de categorias é avaliada como um objeto de cadeia de caracteres e, por isso, um código de formato aplicado posteriormente não tem efeito. Você pode adicionar ou alterar a expressão de rótulo de grupo de categorias ou aplicar a formatação diretamente, através da expressão de rótulo, como mostrado na Figura 4.

    Observação   No modo categoria, a semântica de mínimo, máximo e intervalos se baseia no índice de categorias. Por exemplo, definir o mínimo do eixo x como 2 significa que a primeira categoria de dados não será exibida. Definir o intervalo maior como 5 significa que serão exibidos rótulos somente para cada quinta categoria do eixo x. Isso poderá ser útil se o eixo x estiver lotado com muitas categorias (e rótulos) e a semântica subjacente das categorias for, na verdade, numérica.

    Observação   O Reporting Services 2005 também permite expressões em todos os campos de entrada exibidos nas guias X Axis (Eixo X) e Y Axis (Eixo Y): Title (Título), Minimum (Mínimo), Maximum (Máximo), Major interval (Intervalo maior), Minor interval (Intervalo menor) e assim por diante.

Figura 4. Se a expressão de rótulo estiver explicitamente definida, o resultado será exibido no eixo x (eixo categoria), em vez do resultado da expressão de grupo.

P&R sobre formatação de rótulo de eixo

  • Pergunta (eixo Y): Como posso impor "bons" rótulos baseados em inteiros no eixo y?

    Resposta: Se nenhuma configuração de eixo estiver especificada, o controle do gráfico determinará automaticamente os valores, com base nos valores y dos pontos de dados. Se os valores mínimo/máximo dos pontos de dados não forem inteiros, pode ser que os rótulos do eixo y usem valores duplos.

    Se, todavia, pelo menos uma das configurações do eixo (por exemplo, Minimum ou Cross at) estiver explicitamente especificada como um valor inteiro pelo autor do relatório, o controle do gráfico arredondará automaticamente os valores detectados para o valor inteiro mais próximo e, em seguida, exibirá rótulos "bons". Por exemplo, você poderia definir dinamicamente o valor mínimo do eixo y e aplicar um arredondamento tal como:

    =Floor(Min(Fields!Freight.Value))

.

  • Pergunta (eixo x escalar): Ativar Numeric or time-scale values (Valores numéricos ou de escala de tempo) está resultando em um gráfico que não exibe nenhum ponto de dados em tempo de execução. O que está errado?

    Resposta: Muito provavelmente, a expressão de grupo de categorias está sendo avaliada como uma cadeia de caracteres, em vez de valores numéricos. Altere a expressão do grupo de categorias apropriadamente. Caso não queira alterar a consulta para buscar valores de dados escalares, em vez de valores de cadeias de caracteres, você também poderá executar a conversão de tipo no relatório, usando funções do Microsoft Visual Basic tais como CInt(), CDbl() ou CDate().

  • Pergunta (eixo x no modo categoria): Se o número de categorias aumenta, o eixo x fica lotado e, eventualmente, não são mais obtidos rótulos de eixo. Como posso controlar o número de rótulos no modo categoria do eixo x?

    Resposta: O controle do gráfico tenta posicionar automaticamente os rótulos do eixo x, para evitar sobreposições de textos dos rótulos. Por padrão, cada categoria tem um rótulo no eixo x. É possível definir explicitamente a configuração de intervalo maior do eixo x para que esse comportamento padrão seja desconsiderado. Por exemplo, definir o intervalo maior como 5 faz com que sejam exibidos rótulos somente para cada quinta categoria.

  • Pergunta (eixo X): Como funciona o posicionamento automático de rótulos do eixo x?

    Resposta: Atualmente, os gráficos internos do Reporting Services permitem posicionamento automático apenas para evitar a sobreposição de rótulos no eixo x. A direção dos rótulos (horizontal/vertical) do eixo depende dos tamanhos das cadeias de caracteres dos rótulos e do espaço disponível. Os rótulos do eixo x são exibidos na horizontal em uma linha, horizontalmente em várias linhas com quebras ou verticalmente. Não é aceita, atualmente, a exibição de rótulos do eixo x em um ângulo, nem o controle manual explícito sobre cada posição de rótulo.

    Observação   Existem vários suplementos de gráficos de terceiros que proporcionam mais controle sobre rótulos de eixo. Esses suplementos podem ser instalados no topo do Reporting Services 2005.

Rótulos de pontos de dados e rótulos de legendas

Rótulos de pontos de dados podem ser usados para apontar especificamente para certos valores (como o valor mínimo ou máximo global) entre todos os pontos de dados visíveis no gráfico.

Para ativar rótulos de pontos de dados, edite o valor de gráfico na caixa de diálogo Chart Properties (Propriedades do Gráfico). Isso faz com que a caixa de diálogo Edit Chart Values (Editar Valores de Gráfico), que contém uma guia Point Labels (Rótulos de Pontos) com a opção Show point labels (Exibir rótulos de pontos).

Posicionando rótulos de dados

Quando você ativa rótulos de pontos de dados, por padrão, é exibido um rótulo por dado. O rótulo de ponto de dados é posicionado automaticamente, para evitar sobreposição dos rótulos. Se houver sobreposição dos rótulos de ponto de dados, o controle de gráfico moverá os rótulos sobrepostos para um espaço livre da área de plotagem do gráfico (e o desenho será refeito de modo a conectar os rótulos de ponto de dados aos valores de ponto de dados). Se muitos rótulos se sobrepuserem, o controle do gráfico removerá alguns rótulos de pontos de dados individualmente até que haja espaço suficiente para encaixar os rótulos restantes sem sobreposição.

Além do posicionamento automático, é possível usar posicionamento de rótulo manual explícito (alto, esquerda, centro e assim por diante). Contudo, dependendo dos valores de dados e da extensão e do tamanho dos rótulos de ponto de dados, isso pode resultar em rótulos sobrepostos.

Por padrão, o rótulo de ponto de dados exibe o valor y do ponto de dados. Também é possível especificar uma expressão de rótulo de ponto de dados explícito ou cadeias de caracteres de formato numérico ou de DateTime para personalizar o rótulo. Em geral, você realizaria cálculos de rótulo de ponto de dados usando expressões similares àquelas utilizadas para calcular o valor y na expressão de valor de ponto de dados. Por exemplo, para exibir apenas rótulos de ponto de dados, se a contribuição relativa do segmento for maior do que 5 por cento da quantidade total, use uma expressão de rótulo de pontos de dados similar ao código no procedimento abaixo.

  1. Use a expressão a seguir para a expressão de rótulo de ponto de dados:

    =Code.GetLabel(Sum(Fields!Sales.Value), Sum(Fields!Sales.Value,"SalesChart"))
  2. Abra a caixa de diálogo Report Properties (Propriedades do Relatório) e clique na guia Code (Código). Adicione a seguinte função de código personalizado GetLabel() na opção Custom code (Código personalizado).

    Public Function GetLabel(ByVal currentValue As Double, ByVal totalValue As Double) As String
    

    If currentValue / totalValue < 0.05 Then         Return " "     Else         Return Format(currentValue / totalValue, "P1")     End If End Function

Explicação do código

A função GetLabel() leva dois argumentos. O primeiro argumento fornece o valor atual deste determinado ponto de dados. O segundo argumento fornece o cálculo do valor total. A função calcula a porcentagem relativa. Se ela for menor do que 5 por cento (0,05), será retornada uma cadeia de caracteres em branco.

Observação   O retorno de uma cadeia de caracteres nula ou vazia faz com que seja exibido o rótulo padrão gerado automaticamente. Se a porcentagem relativa for, pelo menos, de 5 por cento, será retornada uma cadeia de caracteres de porcentagem formatada (cadeia de caracteres de formato: P1).

Um exemplo de aplicação deste tipo de formatação pode ser encontrado no relatório de exemplo PiePercentage que acompanha este white paper.

Posições de rótulos de dados em gráficos de pizza e de rosca

Para gráficos de pizza e de rosca, existem apenas duas posições para rótulos de ponto de dados: dentro (define a posição do rótulo de ponto de dados como Automático ou Centro) e fora (qualquer outra posição de rótulo). Um exemplo de rótulo externo é mostrado na Figura 5 (e no relatório de exemplo PieSimplePercentage).

Figura 5. Rótulos de ponto de dados fora do gráfico em um gráfico de pizza

A posição dos rótulos dos segmentos da pizza pode ser especificada conforme mostrado na Figura 6.

Figura 6. Configuração de rótulos de ponto de dados fora do gráfico em um gráfico de pizza ou de rosca pela seleção de qualquer posição, exceto o centro

Rótulos de legendas

Em geral, os rótulos de legendas são determinados com base nos valores de grupo de séries dinâmicas (ou rótulos, se explicitamente especificado no grupo) e nos nomes dos valores (séries estáticas). Uma vez que o gráfico é, essencialmente, uma representação plana de hierarquias de agrupamentos, os rótulos de legendas são gerados com base nessa hierarquia.

Por exemplo, se um gráfico tem dois agrupamentos de séries (a externa definida como OrderYear – Ano do Pedido, a interna como OrderQuarter – Trimestre do Pedido) e somente um valor de gráfico (por exemplo, Actual – Real), os rótulos de legenda são gerados pela concatenação dos valores de grupo e dos valores de gráfico, como mostrado na Tabela 1.

Tabela 1

Rótulo OrderYear

Rótulo OrderQuarter

Rótulo de série de valores de gráfico

RÓTULO DE LEGENDA GERADO

2006

Q1

Actual

2006 – Q1 – Actual

2006

Q2

Actual

2006 – Q2 – Actual

Suponha que adicionemos um segundo valor de gráfico, chamado Budget (Orçamento). Com os mesmos dados do exemplo anterior, os rótulos gerados se assemelhariam aos da Tabela 2.

Tabela 2

Rótulo OrderYear

Rótulo OrderQuarter

Rótulo de série de valores de gráfico

RÓTULO DE LEGENDA GERADO

2006

Q1

Actual

2006 – Q1 – Actual

2006

Q1

Budget

2006 – Q1 – Budget

2006

Q2

Actual

2006 – Q2 – Actual

2006

Q2

Budget

2006 – Q2 – Budget

Observação   É possível ocultar níveis internos individualmente na hierarquia, configurando a expressão de rótulo de grupo de modo a retornar uma cadeia de caracteres vazia (

=""

). Isso faz com que esse nível de grupo seja removido dos rótulos de legenda gerados.

Rótulos e pontos de dados vazios

A situação a seguir pode soar familiar. Você cria um gráfico com uma série de dados, os rótulos de ponto de dados são ativados e o gráfico parece ótimo. Então, você decide adicionar um grupo de série dinâmica, para que o gráfico exiba várias séries de dados. Repentinamente, o gráfico adquire rótulos adicionais (para pontos de dados vazios).

Pontos de dados vazios ocorrem quando o dataset subjacente não contém valores de dados para cada combinação de série/categoria. O gráfico equivale, em essência, a uma matriz (esparsa) com células vazias.

É possível remover rótulos de pontos de dados vazios. Em vez de ativar os rótulos de ponto de dados e usar o rótulo padrão, use a abordagem mostrada no relatório de exemplo EmptyDataPointLabels que acompanha este white paper (consulte também a Figura 7). A seguir é apresentado o código de exemplo que faz isso.

  1. Use a função Count() para determinar quantas linhas do dataset subjacente devem ser agregadas para esse ponto de dados. Se a contagem for igual a zero, o ponto de dados será vazio. Transmita a contagem a uma função de código personalizado com o valor de rótulo real:

    =Code.GetLabel(Avg(Fields!UnitsInStock.Value), Count(Fields!UnitsInStock.Value))
    
  1. Abra a caixa de diálogo Report Properties (Propriedades do Relatório) e clique na guia Code (Código). Adicione a seguinte função de código personalizado GetLabel() na opção Custom code (Código personalizado).

    Public Function GetLabel(ByVal datapointValue As Double, ByVal count As Integer) As String
    If count = 0 Then
        Return " "
    Else
        Return Format(datapointValue, "N1")
    End If
    

End Function

Figura 7. Relatório de exemplo que tem pontos de dados vazios sem rótulos

P&R sobre formatação de rótulos de ponto de dados

  • Pergunta: Qual é a finalidade das linhas cinzentas (denominadas contornos) próximas aos rótulos de ponto de dados, se o gráfico está lotado com pontos de dados e rótulos?

    Resposta: Se a posição dos rótulos de ponto de dados estiver definida como Auto (Automática), o controle do gráfico moverá os rótulos para áreas de espaço livre, de modo a evitar a sobreposição de rótulos. Os contornos conectam o rótulo de ponto de dados ao local do ponto de dados.

    Você pode usar posicionamento manual para impedir isso. Usando expressões, você pode ocultar dinamicamente a maioria dos rótulos de ponto de dados, fornecendo, por resultado da avaliação de uma cadeia de caracteres, um espaço vazio (

    =" "

). Do contrário, o rótulo padrão será exibido, se os rótulos de ponto de dados estiverem ativados.

  • Pergunta: É possível usar palavras-chave Dundas para a formatação de rótulos?

    Resposta: Sim, você pode usar palavras-chave Dundas para rótulos de ponto de dados. No entanto, em geral, recomenda-se que você não combine expressões RDL e palavras-chave Dundas ao mesmo tempo (expressões RDL são avaliadas primeiro, funções Dundas são interpretadas pelo controle do gráfico mais tarde). A Tabela 3 contém uma lista de palavras-chave Dundas úteis.

    Tabela 3

    Palavra-chave Dundas

    Substituída por

    #VALX

    Ponto de dados do valor x

    #VAL

    Ponto de dados do valor y

    #VALY, #VALY2, #VALY3 etc.

    Primeiro valor y, segundo valor y, terceiro valor y e assim por diante

    #INDEX

    Índice dos pontos de dados em uma série

    #TOTAL

    Total de todos os valores y na série atual

    #VALY{C2}

    Valor y do ponto de dados formatado com a cadeia de caracteres de formato C2 (formatação de moeda)

Exemplos de gráficos e relatórios

Esta seção contém exemplos de criação de diferentes tipos de gráficos e relatórios. Pode ser útil, ocasionalmente, voltar aos tópicos específicos de rótulos de gráfico abordados nas seções anteriores ao estudar estes exemplos. Os exemplos a seguir são abordados nesta seção.

  • Gráficos híbridos de colunas e linhas

    Descreve gráficos combinatório em geral e o relatório de exemplo SalesCostTarget.

  • Gráficos de Pareto

    Implementa uma visualização de Pareto para um gráfico (relatório de exemplo ParetoChart).

  • Cálculos de médias móveis

    Cálculo e visualização de tendências de séries de tempo em gráficos (relatório de exemplo MovingAverage).

  • Paletas de cores personalizadas de gráficos e legendas

    Como personalizar as cores de seu gráfico (relatório de exemplo CustomColorPalette).

  • Gráficos de pizza e de rosca

    Informações específicas a ter em mente ao trabalhar com gráficos de pizza ou de rosca.

  • Adicionando tabelas de dados de gráficos

    Mostra como vincular dados de gráficos agregados a dados detalhados (relatório de exemplo PiePercentage).

  • Gráficos de dispersão e de bolhas

    Dicas importantes para desenho de gráficos de dispersão e de bolhas (BubbleChart, StepFunctionChart).

  • Gráficos embutidos em tabelas

    Talvez você não precise de visualizações de gráficos complexas ou tenha que lidar com uma quantidade desconhecida de dados em tempo de execução, mas, mesmo assim, deseje ter visualizações úteis e de boa aparência. Esta seção provê maneiras de atingir esse objetivo (TableInlineCharts).

  • Extensibilidade e criação manual de gráficos

    Aborda opções para o caso de os gráficos internos não serem suficientes.

Relatórios de exemplo, baseados nos bancos de dados de exemplo AdventureWorks, do SQL Server 2005, e Northwind estão incluídos no arquivo para download deste white paper.

Gráficos híbridos de colunas e linhas

Gráficos que exibem várias séries de dados na forma de colunas e outras séries na forma de linhas são usados, muitas vezes, para apresentar tendências globais, valores-alvo ou analisar mais profundamente os dados dentro do gráfico. Esta seção fornece informações gerais sobre como criar este tipo de gráfico no Reporting Services.

Para criar um gráfico híbrido de colunas e linhas:

  1. Adicione um gráfico ao relatório, definindo o tipo de gráfico como Column (Coluna).

  2. Crie o gráfico, adicionando grupos de categorias e/ou grupos de séries e valores de dados.

  3. Para que os valores de dados sejam exibidos na forma de linhas, cumpra as seguintes etapas no Report Designer:

    • Abra a caixa de diálogo Chart Properties (Propriedade do Gráfico).

    • Clique na guia Data (Dados).

    • Selecione o valor de dados a ser exibido como linha e clique em Edit (Editar).

    • Na caixa de diálogo Edit Chart Value (Editar Valor de Gráfico), clique na guia Appearance (Aparência) e selecione Plot data as line (Plotar dados como linha) (veja a Figura 8).

    Figura 8. Criação de uma série de dados como linha em um gráfico de colunas

Para adicionar um valor-alvo constante ou dinâmico ao gráfico:

  1. Crie o gráfico.

  2. Na guia Data (Dados) da caixa de diálogo Chart Properties (Propriedades do Gráfico), adicione um novo valor de dados (por exemplo, Target – Alvo).

  3. Defina o valor-alvo (o exemplo na Figura 9 usa um valor-alvo constante de 100.000 em todas as categorias). Certifique-se de usar uma expressão começando com = (igual). Caso contrário, o valor não será interpretado como valor numérico.

    Figura 9. Adição de um valor-alvo

O relatório de exemplo SalesCostTarget (veja a Figura 10) usa essa abordagem para adicionar ao gráfico uma linha-alvo de vendas simples.

Clique aqui para ver a imagem ampliada

Figura 10. Valor-alvo (linha vermelha) (clique na imagem para ampliá-la)

Observação   Uma vez que as linhas das séries de gráficos de linhas são desenhadas conectando-se pontos de dados de várias categorias, elas só ficarão visíveis se o agrupamento de categorias tiver, pelo menos, dois valores distintos de instância de grupo em tempo de execução.

Observação   Se o gráfico contiver um ou mais grupos de séries, o valor-alvo de dados será repetido para cada instância de grupo de séries. Isso poderá ser útil se você tiver valores-alvo específicos para cada instância de grupo.

Caso queira apenas um valor-alvo global para todas as séries, você poderá definir dinamicamente o valor-alvo de dados, por exemplo, desta maneira:

=iif(Fields!<SameFieldAsSeriesGroup>.Value =
	First(Fields!<SameFieldAsSeriesGroup>.Value,
	<ChartName>), <TargetValue>, Nothing)

Um exemplo de expressão específica poderia se assemelhar a:

=iif(Fields!Year.Value = First(Fields!Year.Value,
	"SalesChart"), 100000, Nothing)

Gráficos de Pareto

Um gráfico de Pareto resume e exibe a importância relativa de diferenças entre grupos de dados. Os gráficos de Pareto distinguem os "poucos vitais" dos "muitos úteis". Um gráfico de Pareto também pode ser definido como um gráfico de colunas, cujas colunas são classificadas em ordem descendente, para identificar a maior oportunidade de melhoria.

Embora os gráficos de Pareto não tenham suporte direto dos gráficos internos do Reporting Services, é possível criar um deles por meio dos recursos do Reporting Services 2005 e de código adicional. Esta seção oferece uma explicação minuciosa do relatório de exemplo ParetoChart que acompanha este white paper.

A seguir, há a descrição do cenário em que foi produzido o relatório de exemplo ParetoChart.

O banco de dados AdventureWorks do SQL Server 2005 contém dados sobre funcionários de vendas. Em particular, estamos interessados em analisar as seguintes informações de nossos funcionários de vendas:

  • A que se assemelharia a análise de Pareto que se baseasse nos funcionários de vendas com os maiores bônus do ano passado? (Veja a linha laranja na Figura 11.)

  • Quais funcionários de vendas receberam os maiores bônus no ano passado e como isso se compara às suas vendas totais deste ano? (Veja as colunas azul e verde na Figura 11.)

  • Há mudanças significativas no desempenho de vendas quando comparamos os bônus do ano passado com as vendas deste ano? Embora isso possa ser respondido por meio da comparação das colunas azul e verde, a enorme lacuna entre as linhas de Pareto laranja e vermelha na Figura 11 deixa as coisas mais evidentes.

  • No caso de um funcionário de vendas em particular, nós gostaríamos de detalhar o desempenho de vendas passado e presente e analisar as tendências históricas derivadas de vários anos de dados.

Isso pode ser feito pela adição de ações de detalhamento nos valores de dados de vendas (colunas verdes na Figura 11) para fornecer uma análise detalhada dos dados de um vendedor em especial, incluindo uma análise de tendência. O relatório de detalhamento (relatório de exemplo MovingAverage) é discutido mais minuciosamente na próxima seção.

Clique aqui para ver a imagem ampliada

Figura 11. Relatório de exemplo de gráfico de Pareto (Clique na imagem para ampliá-la)

Para criar o relatório de gráfico de Pareto

  1. Defina a consulta para recuperar os dados de vendas necessários.

    A consulta pré-classifica os dados de cada vendedor com base nos valores de bônus. Ela não recupera as ordens de venda individuais, pois estas não são necessárias para este relatório. Isso também mantém pequeno o tamanho do dataset.

  2. Crie o layout global do gráfico.

    Adicione um gráfico de colunas ao relatório. Para analisar os dados por vendedor, adicione um grupo de categorias com base no vendedor (agrupe por

    =Fields!SalesPersonID.Value

). Como rótulo de categoria, exiba o nome e o sobrenome do vendedor. Isso é feito por meio da configuração da expressão de rótulo de grupo de categorias da maneira a seguir. FakePre-34e708a833504f2fada0da2f08ee7694-639a7693635e4420bc28ff7c03930c76

  1. Prepare o gráfico para os cálculos de Pareto.

    Usamos a função RunningValue() para os cálculos.

    Observação   A função RunningValue é aceita apenas em gráficos iniciados com o Reporting Services 2005.

    Semelhante a uma matriz, a função RunningValue necessita de um escopo de agrupamento explícito em um gráfico para determinar se o valor em execução deve ser executado em todas as categorias de uma série de dados em particular (a direção, em essência, é horizontal) ou se ele deve ser executado em todas as séries de dados de uma categoria em particular (menos comum).

    Para os cálculos de Pareto, precisamos usar uma função RunningValue que tome o nome de um grupo de série como seu escopo para "redefinir" (e, assim, executá-lo em todas as categorias). Como ainda não temos um grupo de séries para este gráfico em particular, podemos simplesmente adicionar um falso grupo de séries baseado em um valor constante (como 1).

    Expressão de grupo:

    1

    Expressão de rótulo:

    =""

(para ocultar o rótulo de série dos rótulos de legenda gerados)

Isso resulta em uma série de dados e fornece, ao mesmo tempo, um nome de escopo de série explícito.
  1. Adicione os valores de dados de bônus e vendas na forma de colunas.

    Podemos adicionar ao gráfico valores de dados para Bônus e Vendas no Ano, arrastando os campos de dataset correspondentes para cima do gráfico.

    Observação   Este exemplo usa a função de agregação Sum() para os valores de bônus e vendas.

    Queremos colocar a legenda no canto superior esquerdo, dentro da área de plotagem do gráfico. Logo, desejamos que o eixo y seja escalado de modo que o valor de ponto de dados máximo mostrado no gráfico nunca exceda 75 por cento da altura total do eixo y.

    Isso é feito escalando-se os cálculos de bônus por um fator de 75 por cento:

    =0.75 * Sum(Fields!Bonus.Value) / Max(Fields!Bonus.Value, "SeriesGroup")

    Vamos fazer o mesmo para o cálculo de vendas:

    =0.75 * Sum(Fields!SalesYTD.Value) / Max(Fields!SalesYTD.Value, "SeriesGroup")
  2. Estabeleça o eixo y como um eixo percentual.

    Na etapa anterior, nós estabelecemos os cálculos de bônus e vendas como cálculos percentuais (quantidade relativa em comparação com o valor máximo).

    A definição da cadeia de caracteres de formato do eixo y como P0 aplica a formatação de porcentagem (o eixo y real será colocado em uma escala entre 0,0 e 1,0). Para obtermos bons intervalos, definimos o intervalo maior do eixo y como 0,2 para configurar intervalos de 20 por cento.

  3. Adicione os cálculos de Pareto de bônus e vendas na forma de linhas.

    A função RunningValue() proporciona um cálculo cumulativo até ser redefinida. Queremos que ela nunca seja redefinida. Como não temos um grupo de séries explícito inicialmente, adicionamos um na etapa 3.

    Os cálculos de Pareto são a soma cumulativa dividida pelos valores totais. Para o cálculo de Pareto dos bônus, usamos a expressão a seguir.

    =RunningValue(Fields!Bonus.Value, Sum, "SeriesGroup") / Sum(Fields!Bonus.Value, "SeriesGroup")
    
Vamos fazer o mesmo para o cálculo de Pareto de vendas:

<pre IsFakePre="true" xmlns="http://www.w3.org/1999/xhtml">=RunningValue(Fields!SalesYTD.Value, Sum, "SeriesGroup") / Sum(Fields!SalesYTD.Value, "SeriesGroup")
  1. Adicione uma ação de detalhamento ao valor de dados de vendas.

    Para habilitar uma análise de detalhamento dos dados de vendas de um vendedor individual, no relatório de exemplo MovingAverage, adicionamos uma ação de detalhamento (veja a Figura 12) ao ponto de dados de vendas. Como estamos interessados apenas em um determinado vendedor, definimos o parâmetro de detalhamento SalesPersonID como o valor do grupo de categorias atual. Neste exemplo, trata-se do ID do vendedor atual:

    =Fields!SalesPersonID.Value

.

![](images/Aa964128.moressrschartsfig12(pt-br,SQL.90).gif)

**Figura 12. Adição de uma ação de detalhamento**
  1. Termine o gráfico acrescentando formatação, rótulos de ponto de dados e legenda.

Cálculos de médias móveis

Uma média móvel é uma dentre uma família de técnicas estatísticas similares usadas para analisar dados de séries de tempo. Uma série de médias móveis pode ser calculada para séries de qualquer tempo.

Embora os cálculos de médias móveis não tenham suporte direto dos gráficos internos do Reporting Services, com freqüência, é possível escrever código para realizar esse tipo de cálculo. Esta seção apresenta uma explicação minuciosa do relatório de exemplo MovingAverage.

O relatório de exemplo se refere ao cenário descrito na seção anterior sobre gráficos de Pareto. No caso de um funcionário de vendas em particular, gostaríamos de analisar o desempenho de vendas passado e presente e analisar as tendências históricas derivadas de vários anos de dados. As médias móveis são usadas para suavizar flutuações de curto prazo, destacando, assim, tendências ou ciclos de longo prazo.

O exemplo MovingAverage mostra como calcular uma média móvel simples (a média não ponderada dos n pontos de dados anteriores). Neste exemplo em particular, usamos os dados de vendas dos três meses anteriores. Veja a Figura 13.

Clique aqui para ver a imagem ampliada

Figura 13. Cálculo de média móvel (clique na imagem para ampliá-la)

Para criar o relatório

  1. Defina a consulta de modo que ela recupere os dados de vendas detalhados necessários.

    A consulta é parametrizada para recuperar apenas dados relativos a um determinado vendedor. O parâmetro de consulta é definido com base em um parâmetro de relatório, que é populado com um dataset que se baseia em uma lista de valores válidos.

  2. Crie o layout global do gráfico.

    Adicione um gráfico de colunas ao relatório. Para o eixo x, use o modo categoria, de modo a ter dois níveis de agrupamento: agrupamento por meses, no nível interno, e agrupamento por ano com distribuições de agrupamentos, no nível externo. O grupo de meses usa a expressão de rótulo de grupo explícito abaixo para formatar o mês com o nome abreviado.

    =Format(Fields!OrderDate.Value,"MMM")
  3. Prepare o gráfico para o cálculo da média móvel.

    Assim como na etapa 3 dos cálculos de Pareto, nós usamos a função RunningValue. A média móvel não deve ser redefinida pelas categorias e, por isso, adicionamos um agrupamento de séries baseado em SalesPersonID. Uma vez que a consulta está parametrizada com base no vendedor, haverá apenas uma série de vendedor. A expressão de rótulo de grupo de séries é definida como

    =Fields!FullName.Value

, de modo que os itens de legenda do gráfico conterão o nome completo do vendedor.

  1. Adicione o cálculo de vendas na forma de colunas.

    Arraste o campo de dataset TotalDue para cima da zona de transferência de valores de gráfico para adicionar um valor de dados de vendas com base na agregação Sum(). Para concatenar a palavra "Vendas" com o rótulo de grupo de séries (o rótulo de grupo é o nome completo do vendedor, como definido na etapa 3), definimos explicitamente o rótulo de valor de dados como Vendas.

  2. Adicione as funções de código personalizado para média móvel.

    A tabela abaixo mostra um exemplo de cálculo de média móvel por meio de fila. A coluna Queue Contents (Conteúdo da Fila) mostra o conteúdo atual da fila para um determinado mês. A última coluna da tabela mostra um cálculo de RunningValue com base nos itens agregados adicionados e removidos da fila. O exemplo de código abaixo da tabela mostra uma implementação desse algoritmo.

    Tabela 4

    Mês

    Vendas

    Média móvel
    (2 meses)

    Valor normal em execução

    Conteúdo da fila

    Valor removido da fila

    Valor em execução baseado na fila

    Jan

    20

    n/a

    20

    20

    n/a

    0

    Fev

    10

    15

    35

    20, 10

    n/a

    0+ 15 = 15

    Mar

    24

    17

    59

    10, 24

    -20

    15+ (24-20) /2 = 17

    Abr

    16

    20

    75

    24, 16

    -10

    17+ (16-10) /2 = 20

    Mai

    12

    14

    87

    16, 12

    -24

    20+ (12-24) /2 = 14

     

     

     

     

     

     

    Para implementar RunningValue com base em fila, adicione o código a seguir à seção Custom code (Código personalizado) na guia Code (Código) da caixa de diálogo Report Properties (Propriedades do Relatório).

        Private queueLength As Integer = 3
    

    Private queueSum As Double = 0     Private queueFull As Boolean = False     Private queue As New System.Collections.Generic.Queue(Of Double)

    Public Function MovingQueue(ByVal currentValue As Double) As Object         Dim removedValue As Double = 0         If queue.Count >= queueLength Then             removedValue = queue.Dequeue()         End If         queueSum += currentValue         queueSum -= removedValue         queue.Enqueue(currentValue)         If queue.Count < queueLength Then             Return Nothing         ElseIf queue.Count = queueLength And queueFull = False Then             queueFull = True             Return queueSum / queueLength         Else             Return (currentValue - removedValue) / queueLength         End If     End Function

  1. Adicione o valor de vendas da média móvel na forma de uma linha.

    O cálculo do valor de dados para a média móvel usará a função RunningValue sobre os valores retornados pela função de código personalizado MovingQueue. A função MovingQueue calcula os valores de ajuste para o cálculo RunningValue cumulativo. Isso é feito por meio do código a seguir.

    =RunningValue(Code.MovingQueue(Fields!TotalDue.Value), Sum, "SalesPerson")
    

Observação   Para realizar vários cálculos de média móvel em um gráfico, determine uma forma de redefinir a fila ao final de uma série ou utilizar várias filas. Por exemplo, você poderia usar uma tabela de hash com filas indexadas com base no valor de grupo de séries e transmitida à função MovingQueue na forma de argumento adicional.

Observação   Um gráfico não pode distribuir várias páginas. Portanto, é válido declarar as variáveis como privadas e não-compartilhadas.

Para usar o cálculo de média móvel em outra região de dados (como uma lista, tabela ou matriz) que distribua várias páginas, as variáveis devem ser declaradas como compartilhadas (isto é, estáticas) para que o estado seja mantido na paginação. No entanto, como isso utiliza variáveis estáticas, se duas pessoas executarem o relatório ao mesmo tempo, haverá uma pequena chance de que uma esmague o estado da variável da outra. Se você tiver que estar 100 por cento seguro de que isso não ocorrerá, torne cada uma das variáveis compartilhadas uma tabela de hash baseada no ID do usuário solicitante (

=Globals!UserID

).

Paletas de cores personalizadas de gráficos e legendas

Os gráficos usam paletas de cores internas predefinidas com 10 a 16 cores distintas. Desde o Reporting Services 2000 Service Pack 1 (SP1), as cores padrão podem ser substituídas. Para especificar valores de cor como constantes ou com base em expressão, clique no botão Series Style (Estilo da Série) nas propriedades de aparência do valor de dados na caixa de diálogo Edit Chart Value (Editar Valor do Gráfico). Isso pode ser usado, por exemplo, para realçar valores com base em uma certa condição, como um valor mínimo ou máximo dentro da série atual.

Observação   Caso não deseje definir uma paleta de cores personalizada completa, você poderá substituir a cor em cada ponto de dados. Use uma expressão que retorne um valor de cor específico (para substituir) ou "Nada", o que fará com que a cor atual seja selecionada na paleta de cores interna subjacente.

Por exemplo, digamos que você queira destacar em vermelho todos os valores de ponto de dados com valores y negativos. Em todos os demais pontos de dados, você deseja aplicar as cores padrão. Para fazer isso, selecione Edit the data value (Editar o valor de dados) e clique na guia Appearance (Aparência). Clique no botão Series Style (Estilo da Série), que abre a caixa de diálogo Style Properties (Propriedades do Estilo). Clique na guia Fill (Preenchimento). Insira a expressão a seguir nas propriedades de estilo de cor de preenchimento.

=iif(Sum(Fields!Sales.Value - Fields!Cost.Value) < 0, "Red", Nothing))
  

Observação   Se você definir a cor de preenchimento como um valor constante, essa cor será aplicada a todos os pontos de dados daquela série de dados.

A legenda do gráfico usa campos de cor para fazer a correspondência entre os itens de legenda e os pontos de dados visíveis. A legenda pode exibir apenas um campo de cor por item de legenda (série de dados); logo, ela exibe a cor do primeiro ponto de dados dentro da série. Lembre-se disso quando você usar expressões para determinar dinamicamente a cor de pontos de dados individuais dentro de uma série; o item de legenda sempre exibirá a cor real do primeiro ponto de dados.

Embora a legenda interna dos gráficos do Reporting Services seja fácil de usar, falta a ela flexibilidade. Por exemplo, a legenda consome espaço no gráfico. Se a legenda for colocada fora da área de plotagem e ela aumentar, o tamanho da área de plotagem do gráfico será encolhido na mesma proporção.

É possível obter mais flexibilidade e controle sobre a legenda gerando sua própria legenda personalizada, por meio de uma tabela ou matriz. A maneira mais fácil de sincronizar as cores no gráfico com sua legenda personalizada é definir sua própria paleta de cores personalizada para gráficos. O relatório de exemplo CustomColorPalette implementa uma paleta de cores personalizada e uma legenda personalizada. Veja a Figura 14.

Figura 14. Um relatório de gráfico de barras com uma paleta de cores personalizada e uma legenda personalizada

Para criar uma paleta de cores personalizada

  1. Defina os grupos de séries e os grupos de categorias do gráfico.

    Por padrão, cada série de dados do gráfico possui uma cor atribuída a ela. Essa cor se baseia na paleta selecionada para o gráfico. Neste exemplo, queremos substituir essas cores segundo os valores de instância de grupos de séries.

  2. Defina a paleta de cores personalizada e o código personalizado.

    A variável colorPalette armazena a definição de nossa paleta de cores personalizada, que tem 15 cores distintas. A variável count mantém o controle da contagem total de valores de agrupamentos distintos para delimitação quando excedermos o número de cores distintas da paleta de cores personalizada. A tabela de hash mapping mantém o controle do mapeamento entre valores de agrupamentos e cores. Isso assegura que todos os pontos de dados dentro da mesma série de dados tenham a mesma cor. Mais tarde, ela será usada para sincronizar as cores de legenda personalizadas com as cores do gráfico. O código a seguir vai na janela de código personalizado do relatório.

        Private colorPalette As String() = {"Green", "Blue", "Red", "Orange", 
    

"Aqua", "Teal", "Gold", "RoyalBlue", "MistyRose", "LightGreen", "LemonChiffon", "LightSteelBlue", "#F1E7D6", "#E16C56", "#CFBA9B"}     Private count As Integer = 0     Private mapping As New System.Collections.Hashtable()     Public Function GetColor(ByVal groupingValue As String) As String         If mapping.ContainsKey(groupingValue) Then             Return mapping(groupingValue)         End If         Dim c As String = colorPalette(count Mod colorPalette.Length)         count = count + 1         mapping.Add(groupingValue, c)         Return c     End Function

  1. Chama a função GetColor() para atribuir cores aos pontos de dados.

    A função GetColor é chamada a partir das propriedades de estilo de cor de preenchimento. Edite o valor de dados para abrir a caixa de diálogo Edit Chart Value (Editar Valor de Gráfico) e clique na guia Appearance (Aparência) (Figura 15). Clique no botão Series Style (Estilo da Série) e, depois, na guia Fill (Preenchimento). O valor de grupo de séries atual é transmitido na forma de um argumento à função GetColor, necessária para mapear o valor de instância de grupo interno para o valor de cor.

    Figura 15. Especificação de estilos de série de dados explícitos

    Observação   Se houver vários grupos de séries de gráficos, você poderá concatenar os valores de grupo de séries para criar um identificador exclusivo a ser usado dentro da função GetColor. O código a seguir é um exemplo.

       =Code.GetColor(Fields!Country.Value & "|" & Fields!City.Value)
    
  2. Adicione uma legenda de gráfico.

    Você pode usar a legenda de gráfico interna. Ou, então, desative a legenda de gráfico interna e siga as etapas do próximo procedimento para criar sua própria legenda de gráfico personalizada, com uma região de dados de tabela ou de matriz.

Para criar uma legenda personalizada

  1. Adicione uma região de dados de tabela no relatório.

    Coloque a tabela perto do gráfico e ligue-a ao mesmo dataset do gráfico.

  2. Espelhe a estrutura de agrupamentos do gráfico na tabela, adicionando grupos de tabelas.

    Se o gráfico usar agrupamentos de séries, adicione os agrupamentos à tabela acrescentando grupos de tabelas baseados na mesma expressão de grupo que os agrupamentos de séries do gráfico. Em seguida, adicione agrupamentos de categorias de gráfico (se houver) como grupos de tabelas internos.

    Em geral, se o gráfico tiver m agrupamentos de séries e n agrupamentos de categorias, adicione m+n grupos de tabelas a sua legenda personalizada.

    Para cada grupo de tabelas, certifique-se de exibir apenas o cabeçalho do grupo (que conterá a descrição da legenda). Remova, também, a linha de detalhe da tabela, a menos que você queira usá-la para simular uma tabela de dados de gráfico.

  3. Crie a legenda personalizada.

    Adicione um retângulo para o campo de cor da legenda personalizada. Você poderia, por exemplo, adicioná-lo à primeira coluna da tabela. Como indicado na etapa 2, deve haver apenas linhas de cabeçalho de grupo na tabela. O retângulo vai no nível do cabeçalho de grupo mais interno.

    Defina a propriedade BackgroundColor do retângulo como a expressão equivalente usada na cor de preenchimento do ponto de dados do gráfico. No caso mais trivial, a expressão conteria apenas um valor de agrupamento, como no código abaixo.

    =Code.GetColor(Fields!Country.Value)
    
Para o texto da legenda, use a mesma expressão utilizada para categoria e grupo/rótulo de séries ou experimente outras até obter o texto de descrição de legenda desejada.

Gráficos de pizza e de rosca

A seção Rótulos de ponto de dados e rótulos de legenda descreve como configurar rótulos de ponto de dados internos e externos para as fatias da pizza. Esta seção aborda algumas propriedades adicionais de gráficos de pizza e de rosca.

Ao contrário de outros tipos de gráfico, um gráfico de pizza ou de rosca tem apenas uma "dimensão de agrupamentos" (ou seja, uma série de dados). Para haver duas dimensões em gráficos de pizza e de rosca, eles precisariam ser empilhados um em cima do outro.

Observação   Durante a publicação do relatório, o Reporting Services converte automaticamente os grupos de séries de um gráfico de pizza ou de rosca em grupos de categorias para exibir os dados na forma de uma série de dados.

Gráficos de pizza são usados com freqüência para exibir as porcentagens relativas de pontos de dados. Em geral, o valor percentual(que pode ser usado, por exemplo, para exibição na forma de um rótulo de ponto de dados) pode ser calculado pela divisão da expressão de valor de ponto de dados pela soma total do gráfico inteiro. O código a seguir é um exemplo disso.

=Sum(Fields!Sales.Value) / Sum(Fields!Sales.Value, "SalesChart")

Esta expressão é adicionada como expressão de rótulo de dados, como mostrado na Figura 16.

Figura 16. Cálculo de porcentagem de rótulo de dados

Por padrão, as fatias da pizza têm bordas pretas que aumentam sua visibilidade. Todavia, como mostrado na Figura 17 na próxima seção, é possível substituir a borda por configurações específicas para a aparência do ponto de dados. Se você quiser que a cor da borda corresponda à cor da fatia da pizza, use uma paleta de cores personalizada, conforme abordado na seção anterior. Usando uma paleta de cores personalizada, você pode definir a mesma cor para o ponto de dados (fatia da pizza) e para a borda, fazendo uma chamada em uma função de código personalizado que atribui cores com base no valor de agrupamento de categorias.

Adicionando tabelas de dados de gráficos

Pode ser conveniente adicionar dados de detalhes ao seu gráfico. A adição direta de dados no gráfico pode torná-lo mais difícil de ser interpretado. Em vez disso, adicione as informações a uma tabela de dados.

Um gráfico é um modo muito eficaz de visualizar a distribuição global de valores e identificar áreas interessantes (por exemplo, valores muito pequenos e muito grandes). O leitor pode querer analisar as informações mais detalhadamente, a partir dos dados de detalhe subjacentes.

O Reporting Services oferece três maneiras de introduzir interatividade em pontos de dados de gráficos, a saber:

  • Usar uma ação saltar para relatório para exibir os dados de detalhe passando a um outro relatório baseado nos mesmos valores de grupo de séries/categorias adicionados como valores de parâmetro de detalhamento.

  • Usar uma ação saltar para indicador para saltar para uma seção (como uma tabela de dados) dentro do mesmo relatório.

  • Usar uma ação saltar para URL para gerar um hiperlink para um destino de navegação externo fora do relatório.

A Figura 17 mostra uma versão simplificada do relatório de exemplo PiePercentage que acompanha este white paper.

Clique aqui para ver a imagem ampliada

Figura 17. Gráfico de pizza com formatação personalizada, paleta de cores personalizada e uma tabela de dados (clique na imagem para ampliá-la)

Para criar uma tabela de dados

  1. Crie um gráfico de pizza com uma paleta de cores personalizada.

    O gráfico de pizza da Figura 17 tem dois agrupamentos de categorias. O agrupamento externo se baseia no ano do pedido. O agrupamento interno se baseia na categoria do produto. A paleta de cores personalizada é definida conforme descrição na etapa 2 das etapas para criar uma paleta de cores personalizada.

    Como há dois agrupamentos de categoria, nós usamos a expressão abaixo, que gera uma chave composta, transmitida na função GetColor.

    =Code.GetColor(Fields!OrderYear.Value & Fields!ProdCat.Value)
    

    Se nós aplicarmos a mesma chamada de função GetColor às propriedades de cor de preenchimento e de cor de borda do ponto de dados, as fatias da pizza não apresentarão a borda preta padrão.

  2. Exiba rótulos de ponto de dados apenas para aquelas fatias da pizza que representam uma parte maior do que 4 por cento do total da pizza.

    Para tanto, adicione a função a seguir à seção de código personalizado do relatório. O que importa é retornar uma cadeia de caracteres com um rótulo em branco para as fatias da pizza sem rótulo; caso contrário, o controle do gráfico exibirá o rótulo padrão para essas fatias. (O rótulo padrão é o valor do ponto de dados subjacente.)

    Public Function GetLabel(ByVal currentValue As Double, ByVal totalValue As Double) As String
    

If currentValue / totalValue < 0.04 Then Return " " Else Return Format(currentValue / totalValue, "P1") End If End Function

A expressão de rótulo do ponto de dados chama a função **GetLabel** para calcular o valor percentual/rótulo.

<pre IsFakePre="true" xmlns="http://www.w3.org/1999/xhtml">=Code.GetLabel(Sum(Fields!Sales.Value), Sum(Fields!Sales.Value, "SalesChart"))
  1. Crie uma tabela de dados (matriz) para o gráfico.

    O gráfico exibe apenas dados de vendas agregados por ano e por categoria de produto. Na matriz de dados, gostaríamos de agrupar os dados da mesma forma.

    Adicionamos uma região de dados de matriz e a ligamos ao mesmo dataset do gráfico. Em seguida, adicionamos os campos OrderYear (Ano do Pedido) e ProdCat (Categoria do Produto) como grupos de linhas na matriz e agregamos os valores de Sales (Vendas) na célula da matriz. Para adicionar subtotais, clique com o botão direito do mouse nas células de cabeçalho de grupo na matriz e selecione Subtotal no menu de contexto.

    Observação   Clicar no pequeno triângulo verde de um cabeçalho de matriz faz com que sejam selecionadas as propriedades de Subtotal nas quais é possível definir explicitamente propriedades de estilo para as células de subtotal. Por exemplo, você poderia exibir células de subtotal com uma cor de fundo diferente para distingui-las visualmente dos outros dados.

    O dataset subjacente fornece uma granularidade de dados mais fina do que é exibido no gráfico. Podemos aproveitar isso na matriz de dados, adicionando um grupo de linhas (interno) com base na subcategoria e o trimestre e o mês como grupos de colunas da matriz.

  2. Adicione alternância de detalhamentos à matriz de dados.

    Para adicionar um efeito de detalhamento a um determinado grupo, clique com o botão direito do mouse no cabeçalho do grupo e edite suas propriedades. Na guia Visibility (Visibilidade) da caixa de diálogo Group Properties (Propriedades do Grupo), selecione o nome do item do relatório que deve alternar a visibilidade do grupo atual. Normalmente, seleciona-se o nome de item de relatório da caixa de texto no grupo pai. Se não houver um grupo pai, você poderá adicionar uma caixa de texto no canto da matriz e usá-la para alternar o nível de agrupamento mais externo da matriz.

    A opção Initial visibility (Visibilidade inicial), que define o estado de alternância inicial, também se encontra na guia Visibility (Visibilidade) do grupo. A definição dessa opção como Visible (Visível) significa que ele deve se encontrar inicialmente expandido, e Hidden (Oculto), inicialmente recolhido.

  3. Ajuste a imagem de alternância inicial e o estado de alternância.

    Se o estado de visibilidade da alternância inicial de um grupo estiver definido como Visible (Visível), a imagem de alternância no item de relatório que alterna o grupo poderá ser exibida como um sinal de mais (+). Para exibir, em seu lugar, a imagem de alternância sinal de menos (-), clique com o botão direito do mouse no item de relatório que alterna o grupo; geralmente, é a caixa de texto no cabeçalho do grupo pai. Selecione Properties (Propriedades) no menu de contexto. Na caixa de diálogo Textbox Properties (Propriedades da Caixa de Texto), selecione a guia Visibility (Visibilidade) e defina a aparência inicial da imagem de alternância. Como a visibilidade de alternância do grupo está definida como Visible (Visível), a aparência inicial da caixa de texto deve ser definida como Expanded (-) (Expandida - ), como mostrado na Figura 18.

    Figura 18. Ajustando a aparência inicial da imagem de alternância

  4. Adicione indicadores para conectar o gráfico e a matriz de dados (opcional).

    A ativação da navegação por indicadores dos pontos de dados do gráfico para a matriz de dados requer duas etapas. Primeiro, defina as IDs dos indicadores dentro da matriz de dados. Segundo, defina a ação de saltar para a navegação por indicador no ponto de dados do gráfico.

    Para adicionar indicadores à matriz de dados, clique com o botão direito do mouse no cabeçalho do grupo de linhas de ano do pedido e selecione Properties (Propriedades) no menu de contexto. Na caixa de diálogo Textbox Properties (Propriedades da Caixa de Texto), selecione a guia Navigation (Navegação) e defina a expressão Bookmark ID (ID Indicador) usando uma expressão que gere uma cadeia de caracteres:

    =CStr(Fields!OrderYear.Value)

. Isso providencia nossos destinos de salto dos indicadores.

Abra a caixa de diálogo **Chart Properties** (Propriedades do Gráfico) e edite as propriedades de ponto de dados. Na guia **Action** (Ação), selecione **Jump to bookmark** (Saltar para indicador) e use a mesma expressão utilizada para a ID do indicador.

Gráficos de dispersão e de bolhas

Gráficos de dispersão e de bolhas são diferentes dos outros tipos de gráfico porque, em vez de usar valores de agrupamento de categorias como valores x, têm valores x explícitos para os pontos de dados. Por conseqüência, os dados podem ser agrupados (e agregados) em uma categoria diferente daquela do valor exibido no eixo x. Por exemplo, para exibir as vendas do ano passado de vendedores individuais ao longo do eixo x, não seria conveniente agregar valores y, se dois vendedores tivessem valores x idênticos. O relatório de exemplo BubbleChart (Figura 19) tem um agrupamento de categorias com base no vendedor, de modo a agregar dados de vendas por vendedor. No entanto, o valor das vendas do ano passado é exibido no eixo x.

Observação   É muito importante que você compreenda a distinção entre a propriedade do valor x do ponto de dados e o agrupamento dos dados do gráfico com base em grupos de séries e de categorias. Se você criar um gráfico de dispersão ou de bolhas e ele exibir apenas um ponto de dados na pré-visualização, embora esperasse que fossem exibidos vários pontos diferentes, a explicação mais provável seria que os grupos de categorias ou grupos de séries não foram definidos. Se não houver grupos de categorias e de séries definidos, as linhas do dataset subjacente serão agregadas em um mesmo ponto de dados, com um valor x e um valor y específicos. Em alguns casos, pode-se definir uma expressão de grupo de categorias ou de séries idêntica à expressão do valor x, mas, em um gráfico de dispersão ou de bolhas, seria mais conveniente adicionar um agrupamento de categorias ou de séries com base na representação dos dados. Se o gráfico agrega valores de vendas para cada vendedor, o agrupamento de categorias ou de séries deve se basear na ID ou no nome do vendedor, como mostrado no relatório de exemplo BubbleChart.

Figura 19. Gráfico de bolhas com dados de séries agrupados por vendedor

Um outro cenário útil para gráficos de dispersão encontra-se no relatório de exemplo StepFunctionChart. O gráfico de linha de dispersão usa um agrupamento de categorias baseado em IDs de medidas. Para certos dias, exibidos como valores x, há várias medidas no dataset, exibidas ao longo do eixo y, resultando em etapas verticais.

Figura 20. Gráfico de dispersão baseado, por exemplo, em medidas de sensor

Gráficos embutidos em tabelas

Às vezes, há uma quantidade desconhecida de dados em tempo de execução e você quer que o gráfico "cresça" de tamanho dinamicamente. Um modo de fazer isso é embutir um gráfico em um outro grupo da região de dados. Por exemplo, é possível usar uma região de dados de lista com um grupo de detalhe baseado na expressão abaixo.

=Ceiling(RowNumber(Nothing)/20)

Isso resulta em um grupo para cada vinte linhas de detalhe. Embutir um gráfico dentro dessa lista faz com que sejam criadas instâncias do gráfico, em tempo de execução, a cada vinte linhas.

Para criar uma visualização em barra embutida dos dados, você pode usar duas abordagens de implementação diferentes:

  • Embutir uma imagem que tenha calculado dinamicamente valores de preenchimento corretos (veja a Figura 21). Ajustar o preenchimento correto de uma imagem estática produz um efeito de gráfico de barras como resultado do esticamento dinâmico da imagem.

  • Embutir um gráfico de barras que tenha calculado um valor máximo de eixo y (veja a Figura 23).

  • Ambas as abordagens encontram-se implementadas lado a lado no relatório de exemplo TableInlineCharts.

Figura 21. Gráfico embutido em tabela simulado por uma imagem embutida e preenchimento dinâmico

Para implementar visualizações embutidas baseadas em imagens embutidas

  1. Crie uma imagem embutida que será usada para a visualização em "barra".

    Uma imagem gradiente simples normalmente tem boa aparência. Adicione a imagem como imagem embutia no relatório.

  2. Adicione uma tabela no grupo e visualize os dados.

    Crie a estrutura de agrupamento da tabela. Você pode colocar a visualização da imagem no cabeçalho do grupo ou na linha de detalhes da tabela. Adicione uma imagem embutida em uma nova coluna da tabela. Selecione a imagem embutida da etapa 1 como origem da imagem.

  3. Calcule o preenchimento de imagem à direita (ou à esquerda).

    Crie uma expressão para a propriedade de preenchimento à direita (ou à esquerda) do item de relatório da imagem. A expressão divide o valor numérico a ser visualizado pelo valor máximo. Em seguida, multiplique o tamanho relativo pela largura da coluna da tabela, como definido na etapa 2. Pode ser conveniente, ainda, considerar as funções Math.Min ou Math.Max para restringir o preenchimento a um certo intervalo, se necessário.

    No relatório de exemplo TableInlineChart, a coluna da tabela tem uma largura de 2 polegadas. Para o cálculo do preenchimento, nós usamos a unidade de medida em pontos; há 72 pontos por polegada. Logo, assumindo que definimos o preenchimento à esquerda como 0 ponto, há um intervalo de 144 pontos para a opção Right Padding (Preenchimento à Direita). O código a seguir configura o preenchimento.

    =144 * (1.0 - Fields!UnitsInStock.Value / Max(Fields!UnitsInStock.Value, "DataSet1")) & "pt"
    
![](images/Aa964128.moressrschartsfig22(pt-br,SQL.90).gif)

**Figura 22. Cálculo dinâmico do tamanho do preenchimento à direita da imagem**
  1. Defina a propriedade de redimensionamento da imagem como Fit (Ajustar).

    O preenchimento definido na etapa anterior determina quanto espaço está disponível para esticar a imagem, gerando, assim, o efeito de visualização em barras.

Uma desvantagem da abordagem de imagem embutida é que a imagem poderá ser esticada se você usar fontes ou linhas finas. Usar um gráfico para visualização embutida (Figura 23) proporciona mais controle sobre a visualização e, geralmente, resultados melhores.

Figura 23. Gráfico embutido em tabela com base em um gráfico embutido no cabeçalho de grupo da tabela

Para usar um gráfico para visualização embutida

  1. Adicione uma tabela para agrupar os dados.

    Crie a estrutura de agrupamento da tabela. Tenha em mente que gráficos podem ser colocados somente no cabeçalho ou no rodapé da tabela, ou no cabeçalho ou rodapé do grupo.

  2. Adicione uma nova coluna à tabela e coloque o gráfico em um cabeçalho de grupo.

    Para maximizar a área de plotagem do gráfico para a visualização em barras, aplique as configurações de propriedades de gráfico a seguir.

    Configurações gerais: Defina gráfico em barras, desative a legenda.

    Dados: Ligue o gráfico ao mesmo dataset da tabela pai; adicione um valor de ponto de dados baseado no valor a ser visualizado.

    Eixo x: Desative rótulos de eixo, desative linhas de grade, defina as marcas de seleção como None (Nenhuma).

    Eixo y: Desative rótulos de eixo, defina as marcas de escala como None (Nenhuma), defina o máximo como o valor máximo calculado no escopo da tabela ou dataset contido. Isso é necessário para obter tamanhos corretos de barra; do contrário, cada instância do gráfico escalaria automaticamente o eixo y, com base nos valores de dados daquele grupo em particular.

  3. Refine a visualização do gráfico (opcional).

    Experimente configurações de estilo de área de plotagem do gráfico, linhas de grade maiores no eixo y, efeitos 3D ou configurações de cores dinâmicas para refinar ainda mais a visualização do gráfico embutido.

Extensibilidade e criação manual de gráficos

Este white paper dá informações sobre ajuste de configurações de gráfico e extensão dos recursos do gráfico existente com expressões e funções de código personalizadas. Além disso, existem outras abordagens para integrar funcionalidade de gráfico mais avançada no Reporting Services:

  • Integrar imagens de gráficos geradas por assemblies personalizados.

  • Implementar extensibilidade de gráfico com base no novo recurso item de relatório personalizado do Reporting Services 2005.

  • Usar componentes de suplementos de terceiros no Reporting Services 2005, o que aumenta a funcionalidade de gráfico. Eles se baseiam no recurso item de relatório personalizado.

Para integrar imagens geradas por assemblies personalizados

  1. Crie e implemente um assembly personalizado para gerar imagens.

    O assembly personalizado deve recuperar os dados por si mesmo, cuidar do agrupamento/classificação dos dados e gerar a imagem do gráfico.

    Observação   O assembly personalizado precisa retornar a imagem na forma de byte[]. Ele não pode retorná-la como System.Drawing.Image. Muitas vezes, é possível converter um objeto System.Drawing.Image com código similar ao seguinte:

    System.IO.MemoryStream renderedImage = new MemoryStream(); 
    

myChart.Save(renderedImage); renderedImage.Position = 0; return renderedImage.ToArray();

  1. Adicione uma imagem ao relatório.

    Defina o tipo de imagem como Database (Banco de Dados). Se a imagem gerada for um bitmap no formato de imagem PNG, defina a propriedade mimetype da imagem como "image/png". Para a propriedade de valor de imagem, use uma expressão como esta:

    =MyCustomAssembly.GenerateChart()
    
  1. Visualize o relatório no modo de exibição Preview do Report Design para verificar se ele está funcionando corretamente.

    Observação   Em uma configuração padrão, os assemblies personalizados são executados em FullTrust na pré-visualização do Report Designer. Logo, operações que exigem certas permissões de segurança para acesso ao código (como entrada/saída de arquivo, dados que dão acesso etc.) as recebem automaticamente em FullTrust.

  2. Implante o assembly personalizado em um servidor de relatórios.

    Certifique-se de que a configuração de diretiva de segurança do servidor de relatórios concede permissões suficientes para seu assembly personalizado em tempo de execução; caso contrário, a geração da imagem falhará. Para obter mais informações, consulte Understanding Code Access Security in Reporting Services in SQL Server 2005 Books Online (em inglês) no SQL Server 2005 Books Online.

Gráficos baseados em item de relatório personalizado comparados com Assemblies personalizados

Há vários benefícios em usar o recurso item de relatório personalizado em lugar da abordagem de assembly personalizado. Em primeiro lugar, você pode criar seu próprio componente de suporte em tempo de design que se integrará diretamente no Report Designer. Em segundo lugar, em tempo de execução, você pode aproveitar o mecanismo de processamento do Reporting Services para recuperar os dados e aplicar agrupamento/classificação e filtros. O controle em tempo de execução CustomReportItem acessará os dados processados e gerará uma imagem de gráfico com um mapa de imagem interativo e ações associadas.

Estude e examine minuciosamente a documentação e os exemplos antes de criar seu próprio CustomReportItem (Item de Relatório Personalizado). Há mais informações disponíveis nos seguintes sites:

Conclusão

Este white paper dá dicas e idéias sobre a funcionalidade de gráficos do Reporting Services que não haviam sido abordadas anteriormente em livros, outros artigos, artigos ou apresentações. Ele também aborda como e quando usar certas opções de funcionalidade.

O white paper apresenta e explica detalhadamente uma série de exemplos de relatórios que demonstra como aproveitar melhor os gráficos internos do Reporting Services quando se trabalha em determinados cenários. Por exemplo, ele descreve como adicionar uma análise de Pareto ou calcular médias móveis.

Finalmente, este artigo abordou, brevemente, a extensibilidade do Reporting Services que pode ser usada para integrar funcionalidade (de gráfico) externa em seus relatórios.

 Sobre o autor

Robert M. Bruckner é engenheiro de desenvolvimento de software no grupo Microsoft SQL Server Business Intelligence. Sua principal área é o mecanismo de processamento de dados e relatórios do SQL Server Reporting Services.

Para obter mais informações:

https://msdn.microsoft.com/sql/bi/reporting/ (em inglês)