As Aplicações Web frequentemente analisam dados no banco de dados gerando relatórios. Os gráficos fornecem uma representação visual dos relatórios, que pode ser usada para facilitar o entendimento e geralmente facilitar a síntese de dados. Ruby On Rails é uma das tecnologias que pode ser usada para criar essas aplicações web com relatórios e gráficos. Neste artigo, nós discutiremos sobre como criar gráficos em Ruby on Rails.
Para gerar gráficos a partir de relatórios ou dados no banco de dados, precisamos de um bom produto de gráficos. Gruff, JFreeChart, XML/SWF charts, FusionCharts são alguns dos produtos disponíveis para Ruby on Rails. A tabela a seguir apresenta uma comparação grosseira destes produtos. Repare que nem todos os produtos foram experimentados e testados. A maior parte da análise a seguir é baseada em informações coletadas a partir da documentação dos produtos.
Gruff | JFreeChart | XML/SWF | FusionCharts Free | FusionCharts v3 (Paid) | |
Tipo | Ruby classes | Java Class files | Flash charting component | Flash Charting component | Flash Charting component |
Sistema de Operação | O/S Independente | O/S Independente | O/S Independente | O/S Independente | O/S Independente |
Adobe Flash Plug-in exigido | Não | Não | Sim | Sim | Sim |
Adequado para Análises de Dados Avançadas | Não | Sim | Sim | Não | Sim |
Qualquer plug-ins ou software podem ser instalados | Sim- RMagick, ImageMagick e Gruff | Sim, JDK versão 1.3 ou posterior | Não | Não | Não |
Os gráficos podem ser animados? | Não | Sim | Sim | Sim | Sim |
Capacidade para salval o gráfico como imagem | Sim | Sim | Sim | Não | Sim |
Suporte UTF8 | Não Documentado | Sim | Sim | Sim | Sim |
Facilidade de Uso em RoR | Sim, mas muita codificação envolvida. | Não muito fácil de usar. Não serve para o usuário final. | Complexo, também muitas tags xml para configurar o gráfico. | Muito fácil de usar. Os desenvolvedores e os usuários final podem usá-lo. | Muito fácil de usar. Os desenvolvedores e os usuários final podem usá-lo. |
Bar Charts 2D, 3D | Sim | Sim | Sim | Sim | Sim |
Gráficos de linha | Sim | Sim | Sim | Sim | Sim |
Gráficos Scatter | Sim | Sim | Sim | Sim | Sim |
Gráficos de Área | Sim | Sim | Sim | Sim | Sim |
Pie 2D, 3D | Sim | Sim | Sim | Sim | Sim |
Doughnut 2D, 3D | Não | Yes, Ring Chart | Sim | Sim | Sim |
Gráficos Gantt | Não | Sim | Não | Sim | Sim ( as part of FusionWidgets v3) |
Gráficos de Combinação | Não | Sim | Sim | Sim | Sim |
Gráficos Gauge | Não | Sim ( como parte de XML/SWF Gauge) | Sim | Não | Sim ( como parte do FusionWidgets v3) |
Gráficos em tempo real | Não | Não | Não | Não | Sim ( como parte do FusionWidgets v3) |
Dados-dirigidos a Mapas | Não | Não | Não | Não | Sim ( como parte do FusionWidgets v3) |
Neste artigo, nós exploraremos os gráficos em Rails utilizando FusionCharts e a base de dados do MySQL. FusionCharts é um componente de gráficos baseado em flash que pode gerar gráficos interativos e animados. FusionCharts pode ser usado com qualquer linguagem de script da web, para entregar gráficos poderosos com a mínima codificação. O FusionCharts vem com módulos para ser usado com RoR. Facilidade para usar, variedades de tipos de gráficos, boa documentação e um bom suporte é a motivação por trás da utilização do FusionCharts para este artigo.
Este artigo descreve o mecanismo de geração de gráficos usando FusionCharts em Ruby on Rails através de uma aplicação de exemplo. Para executar a aplicação de exemplo discutida neste artigo, é necessário o seguinte:
• FusionCharts Free/ v3:
FusionCharts Free pode ser baixado em www.fusioncharts.com/free , ou a versão comercial com mais opções pode ser baixada em www.fusioncharts.com . Neste artigo, usamos a versão gratuita para criar os gráficos.
A instalação do FusionCharts implica apenas em copiar e colar o SWF e os arquivos .rb do pacote de download para a pasta apropriada na aplicação. Os arquivos .rb estão presentes na pasta: Pacote de Download > Code > RoR > Libraries.
• Ruby 1.8.6 ou superior:
Disponível em http://www.rubyonrails.org/down
• Rails gem 2.0.2 ou superior:
Com o RubyGems carregado, você pode instalar o Rails e suas dependências pela linha de comando:
gem install rails
O Rails também pode ser baixado como pacote stand-alone aqui .
• MySQL 4.0 ou superior:
Pode ser baixado aqui .
A aplicação de exemplo desenvolvida para este artigo é uma aplicação time tracker básica. Esta é uma aplicação simples onde um funcionário preenche o tempo para uma semana e vê o gráfico baseado nas horas inputadas. Este artigo discutirá a aplicação de exemplo em duas partes. A primeira parte trata com o desenvolvimento da aplicação básica que inclui listar, editar, mostrar e destruir para employees e timesheets. Se você já tem uma aplicação em que você tem que integrar gráficos, então você pode pular esta parte e ir para a próxima parte, que explica a integração de gráficos com a aplicação. O artigo espera que o leitor tenha um conhecimento básico de Ruby on Rails.
Criando a Aplicação time tracker básica
Usando scaffold, a funcionalidade básica de listar, mostrar, editar e deletar para employees e timesheets pode ser gerado. Os comandos básicos para gerar os controllers employee e timesheet são os seguintes: (executar os dois últimos comandos dentro da pasta TimeTrackerApplication criada com o primeiro comando)
rails –d mysql TimeTrackerApplication ruby script/generate scaffold Employee name:text ruby script/generate scaffold Timesheet log_date:datetime hours_spent:integer employee_id:integer
Em seguida, você deve modificar o database.yml presente na pasta de configuração para apontar para “timetrackerdb” e as entradas do username e password corresponde à seu database. Então, você deve executar os seguintes comandos rake para criar o database,
rake db:create rake db:migrate
Afim de estabelecar o relacionamento (foreign key) entre tabelas employees e timesheets, você deve executar a seguinte query em sua instância do mysql:
alter table timesheets add constraint fk_employee_id foreign key fk_employee_id(employee_id) references employees(id) on delete cascade
Evidentemente, que há outras maneiras de criar foreign keys; uma discussão do que está além do escopo deste artigo. Para representar o relacionamento (foreign key) acima em Ruby on Rails, você terá que criar uma associação entre os modelos.
No modelo Employee, depois da declaração da classe, escreva o seguinte:
has_many :timesheets
E no modelo Timesheet você precisa escrever:
belongs_to :employee
Para inserir os valores do exemplo em seu database, você precisa executar o script sql db/sampledata.sql. A aplicação básica está pronta. Você pode adicionar, visualizar, editar ou deletar employees.
Integrar Gráficos na Aplicação
Com a aplicação time tracker básica no lugar, aqui está o que é necessário para gerar os gráficos de time tracker para um employee:
• Copiar a pasta FusionCharts disponível no download do FusionCharts Free/Pro
(Download Package > Code > FusionCharts), para a pasta public do TimeTrackerApplication.
• Copiar o arquivo FusionCharts.js presente na pasta Download Package > Code > FusionCharts
para a pasta public/javascripts.
• Copiar o fusioncharts_helper.rb da pasta Download Package > Code > RoR > Libraries
para a pasta lib do TimeTrackerApplication.
Isso completa a configuração do FusionCharts.
A partir da página de listagem de employees, um link para o Gráfico Time Tracker precisar ser criado. Assim, para cada employee, haverá um link paragem visualizar seu tempo como um gráfico. O link para o gráfico time tracker é criado no arquivo app/views/employees/index.html.erb. A listagem 1 mostra os detalhes do link adicionado. Adicione este link e depois outros links na página.
Listagem 1
<%= link_to 'Time Chart', {:action=>'view_timesheet_chart',:id=>employee.id} %>
A figura 1 ilustra a página de listagem de employees da aplicação. As características vistas na Figura 1 foram obtidas facilmente através de configuração de database e ruby scaffold como já visto no artigo. Esta página pode ser visualizada acessando o endereço "http://yourserver:port/employees". A parte pertinente desta tela é mostrada na Figura 1.
Figura 1
A action invocada clicando sobre este link "Time Chart" é a ação view_timesheet_chart do controller employees. A Listagem 2 mostra o código para esta ação. Está ação renderiza o gráfico para o employee selecionado. A ação contata o modelo Employee para achar os timesheets para este employee dentro do período de "2008-12-01" à "2008-12-07" e em seguida renderiza o "view_timelog_chart.html.erb". Para manter as coisas simples, o date range foi fixado no controller. Na aplicação do mundo real, o date range para gerar o relatório / gráfico deverá ser selacionado pelo usuário.
Listagem 2
EmployeesController
def view_timesheet_chart start_date= "2008-12-01" end_date="2008-12-07" @employee_id = params[:id] employee_details_with_timesheets = Employee.find_with_timesheets_in_date_range(@employee_id,start_date,end_date) if(!employee_details_with_timesheets.nil?) @employee_details_with_timesheets =employee_details_with_timesheets[0] else @employee_details_with_timesheets =nil; end headers["content-type"]="text/html" end
Usando o employee id como parâmetro, esta action contata o modelo Employee para achar os timesheets para este employee dentro do período especificado. A função a ser adicionada na classe Employee é mostrada na Listagem 3 abaixo:
Listagem 3
Employee.rb
def self.find_with_timesheets_in_date_range(id, start_date, end_date) conditions="employees.id =? and log_date between ? and ?" employee_details_with_timesheets=self.find(:all, :include=>'timesheets', :conditions=> [conditions,id,start_date,end_date], :order=>'log_date asc') return employee_details_with_timesheets end
A action finalmente renderiza "view_time_chart.html.erb". A template "view_timelog_chart.html.erb" usa o layout "employees.html.erb" que é comum a todas as views do controller de employees. Assim, o código na view é curto e doce como visto na Listagem 4.
Listagem 4
view_timesheet_chart.html.erb (in app/views/employees folder)
<%= javascript_include_tag "FusionCharts"%> <% # O xml é obtido como uma string do builder template. str_xml = render "employees/timesheet_data" #Criar o Gráfico - Coluna 3D Chart com dados do strXML render_chart '/FusionCharts/Column3D.swf' , '' , str_xml , 'TimeChart' , 650 , 400 , false , false do -%> <% end -%>
A partir do código acima, entendemos o seguinte como sendo os passos envolvidos para renderizar um gráfico na página view:
- Incluir o arquivo FusionCharts.js.
- Obter os dados xml do builder. ( O builder usa os dados da action do controller para a contrução do xml)
- Renderizar o gráfico chamando a função render_chart com os parâmetros apropriados
Normalmente, o tempo é representado em um gráfico Gantt e este gráfico também está diponível no FusionCharts. Aqui, para sermos mais simples, o gráfico de Coluna foi usado.
O segundo passo envolve a criação do xml. FusionCharts uses XML (eXtensible Markup Language) para criar e manipular gráficos. O gráfico todo do FusionCharts é controlado por parâmetros XML. Você usa XML para definir a aparência e as propriedades funcionais para o gráfico. Há muitas propriedades que você pode definir para cada tipo de gráfico. FusionCharts tem uma estrutura XML específica para cada gráfico. O gráfico em discussão é um gráfico de uma única série (com apenas um conjunto de dados), representando o dia da semana e o número de horas gastadas pelo empregado nesse dia. Um xml de exemplo para este gráfico é mostrado na Listagem 5.
Listagem 5
Sample Single-Series Chart XML
Para gerar um xml semelhante ao mostrado na Listagem 5 mas com o dado presente no database, o arquivo builder é usado.
Como é que o builder contrói o gráfico xml? O builder constrói o xml para o gráfico usando a variável @employee_details_with_timesheets armazenada na action. A Listagem 6 mostra o conteúdo do arquivo builder.
Listagem 6
timesheet_data.builder (na pasta app/views/employees)
xml = Builder::XmlMarkup.new(:indent=>0) options = { :caption=>'Time Tracker Chart', :subcaption=>'For Employee '+ @employee_details_with_timesheets.name , :yAxisName=>'Hours Spent', :xAxisName=>'Day', :showValues=>'1', :formatNumberScale=>'0', :numberSuffix=>' hrs.' } xml.graph(options) do for timesheet in @employee_details_with_timesheets.timesheets do log_day = timesheet.log_date.strftime('%a') xml.set(:name=>log_day,:value=>timesheet.hours_spent,:color=>''+get_FC_color) end end
No builder, você deve primeiro criar um novo objeto XMLMarkup com o valor para "indent" igual a zero e usar este objeto para a contrução do xml.
Todas as opções requeridas para a configuração do gráfico está presente em um hash chamado options, que é passado para a alta tag acima (graph). Para obter detalhes das opções que podem ser passadas para o gráfico, por favor consulte a documentação completa do FusionCharts. O elemento xml raiz é "graph". Dentro deste, existe um elemento "set" correspondente a cada timesheet do employee selecionado. Cada elemento “set” tem nome e valor como atributos. O nome deve conter o dia da semana e o valor conterá as horas gastas pelo employee neste dia. O builder usa a variável @employee_details_with_timesheets da action do controller, para obter estes valores.
Finalmente, na página view, o gráfico é renderizado usando o método render_chart que recebe o nome do arquivo swf do gráfico, a url, o xml, largura (width), altura (height), debugMode e registerWithJS como parâmetros. Esta função está diponível no módulo fusioncharts_helper presente na pasta lib. Isto pode ser acessado de todas as views incluindo o application_helper.rb como mostrado na Listagem 7.
Listagem 7
application_helper.rb
require 'fusioncharts_helper' include FusionChartsHelper
Os arquivos swf necessários para mostrar os gráficos estão presentes na pasta public/FusionCharts. Aqui o Column3D.swf foi utilizado mas qualquer outro tipo de gráfico de série única poderia ser gerado apenas mudando o nome do arquivo swf. Os dados foram fornecidos usando o método dataXML mas os dados tembém podem ser fornecidos através de um dataURL. Exemplos disto estão presentes na documentação do FusionCharts.
Agora, clicando no link "Time Chart" para um employee na página de listagem de employees, os registros de tempo para a semana 01/12/2008 à 07/12/2008 são apresentados na forma de um gráfico. O gráfico de timesheet será semelhante ao da Figura 2 mostrada abaixo.
Figura 2
Sumário das etapas para gerar um gráfico:
Após a configuração do FusionCharts na aplicação e inclusão do FusionChartsHelper no application_helper.rb, os passos são os seguitens:
- Na action do controller, busque os dados necessários para o gráfico no database.
- Escreva um builder para construir o xml do gráfico a partir destes dados.
- Na view referente à action do controller do passo 1, obter o xml a partir do builder, passando os dados para ele ou deixando o builder usar os dados a partir da action do controller.
- Em seguida, chamar a função render_chart com parâmetros apropriados (incluindo o xml obtido no passo 3)
Neste artigo, você aprendeu como criar um gráfico simples usando FusionCharts em Ruby on Rails através da aplicação time tracker. Com algumas modificações para a aplicação de exemplo, você pode criar um gráfico com um overview de tempo para todas os employees. Provavelmente, a partir deste gráfico você pode entrar nos datelhes de um determinado employee para obter os detalhes de tempo para ele. Você pode usar Ajax para mostrar o gráfico. As possibilidades são inúmeras. O download do FusionCharts contém vários exemplos que podem ser explorados. A aplicação de exemplo deste artigo está disponível para download aqui.
Sobre o Autor:
O autor é um consultor com mais de 6 anos de experiência na indústria de TI e tem interesse em uma variedade de tecnologias web, envolvendo J2EE, Ruby On Rails & PHP.