【问题标题】:Chartkick on rails: change the graph style based on the dataChartkick on rails:根据数据改变图表样式
【发布时间】:2018-06-17 15:33:07
【问题描述】:

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

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

<%= line_chart charts_cards_history_by_day_path, refresh: 10 %>

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

谢谢, 兰迪

控制器来源:

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

【问题讨论】:

  • 你在使用 AJAX 吗?你能添加你的视图和控制器的代码吗?
  • 嗨@KartikeyTanna,请检查我已添加视图和控制器代码
  • 我对chartkick知之甚少,但在普通的Highcharts(纯JS)中,您可以简单地使用update函数:api.highcharts.com/class-reference/Highcharts.Chart#update所以如果您可以在您的JS中获得对图表的引用,那么可能代码(例如通过引用Highcharts.charts[0] 对象)您可以更新图表。

标签: ruby-on-rails highcharts chartkick


【解决方案1】:

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

<% 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 %>

【讨论】:

  • 嗨,恐怕每次控制器决定条件时我都无法刷新页面。因为,基于用户输入的决定,当用户提交输入时,图形控制器只渲染 json 图形数据(不刷新页面)。一个 javascript 帮助它根据用户输入更新图形数据,但我找不到如何更改图形样式。换句话说,我们可以用 javascript 做 @neydroid 条件吗?因为在我的情况下,这可能只是可能的解决方案。目前javascirpt是这样的:
【解决方案2】:

您可以做的是,进行 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') %>");

这里你可以看到我已经把你js中的data替换成了erb标签中的记录。

您可能还想在 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

【讨论】:

  • 嗨@Kartikey Tanna,我已经尝试过你的解决方案。但是,当控制器调用文件 .js.erb 时,它会返回 Chart.last.data 的未初始化常量错误。我需要在哪里放置和设置该变量?那是图形数据内容吗?我已根据您建议的解决方案步骤添加更新的控制器源。
  • 是的,那是图表数据。您之前使用的是data = $(this).serialize();。但是现在由于它是从服务器呈现的,您可以从服务器获取数据。早些时候,您从控制器返回了render json 下的一些数据。那是图表的更新数据吗?我没有看到您是如何进行 AJAX 调用的。
【解决方案3】:

非常感谢@Kartikey Tanna,他启发了我回答这个问题。如前所述,是的,我需要稍微修改@Kartikey Tanna 以使事情正常进行。

所以除了@Kartikey Tanna 解决方案。首先,我创建了一个名为 setChartsData 的新控制器方法,并将 cards_history_by_day 方法保留为原始方法(渲染 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') %>");

第三,我将我的视图文件从&lt;%= line_chart charts0_cards_history_by_day_path, refresh:10 %&gt; 修改为一个空的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命令之后,还有一个controller方法可以返回graph的数据,这次我在方法中添加了一个参数bid查询原因。

最好, 兰迪

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    • 2018-11-11
    • 1970-01-01
    • 2014-03-02
    • 2014-08-12
    • 2016-05-17
    • 1970-01-01
    相关资源
    最近更新 更多