使用Ruby / Sinatra将数据传递给Highcharts的更好方法是什么?

时间:2011-07-19 18:04:29

标签: javascript ruby sinatra haml highcharts

我一般认为,如果没有破坏,请不要修复它,但我目前解决这个问题的方法(尽管它确实有效)似乎真的很难看。我正在使用Ruby,Sinatra,Haml和Highcharts,我希望能够传递Ruby中抓取的数据并发送给Highcharts。

目前,我基本上只是从整个Highcharts javascript中创建一个字符串对象,并将ruby数据插入其中。这有效,但我应该采取完全不同的方法吗?这正是我正在做的事情:

我已经定义了一个HighChart类,其中包含一些我希望能够通过Ruby更改的属性(例如图表标题,数据等)。下面的示例(有效!)仅设置其中两个属性,其余属性为默认值:

    get '/' do
      @chart = HighChart.new(options={
                    :title_text => "Test Title",
                    :series_data => 
                    {
                    'Calvin' => [10, 2, 17],
                    'Hobbes' => [11, 14, 6]
                    }
                  }
                )
      haml :index
    end

我在视图中使用Haml的javascript过滤器:

:javascript
  #{@chart.chart_js}

到目前为止一切顺利。丑陋的部分是chart_js方法。我只是简单地复制了HighChart javascript的全文,将其粘贴为字符串,然后使用Ruby插值从控制器中创建的HighChart对象中获取变量:

    def chart_js  
      chart_js = "
      var chart1;
      $(document).ready(function() {

  chart1 = new Highcharts.Chart({

     chart: {

        renderTo: '#{render_to}',

        type: '#{chart_type}'

     },

     title: {

        text: '#{title_text}'

     },

     xAxis: {

        categories: #{x_categories}

     },

     yAxis: {

        title: {

           text: '#{y_categories}'

        }

     },

     series: [#{get_data_js(series_data)}]

  });

 });
  "
end

以防万一它有用,这是HighChart对象类定义的第一部分:

    class HighChart
attr_accessor :render_to, :chart_type, :title_text, :x_categories, 
              :y_categories, :series_data

    def initialize(options={})
      self.render_to = options[:render_to] || 'container'
      self.chart_type = options[:chart_type] || 'bar'
      self.title_text = options[:title_text] || 'Fruit Consumption'
      self.x_categories = options[:x_categories] || ['Apples', 'Bananas', 'Oranges']
      self.y_categories = options[:y_categories] || 'Fruit eaten'
      self.series_data = options[:series_data] || {'Jane' => [1, 0, 4], 
                                                  'Bobbert' => [5, 7, 3],
                                                  'Zach' => [10, 2, 1]
                                                  }
    end

1 个答案:

答案 0 :(得分:3)

您可以专门为Highcharts JS制作视图,然后使用实例变量(例如@render_to,@ chart_type等)。这不会真正清理代码那么多,但它将摆脱在控制器中拥有巨大视图字符串的一些“错误”。

从根本上说,你可以做的事情不多;你有一堆服务器端信息,它必须写入客户端(以特定的Highcharts格式)。只是没有解决这个问题。

我能提供的唯一其他建议是使用中间JS变量。这将允许您在视图中保留所有JS(没有仅JS的视图),然后您只需要设置一些JS变量。这看起来像这样:

var RENDER_TO = "@render_to";
var CHART_TYPE = "@chart_type";
// ...
$(document).ready(function() {
  chart1 = new Highcharts.Chart({
    chart: {
       renderTo: RENDER_TO,
       ....

现在这实际上涉及更多代码,但它可以让你完全将onReady代码与服务器值编写代码分开。

希望有所帮助。