PullMonkey Blog


26 Apr

Headers and Footers in ruby’s Spreadsheet gem


Have you ever needed to add a header or footer to your spreadsheets in ruby?
Yah, well, we have :(
Yes, you can do this with the Write Excel gem.
But we've already written years worth of spreadsheet code with the spreadsheet gem and don't want to rewrite it all.

Anyway, we thought we'd share our little trick to get page headers using the spreadsheet gem.

So what you see here (above) goes into a config/initializer, something like RAILS_ROOT/config/initializer/enable_headers_in_spreadsheet_gem.rb. Here's what's going on:

1) We know that the write_from_scratch method is called when everything is said and done and the data is ready to be written to the spreadsheet file. So we make use of this and alias that method to write_from_scratch_without_header. Which opens us up to call our write_header method inside our write_from_scratch method which, of course, will call the original write_from_scratch method.

2) Our write_header method makes use of the already existing opcode for Header in the spreadsheet gem. It's not being used, so my guess is the developers intend on solving this issue at some point. We have to send the opcode, the length info and the string we want to write out. This was the trickiest part to figure out.

3) We expose an add_header method that simply takes a string and stores it in the header accessor. This means, to set the header, you simply say sheet.add_header("foo header").

To implement the footer, you'd just do the same thing, create a footer accessor, add a method to update it. Then build the writer_footer method with opcode(:footer) and append write_footer at the end of write_from_scratch.

Well, that took us some time to figure out, so enjoy and let me know if you have any questions.


19 Nov

2D Vector Graphics in Ruby / Rails


I've been working with Cairo the last day or two to build a sign generator.   I chose Cairo because it seemed like a good fit for building a sign that had to be loss-less in detail and scalable, this rang vector graphics.   I found a few good examples here and there, but they were very few and the documentation was not exactly ruby-friendly.

So I'm going to do a few posts about what I learned and I am going to start with the very basics, since all I could find were completed and elaborate images, way too complicated for a beginner.

Let's start with rotating a square box by 45 degrees.  Very simple.

rotated_square

That's it, pretty simple, right?


06 Jan

POST OFC Graph as Image


I was asked recently (well sort of) to give an example of saving an image to the server. If you look at teethgrinder's example for this, you will see that he has made available an external interface to do just that - POST your graph as png raw data to your server for storage. This has many benefits such as saving the image for use in a PDF report or for printing, since we know at times it is a bit troublesome to print the embedded flash object.

I think the main problem people are having with this is the receiving of the image data post - see the upload_image method below. Also, teethgrinder's example never really says where to make the post_image() call. So I touch on both in the code below.

Here is an example of the png that is saved when I did this for the chart in the previous example:

OFC Saved Image


Well, let's just get right in to the code.

The controller contains the same code as my last post with only a few minor changes to the index method and the addition of the upload_image method.
In the controller, I have this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class TestItController < ApplicationController
  def index
    # note the user of open_flash_chart_object_from_hash instead of just open_flash_chart_object
    # this allows you to pass in the id of the div you want the the chart to be in
    # this is useful for when we need to findSWF by this id
    @graph = open_flash_chart_object_from_hash("/test_it/chart", :div_name => "my_chart")
  end

  # added to recieve the post data for the OFC png image of the OFC graph
  def upload_image
    name = "tmp_image.png" || params[:name]
    # the save_image method that is provided by the OFC swf file sends raw post data, so get to it like this
    data = request.raw_post
    File.open("#{RAILS_ROOT}/tmp/#{name}", "wb") { |f| f.write(data) } if data
    render :nothing => true
  end

  def chart
    # same code from here - http://pullmonkey.com/2010/01/05/open-flash-chart-ii-x-axis-date-and-time/ 
    ...
  end
end




So just note the use of open_flash_chart_object_from_hash() in the index method, this way we can pass in the id of the div.

In the view, I have this:

1
2
3
4
5
<%= javascript_include_tag 'swfobject.js' %>
<%= @graph %>
<%= save_as_image("http://localhost:3000/test_it/upload_image?name=tmp.png", :id => "my_chart") %>
<br/>
<%= button_to_function "Save Image", "post_image()" %>



Really the only difference from what we would normally have in our view is that I am using the save image setup method that was added to the open flash chart ruby on rails plugin in the last couple hours (as of this post). The save_image method takes some arguments, mainly the url to post the image data to and the id of the chart we setup in the controller.



05 Jan

Open Flash Chart II - X Axis Date and Time


I was asked how to display date and time for the x axis as seen in this teethgrinder example - So here it goes.

Here is the graph we are after in this example:

More Open Flash Chart II examples.

And here is the code (the controller):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

class TestItController < ApplicationController
  def index
    @graph = open_flash_chart_object(550,300,"/test_it/chart")
  end
  def chart
    data1 = []
    data2 = []
    year = Time.now.year

    31.times do |i|
      x = "#{year}-1-#{i+1}".to_time.to_i
      y = (Math.sin(i+1) * 2.5) + 10

      data1 << ScatterValue.new(x,y)
      data2 << (Math.cos(i+1) * 1.9) + 4
    end

    dot = HollowDot.new
    dot.size = 3
    dot.halo_size = 2
    dot.tooltip = "#date:d M y#<br>Value: #val#"

    line = ScatterLine.new("#DB1750", 3)
    line.values = data1
    line.default_dot_style = dot

    x = XAxis.new
    x.set_range("#{year}-1-1".to_time.to_i, "#{year}-1-31".to_time.to_i)
    x.steps = 86400

    labels = XAxisLabels.new
    labels.text = "#date: l jS, M Y#"
    labels.steps = 86400
    labels.visible_steps = 2
    labels.rotate = 90

    x.labels = labels

    y = YAxis.new
    y.set_range(0,15,5)

    chart = OpenFlashChart.new
    title = Title.new(data2.size)

    chart.title = title
    chart.add_element(line)
    chart.x_axis = x
    chart.y_axis = y

    render :text => chart, :layout => false
  end
end

And in your view (index.html.erb):

1
2
3
4

<script type="text/javascript" src="/javascripts/swfobject.js"></script>
<%= @graph %>

Good Luck!


04 Jan

Open Flash Chart II for Ruby on Rails - Lug Wyrm Charmer


A long time overdue, but I've managed to get everything updated to the new version of Teethgrinder's open flash chart.

I've also started tagging everything, so if you notice any problems trying to do anything from Teethgrinder's examples, then first check that you are using the latest (as of now, that is Lug Wyrm Charmer) - http://github.com/pullmonkey/open_flash_chart/tree/LugWyrmCharmer.

Make sure you are using the latest swf either from the plugin assets directory or from Teethgrinder's downloads.