What do you want to see in a Sparklines Library?

D

Daniel Nugent

This is sort of an interest gauging/feature request poll.

I saw Joe Gregorio's Sparklines webservice written in Python and
decided to try and do an implementation in Ruby thinking that I may
want to be able to have access to some quick Sparklines for a Rails
app or something one day.

Well, writing it in Ruby didn't take too long (mostly just issues with
Apache and RMagick) and I generally like the outcome. But I was
thinking that there might be some interest for some more features that
could make doing Sparklines for anything a piece of cake.

What would you like to see in a sparklines library?
--=20
-Dan Nugent
 
D

Daniel Nugent

Yup, seen the stuff on RedHanded, I was planning on writing a little
something that'll let me do data: URIs.

As for Pure Ruby, I assume you mean no image manipulation libraries.=20
Frankly, that's out of the question unless someone's already written
an image manipulation library in Pure Ruby. I don't have any interest
in doing that.

Right now, I'm using RMagick, but if you know of an image manipulation
library in Pure Ruby, please do tell.



--=20
-Dan Nugent
 
M

Mark Hubbart

Yup, seen the stuff on RedHanded, I was planning on writing a little
something that'll let me do data: URIs.
=20
As for Pure Ruby, I assume you mean no image manipulation libraries.
Frankly, that's out of the question unless someone's already written
an image manipulation library in Pure Ruby. I don't have any interest
in doing that.
=20
Right now, I'm using RMagick, but if you know of an image manipulation
library in Pure Ruby, please do tell.

Not an image manipulation library, but a simple-to-use pure ruby png writer=
:
http://www.ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-talk/120493
Not being an image manipulation library shouldn't be a problem unless
you want to draw text in there... I use this a lot for plotting data.

cheers,
Mark
 
A

Adam Sanderson

Well... what does it do right now?
I was looking into writing a nice ruby-centric charting library, then
again I am always looking into doing things I never get around to ;)

I suppose if you're using RMagick then they can already be writtent to
a variety of formats, which is good. One thing I haven't seen yet
which might be neat would be mini pie charts, along the lines of
sparklines, but to show proportions of various things.
.adam sanderson
 
D

Daniel Nugent

Right now I'm outputting 3 different types of sparklines.

2 of them, discrete and smooth, were lifted from Joe's Python code and
use exactly the same query parameters as seen here:
http://bitworking.org/projects/sparklines/

The third is a bit of a blend between the 2 which you can access if
you change the type parameter to "area".

Here's an example query running on my dev server (the IP isn't static
though, so don't expect it to be up forever):
http://68.195.83.222/spark.cgi?height=3D25&type=3Darea&d=3D88,84,82,92,82,8=
6,66,82,44,64,66,88,90,80,24,26,14,0,0,26,8,6,6,24,52,66,36,6,10,14,30&min-=
m=3Dtrue&max-m=3Dtrue&last-m=3Dtrue&min-color=3Dred&max-color=3Dblue&last-c=
olor=3Dgreen&step=3D5&upper=3D45

(the code is http://68.195.83.222/spark.rb if you want to grab it)

Changing the image output type would be a snap, I could probablly have
that working in 10 minutes.

Pie charts could definitley be a possibility. RMagick's got some
excellent drawing functions that make doing something like that a
snap.

Well... what does it do right now?
I was looking into writing a nice ruby-centric charting library, then
again I am always looking into doing things I never get around to ;)
=20
I suppose if you're using RMagick then they can already be writtent to
a variety of formats, which is good. One thing I haven't seen yet
which might be neat would be mini pie charts, along the lines of
sparklines, but to show proportions of various things.
.adam sanderson
=20
=20
=20


--=20
-Dan Nugent
 
D

Daniel Nugent

Adam, your wish is my command:

http://68.195.83.222/spark.cgi?type=3Dpie&d=3D85&diameter=3D40&share-color=
=3Dpink&remain-color=3Dtan

I'm not sure what Mr. Tufte would think about this though, as I'm
pretty sure that pie charts are taboo. However, DAMN THE MAN! We'll
have our pie and eat it too!

