Feed Artigos Comentários


Projetos &Rails &Redmine &TI André Dourado em 06 jul 2009

Tutorial Redmine – Gráficos no Redmine usando a API do Google Charts

Por André Dourado

Não sou um especialista nem em Redmine, nem em Rails, portanto essa pode não ser a melhor solução no tocante às ferramentas, mas acabou sendo uma forma simples de implementar gráficos de controle de nosso backlog no Redmine.

Descrição da Solução

Precisávamos de uma tabela para armazenar uma fotografia do backlog de nosso setor de desenvolvimento. Nessa tabela inserimos, através de uma tarefa agendada, diariamente às 2 da manhã: quantos tickets entraram e saíram no dia anterior e o total de tickets no backlog.

A partir dessa tabela geramos dois gráficos: um gráfico de linhas, com a quantidade diária de tickets abertos, outro de barras verticais, com a quantidade de tickets que entram e que saem.

Google Charts API

Google Charts API é uma ferramenta muito útil e interessante para quem desenvolve aplicações web e quer gerar gráficos de uma forma dinâmica. Esta API caracteriza-se pela facilidade de utilização e implementação, não sendo necessária a instalação de qualquer software ou frameworks. Para a sua utilização, basta a URL da API no qual serão referenciados os dados e características necessários para gerar o gráfico pretendido.

Os parâmetros são separados por “&”. Podem ser especificados quantos parâmetros se desejarem e pretenderem. Não pretendo aqui tentar esgotar as diversas opções de gráficos possíveis. A documentação completa da API pode ser encontrada em: http://code.google.com/intl/pt-BR/apis/chart/

Detalharei aqui apenas os que utilizamos em nossos gráficos, de forma que tenham um ponto de partida para que possam adaptá-los a suas necessidades.

Construção do Gráfico
“chs” Tamanho do gráfico gerado. Use chs=largura,altura. Ex: chs=430×225&

“cht” Especifica o tipo do gráfico. Linhas do tipo lc, onde são desenhadas diversas linhas para diversos conjuntos de dados, ou do tipo lxy, onde um par de conjuntos de dados é necessário para cada linha. Ex: cht=lc&

“chxt” Especifica os diversos eixos que serão usados no gráfico. O índice do primeiro eixo é 0, o índice do segundo eixo é 1 e assim por diante. Você pode especificar diversos eixos incluindo x, t, y ou r diversas vezes. Ex: chxt=x,y& onde x corresponde ao eixo 0 e y ao eixo 1.

“chxr” Define a escala de um eixo. O primeiro parâmetro é o número do eixo relacionado ao especificado em “chxt”. Os seguintes definem o início e o fim da faixa do eixo. Ex: chxr=1,0,150&

“chd=t” Codificação dos dados em forma de texto com dimensionamento de dados. Usa uma string de qualquer número positivo ou negativo em conjunto com um parâmetro de dimensionamento (chds). Ex: chd=t:108,111,111,111,120&

“chds” Maneira alternativa de definir a linha zero, combinado à codificação de texto. Um conjunto de dados que varia de -60 a 120, pode definir uma escala de -80 a 140 para deixar algum espaço acima e abaixo das barras. Ex: chds=0,150&

“chxl” Todos os rótulos de eixo são separados por uma barra vertical “|”.Os rótulos de eixo devem ser especificados em seqüência (0, seguido de 1, seguido de 2 e assim por diante). Ex: chxl=0:|25|26|27|28|29&

Formatação do Gráfico
“chls” Especifica os estilos de linha. Espessura da linha, comprimento da linha contínua, comprimento do segmento em branco. Ex: chls=2,1,0& linha de espessura média (2), linha não tracejada (1,0).

“chco” Especifica as cores das linhas, barras etc. Todos os valores de cores são números hexadecimais no formato RRGGBB. Ex: chco=DE091A,EBB671& mostra dois conjuntos de linhas/barras.

“chf” Especifica o preenchimento sólido com “bg ou c ou a,s,cor|”, onde “bg” para preenchimento de plano de fundo, “c” para preenchimento da área do gráfico ou “a” para aplicar transparência ao gráfico inteiro. é um número hexadecimal em formato RRGGBB. Ex: chf=c,lg,45,ffffff,0,b1cbfa,0.75|bg,s,fcfcfc&

“chm” Para colocar valores e marcadores sobre os pontos dos gráficos. São muitos os detalhes relativos a esse parâmetro. Sugiro consultar diretamente a documentação na Google: http://code.google.com/intl/pt-BR/apis/chart/#shape_markers2

“chma” Define as margens do gráfico. Use chma=esquerda,direita,topo,baixo. Ex: chma=30,20,20,30&

Por exemplo o gráfico de linha que utilizaremos no tutorial, seria gerado a partir da seguinte url:

http://chart.apis.google.com/chart?
chd=t:108,111,111,111,120&
chxl=0:|25|26|27|28|29&
chm=o,FF0000,0,0,6,0|o,FF0000,0,1,6,0|o,FF0000,0,2,6,0|o,FF0000,0,3,6,0|o,FF0000,0,4,6,0|
t108,FF0000,0,0,10,0|t111,FF0000,0,1,10,0|t111,FF0000,0,2,10,0|t111,FF0000,0,3,10,0|t120,FF0000,0,4,10,0&
cht=lc&
chxt=x,y&
chs=430x225&
chds=0,150&
chxr=1,0,150&
chco=FF0000&
chls=2,1,0&
chf=c,lg,45,ffffff,0,b1cbfa,0.75|bg,s,fcfcfc&
chma=30,20,20,30&
chdl=Tickets+Abertos&
chdlp=b

Criação do Modelo

1.Execute o comando de criação do modelo “backlogs”:

