One thing that would make sparklines a lot more universally accessible to
all browsers would be to get rid of the dependency on data urls. The basic
idea is to return the proper MIME type to the browser and then just start
spitting out the raw binary data of the PNG.
Here is an example:
#!/usr/bin/ruby
require 'base64'
require 'cgi'
require 'zlib'
def build_png_chunk(type,data)
to_check = type + data
return [data.length].pack("N") + to_check +
[Zlib.crc32(to_check)].pack("N")
end
def build_png(image_rows)
header = [137, 80, 78, 71, 13, 10, 26, 10].pack("C*")
raw_data = image_rows.map { |row| [0] + row }.flatten.pack("C*")
ihdr_data = [image_rows.first.length,
image_rows.length,
8,2,0,0,0].pack("NNCCCCC")
ihdr = build_png_chunk("IHDR", ihdr_data)
idat = build_png_chunk("IDAT", Zlib::Deflate.deflate(raw_data))
iend = build_png_chunk("IEND", "")
return header + ihdr + idat + iend
end
def bumpspark(results)
white, red, grey = [0xFF,0xFF,0xFF], [0,0,0xFF], [0x99,0x99,0x99]
rows = results.inject([]) do |ary, r|
ary << [white]*15 << [white]*15
ary.last[r/9,4] = [(r > 50 and red or grey)]*4
ary
end.transpose
return build_png(rows)
end
def send_to_browser(results)
puts "Content-type: image/png"
puts "Expires: Wed, 11 Nov 1998 11:11:11 GMT"
puts "Cache-Control: no-cache"
puts "Cache-Control: must-revalidate"
puts
print bumpspark(results)
end
send_to_browser (0..22).map { rand 100 }
See this in action at the following URL:
http://youngbloods.org/sparkline.cgi
Carl