sparklines.rb
来自「用ruby on rails写的一个博客程序,还不错..ruby on rail」· RB 代码 · 共 436 行 · 第 1/2 页
RB
436 行
require 'RMagick'require 'mathn'=begin rdocA library (in Ruby!) for generating sparklines.Can be used to write to a file or make a web service with Rails or other Ruby CGI apps.Idea and much of the outline for the source lifted directly from {Joe Gregorio's Python Sparklines web service script}[http://bitworking.org/projects/sparklines].Requires the RMagick image library.==Authors{Dan Nugent}[mailto:nugend@gmail.com]Original port from Python Sparklines library.{Geoffrey Grosenbach}[mailto:boss@topfunky.com] -- http://nubyonrails.topfunky.com -- Conversion to module and addition of functions for using with Rails. Also changed functions to use Rails-style option hashes for parameters.===Tangent regarding RMagickI had a heck of a time getting RMagick to work on my system so in the interests of saving other people the trouble here's a little set of instructions on how to get RMagick working properly and with the right image formats.1. Install the zlib[http://www.libpng.org/pub/png/libpng.html] library2. With zlib in the same directory as the libpng[http://www.libpng.org/pub/png/libpng.html] library, install libpng3. Option step: Install the {jpeg library}[ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz] (You need it to use jpegs and you might want to have it)4. Install ImageMagick from *source*[http://www.imagemagick.org/script/install-source.php]. RMagick requires the ImageMagick headers, so this is important.5. Install RMagick from source[http://rubyforge.org/projects/rmagick/]. The gem is not reliable.6. Edit Magick-conf if necessary. I had to remove -lcms and -ltiff since I didn't want those to be built and the libraries weren't on my system.Please keep in mind that these were only the steps that made RMagick work on my machine. This is a tricky library to get working.Consider using Joe Gregorio's version for Python if the installation proves to be too cumbersome.==General Usage and DefaultsTo use in a script: require 'rubygems' require 'sparklines' Sparklines.plot([1,25,33,46,89,90,85,77,42], :type => 'discrete', :height => 20)An image blob will be returned which you can print, write to STDOUT, etc.In Rails, * Install the 'sparklines_generator' gem ('gem install sparklines_generator')* Call 'ruby script/generate sparklines'. This will copy the Sparklines controller and helper to your rails directories* Add "require 'sparklines'" to the bottom of your config/environment.rb* Restart your fcgi's or your WEBrick if necessaryAnd finally, add this to the controller whose view will be using sparklines: helper :sparklinesIn your view, call it like this:<%= sparkline_tag [1,2,3,4,5,6] %> <!-- Gives you a smooth graph -->Or specify details:<%= sparkline_tag [1,2,3,4,5,6], :type => 'discrete', :height => 10, :upper => 80, :above_color => 'green', :below_color => 'blue' %>Graph types: area discrete pie smoothGeneral Defaults: :type => 'smooth' :height => 14px :upper => 50 :above_color => 'red' :below_color => 'grey' :background_color => 'white' :line_color => 'lightgrey'==LicenseLicensed under the MIT license.=endmodule Sparklines $VERSION = '0.2.2' # Does the actually plotting of the graph. Calls the appropriate function based on the :type value passed. Defaults to 'smooth.' def Sparklines.plot(results=[], options={}) defaults = { :type => 'smooth', :height => 14, :upper => 50, :diameter => 20, :step => 2, :line_color => 'lightgrey', :above_color => 'red', :below_color => 'grey', :background_color => 'white', :share_color => 'blue', :remain_color => 'lightgrey', :min_color => 'blue', :max_color => 'green', :last_color => 'red', :has_min => false, :has_max => false, :has_last => false } # This symbol->string->symbol is kind of awkward. Is there a more elegant way? # Convert all symbol keys to strings defaults.keys.reverse.each do |key| defaults[key.to_s] = defaults[key] end options.keys.reverse.each do |key| options[key.to_s] = options[key] end options = defaults.merge(options) # Convert options string keys back to symbols options.keys.reverse.each do |key| options[key.to_sym] = options[key] end # Call the appropriate function for actual plotting #self.send('smooth', results, options) self.send(options[:type], results, options) end # Writes a graph to disk with the specified filename, or "Sparklines.png" def Sparklines.plot_to_file(filename="sparklines.png", results=[], options={}) File.open( filename, 'wb' ) do |png| png << self.plot( results, options) end end# Creates a pie-chart sparkline## * results - an array of integer values between 0 and 100 inclusive. Only the first integer will be accepted. It will be used to determine the percentage of the pie that is filled by the share_color#
# * options - a hash that takes parameters:
#
# :diameter - An integer that determines what the size of the sparkline will be. Defaults to 20## :share_color - A string or color code representing the color to draw the share of the pie represented by percent. Defaults to blue.## :remain_color - A string or color code representing the color to draw the pie not taken by the share color. Defaults to lightgrey. def self.pie(results=[],options={})
diameter = options[:diameter].to_i share_color = options[:share_color] remain_color = options[:remain_color] percent = results[0] img = Magick::Image.new(diameter , diameter) {self.background_color = options[:background_color]} img.format = "PNG" draw = Magick::Draw.new
#Adjust the radius so there's some edge left n the pie
r = diameter/2.0 - 2
draw.fill(remain_color)
draw.ellipse(r + 2, r + 2, r , r , 0, 360)
draw.fill(share_color)
#Okay, this part is as confusing as hell, so pay attention:
#This line determines the horizontal portion of the point on the circle where the X-Axis
#should end. It's caculated by taking the center of the on-image circle and adding that
#to the radius multiplied by the formula for determinig the point on a unit circle that a
#angle corresponds to. 3.6 * percent gives us that angle, but it's in degrees, so we need to
#convert, hence the muliplication by Pi over 180
arc_end_x = r + 2 + (r * Math.cos((3.6 * percent)*(Math::PI/180)))
#The same goes for here, except it's the vertical point instead of the horizontal one
arc_end_y = r + 2 + (r * Math.sin((3.6 * percent)*(Math::PI/180)))
#Because the SVG path format is seriously screwy, we need to set the large-arc-flag to 1
#if the angle of an arc is greater than 180 degrees. I have no idea why this is, but it is.
percent > 50? large_arc_flag = 1: large_arc_flag = 0
#This is also confusing
#M tells us to move to an absolute point on the image. We're moving to the center of the pie
#h tells us to move to a relative point. We're moving to the right edge of the circle.
#A tells us to start an absolute elliptical arc. The first two values are the radii of the ellipse
#the third value is the x-axis-rotation (how to rotate the ellipse if we wanted to [could have some fun
#with randomizing that maybe), the fourth value is our large-arc-flag, the fifth is the sweep-flag,
#(again, confusing), the sixth and seventh values are the end point of the arc which we calculated previously
#More info on the SVG path string format at: http://www.w3.org/TR/SVG/paths.html
path = "M#{r + 2},#{r + 2} h#{r} A#{r},#{r} 0 #{large_arc_flag},1 #{arc_end_x},#{arc_end_y} z"
draw.path(path)
draw.draw(img) img.to_blob
end
# Creates a discretized sparkline## * results is an array of integer values between 0 and 100 inclusive## * options is a hash that takes 4 parameters:## :height - An integer that determines what the height of the sparkline will be. Defaults to 14## :upper - An integer that determines the threshold for colorization purposes. Any value less than upper will be colored using below_color, anything above and equal to upper will use above_color. Defaults to 50.## :above_color - A string or color code representing the color to draw values above or equal the upper value. Defaults to red.## :below_color - A string or color code representing the color to draw values below the upper value. Defaults to gray. def self.discrete(results=[], options = {})
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?