速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

Rails 中精彩的图表

  • 2010-06-07
  • 本文字数:5751 字

    阅读完需:约 19 分钟

当分析完数据库中的数据,需要将结果以某种形式展示给用户的时候,有些 Web 应用程序比较偏好采用报告的形式。不过,图表的优点是能够根据报告,给出直观的视觉展现,并且可以帮助开发者观察趋势以及简化数据的综合分析过程。有很多技术能够帮助开发者构建出这类应用程序,Ruby on Rails 就是其中之一。在本文中,我们将会详细介绍如何使用 Ruby on Rails 创建图表。

优秀的软件能够从数据库中的数据或者报告中快速高效地生成图表。Gruff、JFreeChart、XML/SWF charts 和 FusionCharts 是 Ruby on Rails 上为数不多能满足我们需求的软件。不过你得明白,并不是所有这些软件我们都试用和测试过,所以下面的信息大部分是取自产品文档。

类型 Ruby 类 Java Class 文件 Flash 图表组件 Flash 图表组件 Flash 图表组件 操作系统平台 平台独立 平台独立 平台独立 平台独立 平台独立 是否需要 Adobe Flash 插件 不是 不是 是 是 是 是否可用于高级数据分析 不可以 可以 可以 不可以 可以 是否需要安装软件或者其他插件 需要,需要安装 RMagick,ImageMagick 和 Gruff 需要,JDK 1.3 版或更高 不需要 不需要 不需要 能否生成动态图表 不能 是否支持输出到图片 支持 支持 支持 不支持 支持 UTF8 支持 文档未提及 易用性 易用,但是需要写很多代码 并不易用。对用户较友好 很复杂,太多用于配置图表的 xml 标记 非常易用,开发者和用户都可以轻易上手 非常易用,开发者和用户都可以轻易上手 2D/3D 条形图支持 折线图支持 散点图支持 面状图支持 2D/3D 饼图支持 2D/3D 环状图支持 是,以环形图形式 甘特图支持 是(FusionWidgets v3 的一部分) 混合图支持 仪表图支持 是(XML/SWF 标准的一部分) 是(FusionWidgets v3 的一部分) 实时图支持 是(FusionWidgets v3 的一部分) 数据驱动地图 是(FusionWidgets v3 的一部分)本文中,我们将会研究如何使用 FusionCharts 和 MySQL 在 Rails 中绘制图表。FusionCharts 是一个基于 Flash 的图表生成组件,它能够帮助开发者创建可交互的动态图表。同样,它也可以和任何一种 Web 脚本语言绑定,以最少的代码绘制出优秀的图表。不仅如此,FusionCharts 甚至可以封装成模块并在 RoR 中使用。易于使用、多种图表类型支持、优秀的文档以及良好的支持是本文我们介绍 FusionCharts 的原因。

这篇文章以一个应用程序为例,描述了在 RoR 下 FusionCharts 生成图表的机制。这个应用完整运行所需要的软件有:

• FusionCharts 免费版 / v3:

FusionCharts 免费版可以从 www.fusioncharts.com/free 下载。而功能更全面的商业版可以从 www.fusioncharts.com 上下载。在本文中,我们使用的是免费版。

FusionCharts 的安装需要将安装包中的 SWF 和.rb 文件拷贝到合适的位置。.rb 文件是在 Download Package > Code > RoR > Libraries 目录下。

• Ruby 1.8.6 或更高版本:

下载地址是 http://www.rubyonrails.org/down

• Rails gem 2.0.2 或更高版本:

在 RubyGems 加载之后,如果要完整安装 Rails 以及其依赖包,你可以输入如下命令:

gem install rails

Rails 也可以从此页面下载。

• MySQL 4.0 或者更高版本:

MySQL 可以从此处下载。

这里我们以一个计时器为例。这个程序是为员工设计的,员工需要填写每周的上班时间,并且可以查看自己的工时表。本文将会从两个部分来讨论这个应用程序。第一个部分将处理开发上的问题,包括列举、编辑、展示和删除雇员以及工时表。如果你已经有一个需要集成图表的应用程序,你可以跳过这部分,然后直接进入下一个部分,下个部分将会阐述如何将图表和应用程序集成在一起。本文假设读者有基本的 Ruby on Rails 的知识。

