rails 上的 Chartkick:根据数据更改图表样式
Chartkick on rails: change the graph style based on the data
我正在使用 chartkick highchart 在 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
根据你要测试的数据条件,在视图中添加条件逻辑即可 例如:
<% 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 %>
您可以做的是,进行 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 启发了我回答这个问题。如前所述,是的,我需要稍微修改@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') %>");
第三,我将视图文件从 <%= 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>
你可以看到,如果控制器方法return1中的@dataCountPd
,将显示条形图,否则将显示折线图。另外,在bar_chart/line_chart命令之后,有一个controller method to returns data for graph,这次我在方法中添加了一个参数bid
用于查询原因。
最好的,
兰迪
我正在使用 chartkick highchart 在 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
根据你要测试的数据条件,在视图中添加条件逻辑即可 例如:
<% 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 %>
您可以做的是,进行 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 启发了我回答这个问题。如前所述,是的,我需要稍微修改@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') %>");
第三,我将视图文件从 <%= 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>
你可以看到,如果控制器方法return1中的@dataCountPd
,将显示条形图,否则将显示折线图。另外,在bar_chart/line_chart命令之后,有一个controller method to returns data for graph,这次我在方法中添加了一个参数bid
用于查询原因。
最好的, 兰迪