ruby script/generate model backlogs project_id:integer
back_date:date back_abertas:integer back_fechadas:integer back_total:integer

2.Execute a migração:

rake db:migrate

Instalação do Google Charts API

1.Instale a gem do Google Charts API. Mude para o diretório raiz do redmine e digite o seguinte comando:

gem install googlecharts

2.Adicione a nova gem no ambiente de sua aplicação. Edite o arquivo redmine/config/environment.rb e acrescente a linha: config.gem “googlecharts”, :lib => “gchart”

Rails::Initializer.run do |config|
  config.gem "googlecharts", :lib => "gchart"
end

3.Edite o arquivo redmine/app/controllers/application.rb e acrescente a linha: require “gchart”

require "gchart"
class ApplicationController < ActionController::Base
...

Implementação dos gráficos no Redmine

1.Edite o arquivo “redmine/app/controllers/projects_controller.rb” e insira as seguintes linhas:

  def graficos_backlog
    dados = ""
    legenda = ""
    pontos = ""
    pontos_barras = ""
    dados_abertas = ""
    dados_fechadas = ""
    max_total = 0
    max_abertas = 0
    max_fechadas = 0

    nponto = 8

    Backlogs.find(:all, :conditions => {:project_id, @project.id}, :o rder => "id desc", :limit => 9).each do |s|
      dados = "," + s.back_total.to_s() + dados
      dados_abertas = "," + s.back_abertas.to_s() + dados_abertas
      dados_fechadas = "," + s.back_fechadas.to_s() + dados_fechadas
      legenda = "|" + s.back_date.strftime("%d/%m") + legenda
      pontos = "|o,FF0000,0," + nponto.to_s() + ",6,0|t" + s.back_total.to_s() + ",FF0000,0," + nponto.to_s() + ",10,0" + pontos
      pontos_barras = "|t" + s.back_abertas.to_s() + ",FF0000,0," + nponto.to_s() + ",10,0|t" + s.back_fechadas.to_s() + ",FF0000,1," + nponto.to_s() + ",10,0" + pontos_barras

      nponto = nponto - 1

      if max_total < s.back_total
         max_total = s.back_total
      end

      if max_abertas < s.back_abertas
         max_abertas = s.back_abertas
      end

      if max_fechadas < s.back_fechadas
         max_fechadas = s.back_fechadas
      end
    end

    if dados.length > 0
      dados = "chd=t:" + dados[1, dados.length] + "&"
      dados_abertas = "chd=t:" + dados_abertas[1, dados_abertas.length] + "|" + dados_fechadas[1, dados_fechadas.length] + "&"
      legenda = "chxl=0:|" + legenda[1, legenda.length] + "&"
      pontos = "chm=" + pontos[1, pontos.length ] + "&"
      pontos_barras = "chm=" + pontos_barras[1, pontos_barras.length] + "&"

      # define pontos maximos dos graficos
      if max_total > 10
         multi = 1.1
      else
         multi = 2
      end

      max_graf_linha = "chds=0," + (max_total * multi).to_i().to_s() + "&chxr=1,0," + (max_total *multi).to_i().to_s() + "&"

      if max_abertas > max_fechadas
         max_barra = max_abertas
      else
         max_barra = max_fechadas
      end

      if max_barra >= 10
         multi = 1.1
      else
         multi = 2
      end

      max_graf_barra = "chxr=1,0," + (max_barra * multi).to_i().to_s() + "&chds=0," + (max_barra * multi).to_i().to_s() + "&"

      # define parametros de saida
      custom_linha = dados + legenda + pontos + max_graf_linha + "cht=lc&chxt=x,y&chs=430x225&chco=FF0000&chls=2,1,0&chf=c,lg,45,ffffff,0,b1cbfa,0.75|bg,s,fcfcfc&chma=30,20,20,30&chdl=Tickets+Abertos&chdlp=b"
      custom_barra = dados_abertas + pontos_barras + legenda + max_graf_barra + "cht=bvg&chs=430x225&chco=DE091A,EBB671&chbh=15,0,12&chxt=x,y&chs=430x225&chdlp=b&chdl=Abertos|Fechados&chf=c,lg,45,ffffff,0,b1cbfa,0.75|bg,s,fcfcfc&chma=30,20,20,30"
    else
      custom_linha = ""
      custom_barra = ""
    end

    {:custom_linha => custom_linha, :custom_barra => custom_barra}
  end

2.Ainda no arquivo “redmine/app/controllers/projects_controller.rb”, na definição da ação “Show” insira a seguinte linha:

    @graficos_backlog = graficos_backlog

3.No arquivo “redmine/app/views/projects/show.rhtml”, insira as seguintes linhas:

    <%= Gchart.line :size => '430x225',
                    :custom => @graficos_backlog[:custom_linha],
                    :format => 'image_tag' %>

3.Ainda no arquivo “redmine/app/views/projects/show.rhtml”, insira as seguintes linhas:

    <%= Gchart.bar :size => '430x225',
                   :custom => @graficos_backlog[:custom_barra],
                   :stacked => false,
                   :bar_width_and_spacing => '15,0,5',
                   :format => 'image_tag' %>

4.Inclua no arquivo “redmine/config/routes.rb” a linha:

map.resources :graficos_backlog

5.Reinicie o serviço do redmine para que as alterações tenham efeito.

O resultado final deve ser semelhante a tela abaixo:




Todos os arquivos mencionados nesse tutorial, podem ser baixados aqui, para que possam ter certeza onde inseri as linhas que mencionei.


Referências:
    API do Google Chart – Guia do desenvolvedor
    Google Charts With Rails
    Sexy Charts using Google API & Ruby



Post visualizado 1.678 vezes.

Trackback esse post | Subscreva os comentários pelo RSS Feed

Deixe um comentário