创建基本的计时器程序

在脚手架框架(scaffolding framework)的帮助下,一些基本功能,例如列举、编辑、展示和删除雇员以及时间表,可以很简单地生成出来。生成基本的员工和时间表控制器的命令如下:(运行第一个命令后,在创建的 TimeTrackerApplication 目录下运行后面两个命令)

复制代码
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

下一步,你需要修改 config 文件夹里面的 database.yml,让其指向“timetrackerdb”,并且配置好用户名和密码。运行如下命令创建数据库:

复制代码
rake db:create
rake db:migrate

在 mysql 中运行如下命令,创建 employees 和 timetables 表的外键。

复制代码
alter table timesheets add constraint fk_employee_id foreign key fk_employee_id(employee_id) references employees(id) on delete cascade

当然,创建外键的方法有多种;不过如果要深入下去,那么就超出了本文的讨论范围。你需要在模型之间创建关联才能够在 Ruby on Rails 中表示外键。

在 Employee 模型中,在类声明语句后,加入如下语句:

复制代码
has_many :timesheets

而在 Timesheet 模型你需要加入:

复制代码
belongs_to :employee

运行 sql 脚本 db/sampledata.sql 将样例数据插入到数据库中。至此,基本的程序和数据已经就绪,你可以增加、查看、编辑和删除雇员。

在应用程序中集成图表

当程序就绪之后,下面我将介绍如何生成一名员工的工作时间图表:

• 将 FusionCharts 文件夹(Download Package > Code > FusionCharts)拷贝到 TimeTrackerApplication 的public目录下。

• 将Download Package > Code > FusionCharts 文件夹中的FusionCharts.js 拷贝到public/javascripts文件夹下。

• 将Download Package > Code > RoR > Libraries文件夹中的 fusioncharts_helper.rb 拷贝到 TimeTrackerApplication 的lib目录下。

至此,FusionCharts 的安装就已经完成了。

员工名单页中需要一个指向 Time Tracker Chart 的链接。这样,每个雇员都可以查看自己的工时图表。链接是在 app/views/employees/index.html.erb 文件中创建。列表 1 详细描述了链接创建的方法。这段代码是把这个链接加到此页面的其他链接之后。

列表 1

复制代码
<td><%= link_to 'Time Chart', {:action=>'view_timesheet_chart',:id=>employee.id} %></td>

图 1 展示的是员工名单页面。在设置完数据库之后,开发者使用 Ruby 脚手架框架,可以很容易地实现这个功能。我们可以访问“ http://yourserver :port/employees”来查看此页面。图 1 是屏幕部分截图。

图 1

点击“Time Chart”链接将会调用 employees 控制器的 view_timesheet_chart 动作。列表 2 列出了它的代码。这个动作的作用是展示选中员工的工时表。它会向 Employee 模型查询指定员工在“2008-12-01”至“2008-12-07”这段时间的工时表,得到结果之后,渲染“view_timelog_chart.html.erb”文件。为了简单起见,在本文中,这个时间范围是固定的。当然,现实世界中,这个时间范围应该是可由员工指定。

列表 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

这个动作以员工 id 为参数,它向 Employee 模型查询指定员工在特定时间范围内的工时表。我们将在 Employee 模型中加入如列表 3 所示的函数:

列表 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

最后,这个动作会渲染“view_time_chart.html.erb”文件。“view_time_chart.html.erb”模板使用的布局模板是“employee.html.erb”,所有 employees 控制器的视图都会采用这个布局模板。

列表 4

view_timesheet_chart.html.erb (在 app/views/employees 文件夹中)

复制代码
<%= javascript_include_tag "FusionCharts"%>
<%
#xml 文件内容以字符串的形式从模板生成器中得到
str_xml = render "employees/timesheet_data"
#创建图表 - 3D 柱状图,它的数据来自于 strXML
<b>render_chart '/FusionCharts/Column3D.swf' , '' , str_xml , 'TimeChart' , 650 </b>, <b> 400 </b>, <b> false </b>, <b> false do </b>-%>
<% <b> end </b>-%>

