I'm using chartkick highchart to shows some graph in rails application. My question is can the style of chartkick graph be changed based on data provided by the chart controller?
for example this is the code in the chart.html.erb:
<%= line_chart charts_cards_history_by_day_path, refresh: 10 %>
is there a way to change that code to <%= bar_chart charts_cards_history_by_day_path, refresh: 10 %>
based on the decision made by the chart controller? So it is up to the controller whether the chart style is line or bar chart.
Thanks, Randy
the controller source:
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
The view source:
# 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 %>
The javascript source:
#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;
});
});
Updated controller source (returned an uninitialized constant error for Chart.last.data at cards_history_by_day.js.erb):
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
Many Thanks to @Kartikey Tanna who inspired me to answer the question. As mentioned, yes I need to modify @Kartikey Tanna a little bit to make things work.
So in addition to @Kartikey Tanna solution. First, I create a new controller method named setChartsData and leave the cards_history_by_day method as the original (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
Second, I create setChartsData.js.erb with only to render a partial to an empty div id in the view file:
$("#charts_div").html("<%= j render(partial: 'chart') %>");
Third, I modify my view file from <%= line_chart charts0_cards_history_by_day_path, refresh:10 %>
into an empty div like this:
<div id="charts_div" class="tab-content">
<div id="chart_perdays" class="tab-pane fade in active"></div>
</div>
Finally, I create the partial like this:
<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>
You can see, if the @dataCountPd
from the controller method return 1, a bar chart will be shown, else a line chart will be shown. Also, after the bar_chart/line_chart command, there is a controller method to returns data for the graph, this time I add a parameter bid
for query reason in the method.
Best, Randy