Right now I'm outputting 3 different types of sparklines.
=20
2 of them, discrete and smooth, were lifted from Joe's Python code and
use exactly the same query parameters as seen here:
http://bitworking.org/projects/sparklines/
=20
The third is a bit of a blend between the 2 which you can access if
you change the type parameter to "area".
=20
Here's an example query running on my dev server (the IP isn't static
though, so don't expect it to be up forever):
http://68.195.83.222/spark.cgi?height=3D25&type=3Darea&d=3D88,84,82,92,82= ,86,66,82,44,64,66,88,90,80,24,26,14,0,0,26,8,6,6,24,52,66,36,6,10,14,30&mi=
n-m=3Dtrue&max-m=3Dtrue&last-m=3Dtrue&min-color=3Dred&max-color=3Dblue&last=
-color=3Dgreen&step=3D5&upper=3D45
=20
(the code is http://68.195.83.222/spark.rb if you want to grab it)
=20
Changing the image output type would be a snap, I could probablly have
that working in 10 minutes.
=20
Pie charts could definitley be a possibility. RMagick's got some
excellent drawing functions that make doing something like that a
snap.
=20

=20
=20


--=20
-Dan Nugent
 
A

Adam Sanderson

I can't seem to access your pages. Perhaps someone has eaten all the
pie?

A pie chart has a valid purpose, when you're trying to visualize
realtions of data ie (30% sunny, 20% cloudy, 50% rainy). What I think
he rightly doesn't like is that people like to make them 3d, and then
have horrible labels, and such.

Anyways, want to send me a screenshot or two?
.adam sanderson
 
C

Carl Youngblood

------=_Part_1299_22623580.1119897374904
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

One thing that would make sparklines a lot more universally accessible to=
=20
all browsers would be to get rid of the dependency on data urls. The basic=
=20
idea is to return the proper MIME type to the browser and then just start=
=20
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 =3D type + data
return [data.length].pack("N") + to_check +
[Zlib.crc32(to_check)].pack("N")
end

def build_png(image_rows)
header =3D [137, 80, 78, 71, 13, 10, 26, 10].pack("C*")
raw_data =3D image_rows.map { |row| [0] + row }.flatten.pack("C*")
ihdr_data =3D [image_rows.first.length,
image_rows.length,
8,2,0,0,0].pack("NNCCCCC")
ihdr =3D build_png_chunk("IHDR", ihdr_data)
idat =3D build_png_chunk("IDAT", Zlib::Deflate.deflate(raw_data))
iend =3D build_png_chunk("IEND", "")

return header + ihdr + idat + iend
end

def bumpspark(results)
white, red, grey =3D [0xFF,0xFF,0xFF], [0,0,0xFF], [0x99,0x99,0x99]
rows =3D results.inject([]) do |ary, r|
ary << [white]*15 << [white]*15
ary.last[r/9,4] =3D [(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

------=_Part_1299_22623580.1119897374904--
 
C

Carl Youngblood

------=_Part_1303_25629569.1119898910310
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Here's an improvement. Make your CGI script accept parameters so that you=
=20
can make a generic script that will generate sparklines for all types of=20
data:

...

cgi =3D CGI.new
data =3D cgi['data']
if data.empty?
send_to_browser (0..22).map { rand 100 }
else
send_to_browser data.split(',').collect! {|e| e.to_i}
end

Example in action:

http://youngbloods.org/sparkline2.cgi?data=3D23,19,67,20,5

Carl

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

------=_Part_1303_25629569.1119898910310--
 
C

Carl Youngblood

------=_Part_1307_12524513.1119898986847
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Here's an improvement. Make your CGI script accept parameters so that you=
=20
can make a generic script that will generate sparklines for all types of=20
data:

...

cgi =3D CGI.new
data =3D cgi['data']
if data.empty?
send_to_browser (0..22).map { rand 100 }
else
send_to_browser data.split(',').collect! {|e| e.to_i}
end

Example in action:

http://youngbloods.org/sparkline2.cgi?data=3D23,19,67,20,5

Carl

------=_Part_1307_12524513.1119898986847--
 
C

Carl Youngblood

------=_Part_1311_29849957.1119899236183
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Sorry about the duplicate posts. Gmail problem...

------=_Part_1311_29849957.1119899236183--
 
D

Daniel Nugent

I'm doing that right now actually, I just want to add the ability to
do data: URIs, which should be pretty easy I think.

It's strange that you can't access my server Adam, is anyone else
having that problem?

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 basi= c
idea is to return the proper MIME type to the browser and then just start
spitting out the raw binary data of the PNG.
=20
Here is an example:
=20
#!/usr/bin/ruby
=20
require 'base64'
require 'cgi'
require 'zlib'
=20
def build_png_chunk(type,data)
to_check =3D type + data
return [data.length].pack("N") + to_check +
[Zlib.crc32(to_check)].pack("N")
end
=20
def build_png(image_rows)
header =3D [137, 80, 78, 71, 13, 10, 26, 10].pack("C*")
raw_data =3D image_rows.map { |row| [0] + row }.flatten.pack("C*")
ihdr_data =3D [image_rows.first.length,
image_rows.length,
8,2,0,0,0].pack("NNCCCCC")
ihdr =3D build_png_chunk("IHDR", ihdr_data)
idat =3D build_png_chunk("IDAT", Zlib::Deflate.deflate(raw_data))
iend =3D build_png_chunk("IEND", "")
=20
return header + ihdr + idat + iend
end
=20
def bumpspark(results)
white, red, grey =3D [0xFF,0xFF,0xFF], [0,0,0xFF], [0x99,0x99,0x99]
rows =3D results.inject([]) do |ary, r|
ary << [white]*15 << [white]*15
ary.last[r/9,4] =3D [(r > 50 and red or grey)]*4
ary
end.transpose
return build_png(rows)
end
=20
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
=20
send_to_browser (0..22).map { rand 100 }
=20
=20
See this in action at the following URL:
=20
http://youngbloods.org/sparkline.cgi
=20
Carl
=20
=20


--=20
-Dan Nugent
 
E

Ezra Zygmuntowicz

I cannot access your server either. I have tried both times you
posted it and it would just time out multiple times.
-Ezra
I'm doing that right now actually, I just want to add the ability to
do data: URIs, which should be pretty easy I think.

It's strange that you can't access my server Adam, is anyone else
having that problem?

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

-Ezra Zygmuntowicz
Yakima Herald-Republic
WebMaster
509-577-7732
(e-mail address removed)
 
J

John Knight

------=_Part_1370_26420177.1119977535077
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

I also cannot access your server.

=20
I cannot access your server either. I have tried both times you
posted it and it would just time out multiple times.
-Ezra
On Jun 27, 2005, at 1:24 PM, Daniel Nugent wrote:
=20
I'm doing that right now actually, I just want to add the ability to
do data: URIs, which should be pretty easy I think.

It's strange that you can't access my server Adam, is anyone else
having that problem?

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 =3D type + data
return [data.length].pack("N") + to_check +
[Zlib.crc32(to_check)].pack("N")
end

def build_png(image_rows)
header =3D [137, 80, 78, 71, 13, 10, 26, 10].pack("C*")
raw_data =3D image_rows.map { |row| [0] + row }.flatten.pack("C*")
ihdr_data =3D [image_rows.first.length,
image_rows.length,
8,2,0,0,0].pack("NNCCCCC")
ihdr =3D build_png_chunk("IHDR", ihdr_data)
idat =3D build_png_chunk("IDAT", Zlib::Deflate.deflate(raw_data))
iend =3D build_png_chunk("IEND", "")

return header + ihdr + idat + iend
end

def bumpspark(results)
white, red, grey =3D [0xFF,0xFF,0xFF], [0,0,0xFF], [0x99,0x99,0x99]
rows =3D results.inject([]) do |ary, r|
ary << [white]*15 << [white]*15
ary.last[r/9,4] =3D [(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
=20
-Ezra Zygmuntowicz
Yakima Herald-Republic
WebMaster
509-577-7732
(e-mail address removed)
=20
=20

------=_Part_1370_26420177.1119977535077--
 
D

Daniel Nugent

I'll bet it's my ISP blocking access from outside the subnet. I'm
sorry about that.

I'm not quite sure how to let you guys see what it does, I'll email
the source if you'd like it, or you can look at Joe's Python version
(sans my two additions): .http://bitworking.org/projects/sparklines/

Carl: I'm not sure if what you're doing there is any different from
what's in the script right now.

I cannot access your server either. I have tried both times you
posted it and it would just time out multiple times.
-Ezra
On Jun 27, 2005, at 1:24 PM, Daniel Nugent wrote:
=20
I'm doing that right now actually, I just want to add the ability to
do data: URIs, which should be pretty easy I think.

It's strange that you can't access my server Adam, is anyone else
having that problem?

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 =3D type + data
return [data.length].pack("N") + to_check +
[Zlib.crc32(to_check)].pack("N")
end

def build_png(image_rows)
header =3D [137, 80, 78, 71, 13, 10, 26, 10].pack("C*")
raw_data =3D image_rows.map { |row| [0] + row }.flatten.pack("C*")
ihdr_data =3D [image_rows.first.length,
image_rows.length,
8,2,0,0,0].pack("NNCCCCC")
ihdr =3D build_png_chunk("IHDR", ihdr_data)
idat =3D build_png_chunk("IDAT", Zlib::Deflate.deflate(raw_data))
iend =3D build_png_chunk("IEND", "")

return header + ihdr + idat + iend
end

def bumpspark(results)
white, red, grey =3D [0xFF,0xFF,0xFF], [0,0,0xFF], [0x99,0x99,0x99]
rows =3D results.inject([]) do |ary, r|
ary << [white]*15 << [white]*15
ary.last[r/9,4] =3D [(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
=20
-Ezra Zygmuntowicz
Yakima Herald-Republic
WebMaster
509-577-7732
(e-mail address removed)
=20
=20
=20


--=20
-Dan Nugent
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top