Лучший способ использовать Ruby / Sinatra для передачи данных в Highcharts? - PullRequest
3 голосов
/ 19 июля 2011

Я обычно придерживаюсь мнения, что, если он не сломан, не надо его исправлять, но мое текущее решение этой проблемы (хотя и работает) кажется действительно уродливым.Я использую Ruby, Sinatra, Haml и Highcharts, и я хотел бы иметь возможность передавать данные, собранные в Ruby, и отправлять их в Highcharts.

В настоящее время я по сути просто создаю строковый объект извесь Highcharts Javascript и интерполировать данные рубина в это.Это работает, но я должен принять совершенно другой подход к этому?Вот именно то, что я делаю:

Я определил класс 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

Я использую фильтр JavaScript от Haml в представлении:

:javascript
  #{@chart.chart_js}

Все идет нормально.Некрасивая часть - это метод chart_js.Я просто скопировал полный текст JavaScript-кода HighChart, вставил его в виде строки, а затем использовал интерполяцию 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 Ответ

3 голосов
/ 20 июля 2011

Вы можете создать представление специально для 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 от кода записи значений для сервера.

Надеюсь, чтопомогает.

...