从上面的代码,我们知道了如何在视图页面中渲染图表:

  1. 引入 FusionCharts.js 文件。
  2. 从生成器中获取 xml 数据.(生成器的数据来源是控制器)
  3. 使用合适的参数调用render_chart函数渲染图表,

通常情况下,图表会以甘特图的形式表示,当然 FusionCharts 也支持这种形式。在此,简单起见,我们使用了柱状图。

第二步和 XML 的生成有关。FusionCharts 使用 XML(扩展标记语言)创建和操作图表。整个 FusionCharts 图表都是由 XML 控制。例如,你可以使用 XML 定义图表的外观,也可以定义图表的功能。每种图表都有大量特性可供选择。FusionCharts 也有自己的 XML 结构。现在讨论的图表是单系列图表(只有一个数据集),表示员工每周工作的天数和每天工作的时间。列表 5 是这个图表可以使用的一个 XML 例子。

列表 5

单系列图表 XML 样例

复制代码
<graph xAxisName="Day" showValues="1" caption="Time Tracker Chart" numberSuffix=" hrs." subcaption="For Employee John Wilson" yAxisName="Hours Spent">
<set name="Monday" value="8" color="AFD8F8"/>
<set name="Tuesday" value="6" color="F6BD0F"/>
<set name="Wednesday" value="5" color="8BBA00"/>
<set name="Thursday" value="9" color="A66EDD"/>
<set name="Friday" value="9" color="F984A1"/>
<set name="Saturday" value="8" color="CCCC00"/>
</graph>

要用现有的数据生成和列表 5 类似的 xml 文件,那么就需要用到生成器。

生成器是如何生成图表 XML 的呢?它会用到控制器动作中的 @employee_details_with_timesheets变量来构建出图表 XML。列表 6 展示的是这个生成器的实现。

列表 6

