Class: SparkCanvas
- Inherits:
-
Object
- Object
- SparkCanvas
- Defined in:
- lib/city_watch/util/spark_pr.rb
Overview
pure ruby sparklines module, generates PNG or ASCII contact [email protected] for questions
strives to be somewhat compatible with sparklines lib by Dan Nugent and Geoffrey Grosenbach
png creation based on www.whytheluckystiff.net/bumpspark/
Instance Attribute Summary collapse
-
#color ⇒ Object
Returns the value of attribute color.
-
#height ⇒ Object
readonly
Returns the value of attribute height.
-
#width ⇒ Object
readonly
Returns the value of attribute width.
Instance Method Summary collapse
-
#blend(c1, c2) ⇒ Object
alpha blends two colors, using the alpha given by c2.
- #build_png_chunk(type, data) ⇒ Object
-
#grayscale(c) ⇒ Object
calculate perceptive grayscale value.
-
#initialize(width, height) ⇒ SparkCanvas
constructor
A new instance of SparkCanvas.
-
#intensity(c, i) ⇒ Object
calculate a new alpha given a 0-0xFF intensity.
-
#line(x0, y0, x1, y1) ⇒ Object
draw an antialiased line google for “wu antialiasing”.
- #point(x, y, color = nil) ⇒ Object
- #polyline(arr) ⇒ Object
- #rectangle(x0, y0, x1, y1) ⇒ Object
- #to_ascii ⇒ Object
- #to_png ⇒ Object
Constructor Details
#initialize(width, height) ⇒ SparkCanvas
Returns a new instance of SparkCanvas.
15 16 17 18 19 20 21 |
# File 'lib/city_watch/util/spark_pr.rb', line 15 def initialize(width,height) @canvas = [] @height = height @width = width height.times{ @canvas << [[0xFF,0xFF,0xFF]]*width } @color = [0,0,0,0xFF] #RGBA end |
Instance Attribute Details
#color ⇒ Object
Returns the value of attribute color.
12 13 14 |
# File 'lib/city_watch/util/spark_pr.rb', line 12 def color @color end |
#height ⇒ Object (readonly)
Returns the value of attribute height.
13 14 15 |
# File 'lib/city_watch/util/spark_pr.rb', line 13 def height @height end |
#width ⇒ Object (readonly)
Returns the value of attribute width.
13 14 15 |
# File 'lib/city_watch/util/spark_pr.rb', line 13 def width @width end |
Instance Method Details
#blend(c1, c2) ⇒ Object
alpha blends two colors, using the alpha given by c2
24 25 26 |
# File 'lib/city_watch/util/spark_pr.rb', line 24 def blend(c1, c2) (0..2).map{ |i| (c1[i]*(0xFF-c2[3]) + c2[i]*c2[3]) >> 8 } end |
#build_png_chunk(type, data) ⇒ Object
105 106 107 108 |
# File 'lib/city_watch/util/spark_pr.rb', line 105 def build_png_chunk(type,data) to_check = type + data [data.length].pack("N") + to_check + [Zlib.crc32(to_check)].pack("N") end |
#grayscale(c) ⇒ Object
calculate perceptive grayscale value
34 35 36 |
# File 'lib/city_watch/util/spark_pr.rb', line 34 def grayscale(c) (c[0]*0.3 + c[1]*0.59 + c[2]*0.11).to_i end |
#intensity(c, i) ⇒ Object
calculate a new alpha given a 0-0xFF intensity
29 30 31 |
# File 'lib/city_watch/util/spark_pr.rb', line 29 def intensity(c,i) [c[0],c[1],c[2],(c[3]*i) >> 8] end |
#line(x0, y0, x1, y1) ⇒ Object
draw an antialiased line google for “wu antialiasing”
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/city_watch/util/spark_pr.rb', line 52 def line(x0, y0, x1, y1) # clean params x0, y0, x1, y1 = x0.to_i, y0.to_i, x1.to_i, y1.to_i y0, y1, x0, x1 = y1, y0, x1, x0 if y0>y1 sx = (dx = x1-x0) < 0 ? -1 : 1 ; dx *= sx ; dy = y1-y0 # special cases x0.step(x1,sx) { |x| point x, y0 } and return if dy.zero? y0.upto(y1) { |y| point x0, y } and return if dx.zero? x0.step(x1,sx) { |x| point x, y0; y0 += 1 } and return if dx==dy # main loops point x0, y0 e_acc = 0 if dy > dx e = (dx << 16) / dy y0.upto(y1-1) do e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xFFFF x0 += sx if (e_acc <= e_acc_temp) point x0, (y0 += 1), intensity(@color,(w=0xFF-(e_acc >> 8))) point x0+sx, y0, intensity(@color,(0xFF-w)) end point x1, y1 return end e = (dy << 16) / dx x0.step(x1-sx,sx) do e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xFFFF y0 += 1 if (e_acc <= e_acc_temp) point (x0 += sx), y0, intensity(@color,(w=0xFF-(e_acc >> 8))) point x0, y0+1, intensity(@color,(0xFF-w)) end point x1, y1 end |
#point(x, y, color = nil) ⇒ Object
38 39 40 41 |
# File 'lib/city_watch/util/spark_pr.rb', line 38 def point(x,y,color = nil) return if x<0 or y<0 or x>@width-1 or y>@height-1 @canvas[y][x] = blend(@canvas[y][x], color || @color) end |
#polyline(arr) ⇒ Object
89 90 91 |
# File 'lib/city_watch/util/spark_pr.rb', line 89 def polyline(arr) (0...arr.size-1).each{ |i| line(arr[i][0], arr[i][1], arr[i+1][0], arr[i+1][1]) } end |
#rectangle(x0, y0, x1, y1) ⇒ Object
43 44 45 46 47 48 |
# File 'lib/city_watch/util/spark_pr.rb', line 43 def rectangle(x0, y0, x1, y1) x0, y0, x1, y1 = x0.to_i, y0.to_i, x1.to_i, y1.to_i x0, x1 = x1, x0 if x0 > x1 y0, y1 = y1, y0 if y0 > y1 x0.upto(x1) { |x| y0.upto(y1) { |y| point x, y } } end |
#to_ascii ⇒ Object
110 111 112 113 |
# File 'lib/city_watch/util/spark_pr.rb', line 110 def to_ascii chr = %w(M O # + ; - .) << ' ' @canvas.map{ |r| r.map { |pt| chr[grayscale(pt) >> 5] }.to_s << "\n" }.to_s end |
#to_png ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/city_watch/util/spark_pr.rb', line 93 def to_png header = [137, 80, 78, 71, 13, 10, 26, 10].pack("C*") raw_data = @canvas.map { |row| [0] + row }.flatten.pack("C*") ihdr_data = [@canvas.first.length,@canvas.length,8,2,0,0,0].pack("NNCCCCC") header + build_png_chunk("IHDR", ihdr_data) + build_png_chunk("tRNS", ([ 0xFF ]*6).pack("C6")) + build_png_chunk("IDAT", Zlib::Deflate.deflate(raw_data)) + build_png_chunk("IEND", "") end |