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 + -
显示快捷键?