timesheet_data.builder (在 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

在生成器中,你首先要创建一个 XMLMarkup 对象,将其“indent”属性赋值为 0,然后可以开始使用这个对象来构建 XML 了。

配置图表的所有选项都被放到了一个名为 options 的散列表中。如果希望了解更多 options 的信息,可以参考完整的 FusionCharts 文档。XML 文件的 root 元素是“graph”,其子节点是“set”,一个“set”节点表示一个特定员工的工时表。每一个“set”元素都有 name 和 value 属性。name 字段表示一周的第几天,而 value 字段表示的是在这一天中,当前员工的工作小时数。生成器使用控制器动作中的@employee_details_with_timesheets变量来存储这些值。

最后,在视图页中,render_chart 函数将会渲染出图表。这个函数的参数是 swf 图表名称、url、width、height、debugMode 和 registerWithJS。它可以在 lib 文件夹的 fusioncharts_helper 模块中找到。正如列表 7 所示,引入 application_helper.rb 之后,就可以在所有的视图中使用这个函数。

列表 7

application_helper.rb

复制代码
require 'fusioncharts_helper'include FusionChartsHelper

展示图表的 swf 文件在 public/FusionCharts 文件夹中。这里我们已经使用了 Column3D.swf 这个文件名,但是也可以生成任意名字的其他任何单系列的图表。而且,数据不仅仅可以从 dataXML 方法得到,也可以从 dataURL 中获取。这种用法在 FusionCharts 的文档中有举例。

现在,在员工列表页面中点击一个员工的“Time Chart”链接,从 01/12/2008 到 07/12/2008 这一周的工作时间将会以图表的形式展现出来。就像图 2 一样。

图 2

如何生成图表概述:

设置完 FusionCharts,并且引入了 application_helper.rb 中的 FusionChartsHelper 之后,按照如下步骤生成图表:

  1. 控制器动作负责从数据库中寻找所需数据。
  2. 根据当前数据编写生成器。
  3. 在第一步提到的控制器动作所绑定的视图中,开发者有两种方式从生成器中取得 XML,一种是直接将数据传递给生成器,或者让生成器从控制器动作中获取数据。
  4. 下一步,使用合理的参数(包括从第三步中得到的 XML)调用 render_chart 函数。

通过一个计时器的讲解,你已经学到了如何在 Ruby on Rails 中使用 FusionCharts 创建简单的图表。而且,只要对这个程序进行简单的修改,你就能得到一个所有员工的工时图表。或者,你甚至可以深入下去,绘制出某个特定员工的详细工时表。当然,你也可以使用 Ajax 来获取图表。诸如此类的改进数不胜数。FusionCharts 的下载包中就包含了很多值得深入研究的例子。本文讲解的应用程序可以从这里下载。

关于作者:

本文作者有着六年的IT 咨询从业经验,并且对大量的Web 技术感兴趣,包括J2EE 栈、Ruby on Rails 和PHP。

查看英文原文 Amazing Charts In Rails


感谢李明对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。

2010-06-07 22:485076
用户头像

发布了 90 篇内容, 共 34.4 次阅读, 收获喜欢 5 次。

关注

评论

发布
暂无评论
发现更多内容

鸿蒙网络编程系列44-仓颉版HttpRequest上传文件示例

长弓三石

DevEco Studio 开发实例 HarmonyOS NEXT 网络与连接

畅享云边大模型!火山引擎 x 地瓜机器人,大模型网关能力免费开放

火山引擎边缘云

边缘计算 机器人 智能IoT边缘服务 大模型 边缘智能

如何提升汽车行业的项目管理效率?

爱吃小舅的鱼

项目管理 管理项目 汽车行业

HyperWorks批处理网格的类型设置

智造软件

CAE软件 hyperworks BatchMesher

Python淘宝数据挖掘与词云图制作指南

代码忍者

API 接口 pinduoduo API

3D壁纸屏保 Screen Wonders for mac,让屏幕变得如此绚丽!

理理

在昇腾Ascend 910B上运行Qwen2.5推理

GPUStack

AI 大模型 昇腾 生成式AI NPU

科大讯飞学习机怎么样 科大讯飞T30pro建议买吗

妙龙

科大讯飞

SnailSVN Pro for mac SVN客户端

理理

CST软件如何实现S-parameter随其他参数变化的1D曲线

思茂信息

教程 cst cst仿真软件

管理文档必看:8款企业内部工具介绍

爱吃小舅的鱼

文档管理 文档管理软件 文档管理工具

iZotope RX 11 专业音频修复软件

理理

未来已来,软件行业的下一个风口在哪里?

天津汇柏科技有限公司

人工智能 软件

鸿蒙实战开发:网络层的艺术——优雅封装与搭建指南(下)

王二蛋和他的张大花

鸿蒙

IDEA中通义灵码的使用技巧

威哥爱编程

IDEA Java. 通义灵码 AI辅助

【CoCollider】让系统和应用适配如此简单

iofomo

开发 Android; ios 开发 应用适配 API 测试

后勤采购管理系统(源码+文档+部署+讲解)

深圳亥时科技

FlowJo 10:精准分析,展现细胞奥秘

理理

Resolume Arena 7,打造顶级多媒体演出工具

理理

鸿蒙实战开发:网络层的艺术——优雅封装与搭建指南(上)

王二蛋和他的张大花

鸿蒙

浅谈机器学习,聊聊训练过程,就酱!

蛋先生DX

神经网络 机器学习 深度学习

鸿蒙OS创新实践:动态声控话筒开发指南

王二蛋和他的张大花

鸿蒙

TDengine 集群能力:超越 InfluxDB 的水平扩展与开源优势

TDengine

tdengine 时序数据库 数据库·

Native Instruments Guitar Rig 7 Pro for Mac(吉他贝斯效果器)

理理

鸿蒙开发实战:揭秘页面与项目生命周期,实现精准监控

王二蛋和他的张大花

鸿蒙

鸿蒙网络编程系列43-仓颉版HttpRequest下载文件示例

长弓三石

DevEco Studio 开发实例 HarmonyOS NEXT 网络与连接

7thonline第七在线7大价值助力品牌实现智能化商品管理

第七在线

化学绘图 chemdraw 20.0 永久激活码 mac&win

理理

经典gba游戏(寂静岭、节奏天国、机兽新世纪等)游戏合集

理理

平顶山等保测评机构有哪些?电话多少?

行云管家

等保 等保测评 平顶山

堡垒机有远程协助解决难题功能吗?哪家的好用?

行云管家

网络安全 堡垒机

Rails中精彩的图表_Ruby_Srividya Sharma_InfoQ精选文章