Question

I am using the googlecharts gem in my rails app for some simple charting. It works beautifully, except my app is required to be SSL encrypted at all times. In order to pull the google charts, the charts gem of course makes an http request to google which leads to a browser warning about some insecure content on the page for most users. Has anyone else faced this issue and devised a solution to avoid the warning? I am afraid I will need to figure out a way to make the http call, store the image google returns locally, and then display that in the app but figured someone else has already found a nice way to handle this.

Was it helpful?

Solution

The API Google Charts API endpoint is stored in the class variable @@url inside the Gchart class. So initially I thought of monkeypatching the class variable to set the url to https

# Put this in an initializer
Gchart.send :class_variable_set, :@@url, "https://chart.apis.google.com/chart?"

alas Google Charts does not work via https. So we can't use that method. As the Gchart class methods just return a URL we can wrap the calls up in a proxy controller method that does the API call server side and proxies it to the client via the ActionController send_data method using your protocol of choice. That way you don't have to reinvent the Gchart library wheel.

class ChartsController < ApplicationController
  require 'net/http'
  require 'gchart'

  def show
    options = params.except :controller, :action
    options[:data].map! { |x| x.to_i } if options[:data]
    begin 
      chart = URI.parse(Gchart.send options.delete(:type), options)
      send_data Net::HTTP.get(chart), :content_type => 'image/png', :disposition  => 'inline'
    rescue
      raise ActiveRecord::RecordNotFound
    end
  end

end

The helper you can use in your views:

module ApplicationHelper

  def chart_tag(options ={})
    image_tag chart_path(options)
  end

end

and the route

map.resource :chart, :only => :show

Usage:

<%= chart_tag :type => "line", :size => '200x300', :title => "example title", :bg => 'efefef', :legend => ['first data set label', 'second data set label'], :data => [10, 30, 120, 45, 72] %>

Code is untested but should give you a good start.

OTHER TIPS

Google charts supports now ssl :

use https://chart.googleapis.com/chart

instead of : http://chart.apis.google.com/chart

I'm using the GchartRB gem, and a modified version of the first solution worked for me as well. You'll have to use the to_escaped_url method for URI.parse to handle it correctly.

I don't know of an existing plugin that will do this, but you can do it on your own. Simply write a new controller method that will get the chart via HTTP and then return it immediately (no need to save it to a file)

In controller:

require 'net/http'
def googlechart
  send_data Net::HTTP.get("http://chart.apis.google.com/chart?#{params[:api]}"),
    :content_type => 'image/png',
    :disposition  => 'inline'
end

In view:

<%= image_tag googlechart_path(:api=>'cht=p&chd=s:Uf9a&chs=200x100&chl=January') %>

Just set up your route and you're all set.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top