最近需要给抢座增加图表功能,于是对Rails的图表方案做了些调查,整理成这篇贴,希望对有同样需求的人有所帮助。 Google Chart Google Chart的优点是接口简单,容易上手,但是缺点也很明显,需要依赖Google的服务,在有些地方加载可能会存在速度问题,并且有被GFW的风险。 Google Chart的Rails插件很多,个人比较喜欢mattetti的googlecharts: googlecharts: http://github.com/mattetti/googlecharts gchartrb:http://code.google.com/p/gchartrb google-charts-on-rails:http://code.google.com/p/google-charts-on-rails/ gc4r:http://code.google.com/p/gc4r/ Google Visualization Google Visualization是Google Chart的升级版,Rails插件:http://github.com/mwarnock/rails-google-visualization-plugin Gruff Gruff是基于RMagick的Ruby绘图工具,功能强大,可扩展性和可定制性都非常好,不过由于Gruff需要在服务端实时生成图片,因此不适合实时展示数据。 Gruff还有一个JS封装bluff:http://bluff.jcoglan.com/ Flot Flot是一个jQuery插件,可以基于JS生成实时图表,如果你使用jQuery,那么Flot是个不错的选择。Flot有一个很好用的Rails插件插件Flotilla: http://github.com/joshuamiller/flotilla GNUPlot GNUPlot最初是为学术目的使用的数据可视化工具,但是现在也支持生成非交互式的2d和3d图形,如果你需要生成非常复杂的图形,那么可以试试gnuplot,GNUPlot有一个叫rgplot的rubygem可以使用:http://rgplot.rubyforge.org Ziya Ziya是一个Rails图表插件,可以生成非常漂亮和复杂的Flash图表,如果你不介意Flash,那么Ziya是个不错的选择。 Scruffy Scruffy是一个Rubygem,它的目标是帮你生成高质量的SVG和PNG图片,同Gruff一样,是一个服务端解决方案,不过Scruffy目前似乎已经停止开发了,首页的图片在Firefox和Chrome下均无法显示。 Highcharts 感谢dxiao同学留言,Highchars是一个纯JS的图表库,但是实现的效果却和Flash不相上下,相当绚丽,兼容性也很不错,并且有一个Rails的插件可以用,值得一试。 Raphaeljs 感谢Quake推荐,Raphael也是一个非常不错的JS绘图控件,他的核心库是raphaeljs,一个画图工具,详情可以看官方网站 : http://g.raphaeljs.com/ Flash 除了上面介绍的Ziya,Flash图表解决方案还有很多,下面列举几个对Rails支持比较好的: Open Flash Chart II:http://pullmonkey.com/projects/open_flash_chart2/ Fusion Charts Free:http://www.fusioncharts.com/free/ maani.us xml/swf charts:http://www.maani.us/xml_charts/ amcharts: http://www.amcharts.com/,archarts有一个很好用的Rails插件:ambling 参考:http://stackoverflow.com/questions/87561/what-is-your-preferred-way-to-produce-charts-in-a-ruby-on-rails-web-application
Category Archives: 插件
ar_mailer Rails 3 插件
ar_mailer是个很不错的邮件发送插件,工作原理是将邮件发送分为两部分,首先将邮件保存到数据库,然后在调用后台程序实现异步发送,可惜的是目前还不支持Rails 3,于是花了一个下午,将它移植到了Rails 3,这就是:ar_mailer_rails3。 安装 sudo gem install ar_mailer_rails 使用 script/rails generate ar_mailer_rails3 Email 你也可以将Email替换为其它名字,邮件将会被保存到这个Model中。 Generator会自动生成一个initializer: # config/initializers/ar_mailer.rb ActionMailer::Base.add_delivery_method :active_record, ArMailerRails3::ActiveRecord, :email_class => Email ActionMailer::Base.delivery_method = :active_record 如果你不希望所有Mailer都使用ActiveRecord发送,也可以在Mailer中单独定义: class MyMailer < ActionMailer::Base self.delivery_method = :active_record end 命令行的使用方式和ar_mailer是一样的,只不过为了和ar_mailer 2保持兼容,命令行的程序变成了ar_mailer_rails3: $ ar_sendmail_rails3 -h 详细的使用方法可参看这里
豆瓣API Rails 插件
目前只支持Rails 3 beta,地址:http://github.com/yzhang/douban 安装 $ gem install douban 使用 1. 修改Gemfile: gem ‘douban’, :require => ‘oauth’ require ‘douban’ 2. 运行generator $ script/rails generate douban 3. 修改config/douban.yml, 并在ApplicationController中包含DoubanHelper: class ApplicationController include DoubanHelper end 4. 然后在你的application layout中加入: <% if douban_authorized? %> <%= link_to ‘注销豆瓣登录’, douban_logout_path %> <% else %> <%= link_to “使用豆瓣帐号登录”, douban_login_path %> <% end %> [...]
快钱Rails插件
演示站点:http://kqdemo.zaituu.com 演示代码:http://github.com/yzhang/kuaiqian_demo 插件地址:http://github.com/yzhang/kuaiqian 安装 $ script/plugin install git://github.com/yzhang/kuaiqian.git 使用 1. 安装完成后,插件会自动在你的应用的config目录创建一个kuaiqian.yml文件,默认是快钱提供的测试帐号(关于测试帐号的使用方法请参看测试章节)。将kuaiqian.yml中的商户ID和密钥替换为快钱提供给你的真实ID和密钥然后进行下一步。 2. 下面的代码会创建一笔新订单: @request = Kuaiqian::Request.new(‘产品名称’, # 产品名称 1, # 订单ID,必须全局唯一 Time.now.strftime(“%Y%m%d%H%M%S”), # 订单生成时间,格式为20091104174132 4500, # 订单金额,以分为单位 ’http://return’, # 通知地址,用户支付成功后快钱会通过此地址通知商户支付结果 ’00′, # 支付类型,00显示所有方式,10只显示银行卡方式,11只显示电话银行方式,12只显示快钱帐户支付方式,13只显示线下方式 ’attach’) #自定义数据,会在返回URL中原样返回 redirect_to @request.url 上面的代码会将用户重定向到快钱的支付页面。 3. 在用户完成支付后,快钱会调用你在支付请求中提供的返回URL: @response = Kuaiqian::Response.new(params) if @response.successful? # 支付成功 else # 支付失败 end 注意,快钱可能会多次调用你的返回URL,并将结果展现给用户,因此你的代码要考虑多次执行后的输出对用户的有好度。 同时Response还提供了以下方法供用户检查响应的有效性: pay_amount # [...]
财付通Rails插件
最近需要给(ZT)增加在线支付功能,比较了国内的各种支付方案,最后选择了财付通,申请比较简单而且没有年费,但是腾讯官方只提供了PHP,JSP和ASP的代码,只能自己写了一个Rails的。 安装 $ script/plugin install git://github.com/yzhang/tenpay.git 使用 1. 插件安装后,会在你的config目录下创建一个tenpay.yml文件(默认是腾讯提供的测试帐户,往这个帐户付款它居然真的就收了,虽然只是1分钱),你需要修改这个文件,填入你从腾讯申请的商户号(spid)和密钥(key)。 2. 下面的代码演示如何创建一个新交易: @request = Tenpay::Request.new(‘测试产品’, # 产品名称 1, # 订单编号,需要保证全局唯一 4500, # 产品价格,以分为单位 ’http://return’, # 用户完成支付后返回的URL, 支持Get/Post request.remote_ip, #用户IP,用户production模式下检验用户,development模式忽略。 ’attach data’) # 商户数据,会原样传递给返回URL,可不填 redirect_to @request.url 用户访问这个action的时候会被引导到支付页面。 3. 用户完成支付后,需要返回商户页面,也就是你在请求中填写的返回URL,下面的代码用于验证请求是否有效: @response = Tenpay::Response.new(params) if @response.successful? # 支付成功 else # 不合法的请求或支付失败 end 目前还不支持查询接口,欢迎大家的意见和建议。
city_helper: 省市二级联动Select插件
此插件已更新,请移步这里: http://www.letrails.cn/archives/city-helper-update-i18n-and-country-support/ city_helper提供了几个简单的helper来实现省及城市的二级联动select,目前只支持国内城市,经过测试的浏览器:FF3, Chrome 2 beta, IE7, Safari 4。 安装 $ script/plugin install git://github.com/yzhang/city_helper.git 使用 安装之后,你就可以在View中直接使用以下Helper了: state_select :user, :state # 选择省份 capital_select :user, :city # 选择省会城市 city_select :user, :city # 选择所有地级及地级以上城市 state_and_city_select :user, :state, :city # 省市二级联动select 当然,你也可以在FormBuilder中使用,同时还有一个不需要object的_tag版本: form.city_select :city city_select_tag :city 你也可以传递options给city_helper,参数定义同select: city_select :user, :city, options, html_options state_and_city_select :user, :state, :city, {:city => city_options, [...]
theme_support: 为Rails应用添加theme支持
theme_support是Matt McCray写的一个为Rails应用增加类似Typo的theme管理的插件,功能类似于Typo,支持liquid和erb模板。 安装 $ script/plugin install http://mattmccray.com/svn/rails/plugins/theme_support 使用 1. 生成主题 $ script/generate theme [theme_name] 这将在你的Rails应用的跟目录下创建一个themes文件夹: app_root themes/ [theme_name] layouts/ ‘images’ add_named_route ‘theme_stylesheets’, “/themes/:theme/stylesheets/*filename”, :controller=>’theme’, :action=>’stylesheets’ add_named_route ‘theme_javascript’, “/themes/:theme/javascript/*filename”, :controller=>’theme’, :action=>’javascript’ add_route “/themes/*whatever”, :controller=>’theme’, :action=>’error’ end 2. 然后修改actionview_ex.rb,将render_file改为如下定义: def render_file(template_path, use_full_path = true, local_assigns = {}) ["#{RAILS_ROOT}/themes/#{controller.current_theme}/views", # for normal views "#{RAILS_ROOT}/themes/#{controller.current_theme}" # for layouts [...]
Ajax Rating: 简易打分插件
刚完成的一个小插件,比较粗糙,欢迎多提意见。 安装 $ cd vendor/plugins $ git clone git://github.com/yzhang/ajax_rating.git 使用 在你要评分的model中添加acts_as_ratable,比如post: class Post < ActiveRecord::Base :acts_as_ratable end 这为post增加了如下方法: rating,当前post的平均得分 rating_count,评分人数 在可以打分的Model中添加acts_as_rater,比如user: class User < ActiveRecord::Base :acts_as_rater end 这为User增加了如下方法: rating_on(ratable),返回这个用户为某个对象打的分(1-5) 然后在view中调用: rating_tag(rater, ratable) rater就是打分者,ratable则是被评分的对象,如果rater为nil,则用户只能看到分数,但不能打分。 如果需要自定义外观,可以修改rating.css和images下的star123.png,关于CSS的原理说明请参看(十分对不起原作者,找不到原始出处):http://www.viphot.com/InfoView/Article_285645.html 如果为了安全考虑,需要限制只有当前登录用户可以打分,可以通过定义RatingsController#current_rater实现: class RatingsController < ActiveController::Base :before_filter :login_required def current_rater current_user end end 这样客户端传递的rater参数将失去作用。 完整例子 1. 创建demo: $ rails [...]
Engines,Generator以及Rails插件机制
Engines的作用是允许将model,controller和view代码直接嵌入到plugin中,但这其实是同Rails的设计初衷相违背的,这也是为什么DHH反对Engines。Rails针对这种需求提出的解决方案是Generator,相比Generator,Engines让事情变得更简单了一些,使用Engines的好处是,你不再需要生成一堆你可能几百年都不会去看的代码到你的APP目录下,但缺点是一旦你需要对这些代码进行修改,你将不得不再次复制它们到你的app目录下,而且一般来说,这很难避免,并且最终的结果往往是你发现所有代码都需要修改,那为什么不在一开始就用generator将它们全部复制到你的APP目录下呢? 事实上,Generator也不是个好方法,之所以要将代码复制到你的App目录下,而不是放在Plugin中,是因为你需要修改它,而且在大部分情况下你期望对这些生成代码的修改能够复用到不同的项目中,但是使用Generator,你无法复用对这部分代码的修改,而只能一遍遍的重复“生成-修改”的过程,或者从其它项目中copy生成的代码到新项目,但这是个繁琐的过程,John Long在06年的时候就注意到了这个问题,并且他发现Django的解决方案不错,他在05年底的时候帮助组织了Adrian Holovaty(Django之父)和DHH之间的一场讨论,本来他希望看到Django中的一些优秀思想被吸收到Rails中来,但是遗憾的是,这一幕没有发生,直到Rails 2.0,Rails的插件模式并没有发生什么大的变化。 Django的解决方案是将Plugin组织成一个个的mini app而不是Rails的插件,这些mini app同你的app是并列的,要加入一个新的mini app,只需要修改INSTALLED_APPS 即可: INSTALLED_APPS = ( ‘django.contrib.auth’, ‘django.contrib.contenttypes’, ‘django.contrib.sessions’, ‘django.contrib.sites’, ‘mysite.polls’ ) 这样如果你对某个mini app做了修改,在下一个项目中,你只需要将这个mini app直接copy到新项目中即可。 实际上,将Rails的plugin变成Django的mini app也并不难,只需要将Plugin目录变成在development模式下每次重新加载,然后加强路由支持即可,当然更进一步,实际上应该将Rails的插件两类,包含MVC代码的和不包含MVC代码的,John Long已经在Radiant中实践了这个想法,他给包含MVC代码的插件起的名字是extensions。 不过就目前来说,如果你确定你不会修改Plugin中的代码(一般来说发生几率相当小),那么Engines是个不错的选择,否则还是Generator好一些。 参考: Rails Needs Something Better Than Engines Why engines and components are not evil but distracting
自定义will_paginage输出
will_paginate是Rails中比较常用的分页插件,但是有时候我们可能想要自定义它的输出,这可以通过扩展WillPaginate::LinkRenderer类来实现,比如,下面的renderer将会去除Next和Previous链接(来自这里): class CustomPaginationRenderer < WillPaginate::LinkRenderer def to_html links = @options[:page_links] ? windowed_links : [] html = links.join(@options[:separator]) @options[:container] ? @template.content_tag(:div, html, html_attributes) : html end end 要在view中使用这个自定义的renderer,只需要加上:renderer参数即可: <%= will_paginate @items, :renderer => ’CustomPaginationRenderer’ %> 下面给出一个更复杂的自定义Renderer,它会在分页链接后显示一个文本框,以及一个‘Goto’按钮,允许用户直接跳转到某一页: class CustomPaginationRenderer < WillPaginate::LinkRenderer @@id = 1 def to_html links = @options[:page_links] ? windowed_links : [] # previous/next buttons links.unshift page_link_or_span(@collection.previous_page, ‘disabled’, @options[:prev_label]) links.push page_link_or_span(@collection.next_page, ‘disabled’, @options[:next_label]) html = links.join(@options[:separator]) html += goto_box @options[:container] ? @template.content_tag(:div, html, html_attributes) : html [...]
