首页 文章

Chartkick on rails:根据数据更改图表样式

提问于
浏览
0

我正在使用chartkick高图来显示rails应用程序中的一些图形 . 我的问题是可以根据图表控制器提供的数据更改chartkick图的样式吗?

例如,这是chart.html.erb中的代码:

<%= line_chart charts_cards_history_by_day_path, refresh: 10 %>

有没有办法根据图表控制器的决定将代码更改为 <%= bar_chart charts_cards_history_by_day_path, refresh: 10 %> ?因此,图表样式是线条还是条形图取决于控制器 .

谢谢,兰迪

控制器源:

def cards_history_by_day

      begin

        p_board_id = params['post']['board_id']

        render json:
          [{name: "No. of cards", data: ListsCountPerday.joins(:t_list).where('lists_count_perdays.t_board_id = '+p_board_id+' and
            t_lists.t_list_type_id != 1').group(:date).pluck('date, sum(count)')},
          {name: "Completed", data: ListsCountPerday.joins(:t_list).where('lists_count_perdays.t_board_id = '+p_board_id+' and
            t_lists.t_list_type_id = 5').group(:date).pluck('date, sum(count)')}]

      rescue
        render json: CardHistory.where('t_list_id = -1').group_by_day(:created_at).count
      end

  end

视图来源:

# javascript to handle selection and form submission
<%= javascript_include_tag "charts0" %>

# form for user select prefered data to show
<%= form_tag charts0_cards_history_by_day_path , remote: true do %>
<label for="team_name">Team: </label>
<%= collection_select "post", "authentication_id",
            Authentication.order(:team_name), :id, :team_name, prompt: "Please select"  %>
<label for="team_name">Board: </label>
 <%= grouped_collection_select "post", "board_id",
            Authentication.order(:team_name), :t_board, :team_name, :id, :name, prompt: "Please select" %>
 <%= submit_tag 'Apply', class: 'btn btn-primary' %>
<% end %>

#function to show the chart which data taken from the controller
<%= line_chart charts0_cards_history_by_day_path, refresh:10 %>

javascript源码:

#javascript to update chart data once form is submitted
$(document).ready(function() {
  $('form').submit(function(e) {
    e.preventDefault();
    data = $(this).serialize();

    Chartkick.eachChart( function(chart) {
      chart.updateData(chart.getDataSource() + '?' + data);
    });

    return false;
  });
});

更新了控制器源(在cards_history_by_day.js.erb中为Chart.last.data返回了未初始化的常量错误):

def cards_history_by_day

          begin

            p_board_id = params['post']['board_id']

           #call the .js.erb file (based on the JS tutorial given)
           respond_to do |format|
             format.js
           end

          rescue
            render json: CardHistory.where('t_list_id = -1').group_by_day(:created_at).count
          end

      end

3 回答

  • 0

    只需根据要测试的数据条件在视图中添加条件逻辑,例如:

    <% if @data.condition %>
      <%= line_chart charts_cards_history_by_day_path, refresh: 10 %>
    <% else %>
      <%= bar_chart charts_cards_history_by_day_path, refresh: 10 %>
    <% end %>
    
  • 0

    您可以做的是,进行AJAX调用并呈现 .js.erb 视图作为响应 . .js.erb 模板的响应将是Javascript,它将在客户端执行 .

    以下是使用您的代码解释概念的粗略示例 . 您必须对其进行修改才能使其正常工作 .

    首先,让我们创建一个 div ,我们想在其中动态呈现图表 .

    替换以下行:

    <%= line_chart charts0_cards_history_by_day_path, refresh:10 %>
    

    附:

    <div id="cards_history_by_day_chart"></div>
    

    然后,让我们创建一个包含渲染图表代码的部分 . 这个部分将从我们的 .js.erb 视图中调用 .

    // chart.html.erb

    <%= line_chart charts0_cards_history_by_day_path, refresh:10 %>
    

    然后,在 cards_history_by_day 方法而不是 render json 下,您可以创建 .js.erb 视图 .

    因此,在每次AJAX调用之后, .js.erb 视图发送JS在客户端执行 .

    // cards_history_by_day.js.erb

    Chartkick.eachChart( function(chart) {
          chart.updateData(chart.getDataSource() + '?' + <%= Chart.last.data %>);
        });
    $("#cards_history_by_day_chart").html("<%= j render(partial: 'chart') %>");
    

    在这里,您可以看到我已使用 erb 标记中的记录替换了您的js中的 data .

    您可能还想在 cards_history_by_day 方法中使用条件渲染 .

    if condition_match
      render bar_chart
    else
      render line_chart
    

    如果不清楚,教程可以提供帮助:https://coderwall.com/p/kqb3xq/rails-4-how-to-partials-ajax-dead-easy

  • 0

    非常感谢@Kartikey Tanna,他激励我回答这个问题 . 如上所述,是的,我需要稍微修改@Kartikey Tanna才能使事情有效 .

    所以除了@Kartikey Tanna解决方案 . 首先,我创建一个名为setChartsData的新控制器方法,并将cards_history_by_day方法保留为原始方法(render json):

    def setChartsData
          begin
            # get post data once the form is submitted
            p_board_id = params['form']['board_id']
            # set global variable to store board id
            @formbid = p_board_id
            # set global variable as decider which chart style will be shown
            @dataCountPd = ListsCountPerday.group(:date).count.count
    
            respond_to do |format|
              format.js
            end
        rescue
          # do nothing
        end
      end
    

    其次,我创建setChartsData.js.erb只用于在视图文件中呈现部分为空的div id:

    $("#charts_div").html("<%= j render(partial: 'chart') %>");
    

    第三,我将我的视图文件从 <%= line_chart charts0_cards_history_by_day_path, refresh:10 %> 修改为一个空div,如下所示:

    <div id="charts_div" class="tab-content">
      <div id="chart_perdays" class="tab-pane fade in active"></div>
    </div>
    

    最后,我创建了这样的局部:

    <div id="chart_perdays" class="tab-pane fade in active">
      <% if @dataCountPd == 1 %>
          <%= bar_chart charts0_cards_history_by_day_path(bid:@formbid), refresh:10 %>
      <% elsif @dataCountPd > 1 %>
          <%= line_chart charts0_cards_history_by_day_path(bid:@formbid), refresh:10 %>
      <% end %>
    </div>
    

    您可以看到,如果控制器方法的 @dataCountPd 返回1,将显示条形图,否则将显示折线图 . 另外,在bar_chart / line_chart命令之后,有一个控制器方法返回图形的数据,这次我在方法中为查询原因添加了一个参数 bid .

    最好,兰迪

相关问题