How to graph impressions with chartkick and impressionist? - ruby-on-rails

I'm using Impressionist gem to capture impressions for records, and I'm using chartkick to graph the results. What I would like to do, is count the impressions for the current_user's records, and display the count on chartkick. Its a simple issue, but I cannot seem to figure out why the impressions are not being displayed on the graph. My code is below
analytics.html.erb
<%= line_chart current_user.posts.sum(&:impressionist_count).group_by_hour(:created_at).count, refresh: 60, xtitle: 'Hourly Posts Impression Count', ytitle: 'Amount of Views', label: 'View Count' %>

I found a solution to this problem. Just in case anyone has it in the future. The code below, will inject the sum of the impressions into a hash, and then it will display correctly on the graph.
<%= line_chart current_user.posts.group_by_day(:created_at).count.inject(Hash.new(0)) { |acc, (k,v)| acc[:impressionist_count] += v; acc[k] = acc[:impressionist_count]; acc }.except(:impressionist_count) %>

Related

Using sum with chartkick on multiple attributes

I want to display the chart of revenue which is total * quantity
I can do charts like this to display the total:
<%= line_chart #line_items_sold.group_by_day(:created_at).sum(:total) %>
Although doing sum with multiple attributes:
<%= line_chart #line_items_sold.group_by_day(:created_at).sum{|li| li.store_price.to_d * li.store_fulfillable_quantity} %>
doesn't work...
error:
ActionView::Template::Error (PG::GroupingError: ERROR: column "line_items.id" must appear in the GROUP BY clause or be used in an aggregate function
Doing:
<%= line_chart #line_items_sold.sum{|li| li.store_price.to_d * li.store_fulfillable_quantity}.group_by_day(:created_at) %>
Error: Can't group_by nBigDecimal
Any ideas on how I can accomplish this?
I want to show the revenue (price * quantity) on a per day basis.

Chartkick gem "no block given" runtime error

I'm currently trying to display a chart showing the revenue from a shopify boutique, hour by hour. So I came with this :
In my controller I have this, which returns a JSON:
#orders = ShopifyAPI::Order.find(:all)
And in my view I have this:
<%= line_chart #orders.group_by_hour_of_day(:created_at).count, xtitle: "Hour of the day", ytitle: "Profit in AED" %>
Then when trying to launch it locally I have a "no block given error".
I've been searching for 2 days if it's not a syntax error can't find anything.
I also tried just by showing <%= line_chart #orders %> and I have an empty chart. So I guest my issue is when I try to fetch a value from the JSON.
Thanks for your help.

Rails 5.1, chartkick a sum with multiple currencies

I'm stuck on a tiny problem regarding chartkick. I have a rail app where you can create different currencies. You can then create a expense with a title, a amount and choose the currency from a list and the user_id. The relations are made and working. I have in my user controller something like this :
#user_spendings = #current_user.spendings.all.order('date DESC').paginate(:page => params[:page], :per_page => 15)
#sums_by_currency = Currency.joins(:spendings).
select(:symb, 'SUM(spendings.amount) AS amount').
where(spendings: { id: #user_spendings.map(&:id) }).
group(:symb)
And in my show view (as I want the expense from each user to be shown there) something like this :
<% #sums_by_currency.each do |currency| %>
<%= '%.02f' % "#{currency.amount}" %> <%= "#{currency.symb}" %>
<% end %>
That shows me the sum for each spending depending on the currency.
I would like to use this total and use chartkick to display the spending, with the date when this spending has been created.
I've tried several things already
First I went with this just to see :
<% #sums_by_currency.each do |currency| %>
<%= bar_chart currency.amount %>
<% end %>
Well I have to charts appearing but nothing shows up. Maybe the loop isn't the solution. Then I thought about the .map but I don't really know how to put that in place to be honnest.
I tried this aswell :
<%= line_chart #current_user.spendings.group(:date).sum(:amount) %>
That shows me the total spendings from all the currencies. I have to find out how to split all the currencies in different charts and show only the total amount from each currency.
If anyone can give me a clue I would appreciate it.
Thanks alot.
Ok guys I got it !
Took me 2 days only...
For the one interested in the answer here is what I did. I actually didn't change anything in the controller and I let the #sums_by_currency like it is.
Instead I went for that :
<%= column_chart #current_user.spendings.all.joins(:currency).group('currencies.symb').group_by_month(:date, format: "%B %Y").sum(:amount) %>
Give me all the spendings from the current_user from where I joined the currency that I grouped by symb. Then I grouped everything by month and I get the sum from the amount.
Yeah, you need to pass a set of data to the chart, not lots of individual pieces of data for individual charts (ie what you've got with the loop). Using map to convert your currency-objects to their amounts makes sense eg
<%= bar_chart #sums_by_currency.map{|c| c.amount } %>
or if you need a name something like:
<%= bar_chart #sums_by_currency.map{|c| {name: c.unit, data: c.amount} } %>
Where unit is whatever currency unit eg AUD

Labels and Chartkick

Chartkick is amazing, and I can do super simple things like
<%= column_chart Device.joins(:reviews).group(:brand).average(:average_rating) %>
and get results like:
Now, the problem is that the labels aren't fed through to chartkick. This is what chartkick uses to render the chart:
Chartkick.ColumnChart("chart-5", {"#<Brand:0x00000008a3c048>":"78.8","#<Brand:0x0000000879e840>":"80.70000712076823","#<Brand:0x0000000853e9d8>":"81.11111111111111","#<Brand:0x000000082808e0>":"73.42857142857143"}, {});
So, the big question is... How can I use this super easy querying method but get the brand names on the chart?
I tried:
<%= column_chart Device.joins(:reviews).group(:'brand.name').average(:average_rating) %>
...and other variations to no avail...
Basically I just needed to make a small change to my query:
<%= column_chart Device.joins(:reviews).includes(:brand).group(:'brands.name').average(:average_rating) %>
Then I ended up re-ordering this by average ratings instead of brand name:
devices = Device.joins(:reviews).includes(:brand).group('brands.name').average(:average_rating)
arr = styles.to_a
arr.map! { |pair| [pair.first, pair.second.to_f] }
arr.sort! { |a, b| a.second <=> b.second }
#sorted_hash = ActiveSupport::OrderedHash[arr]
View:
<%= column_chart #sorted_hash %>
Bingo:

Adding Rails data to Highcharts series

I am trying to make a chart to display a users weight, using highcharts. I have all of the correct js files included and when passed a simple array of integers, it works just fine.
However I am unsure, having read the highcharts docs, how to pass the correct data into the series options using rails.
my user model is as follows:
A user has many weigh_ins, which has weight:float user_id:integer id:integer created_at:datetime fields. (if this is relevant)
Below is my view, as you can see i have tried to iterate through the users weights and then pass that as the data. I know it needs to be fed json and an array, but im not sure how to format my data to fit in that way.
borderWidth: 0
},
series: [{
pointInterval: <%= 1.day * 1000 %>,
name: 'weight',
data: <% #user.weigh_ins.each do |weight| %>
<%= weight.weight.to_json %>
<% end %>
}]
If there is any more code that needs posting, just shout.
any suggestions would be greatly appreciated.
Thata defo on the right track, however, the data is dynamic so a user can update their weights everyday, so the chart needs to update aswell. If i use the square brackets like above then the graph doesnt even render. Now i have this but it doesnt produce the correct output either. I need to find the weigh_ins for the correct user, then iterate through all of them and select the weight figure which is a float. Not sure how to tackle it.
data: <% user = #user.weigh_ins %>
<% user.each do |user_weight| %>
[<%= user_weight.weight %> ]
<% end %>
I'm something similar with this code:
<% bio_array = Array.new(#bio.size) %>
<% #biometrics.each_with_index {|x, index| %>
<% bio_array += [x[:weight]] %>
<% } %>
(... some code ...)
series: [{
name: 'Some Name',
data: <%= bio_array %>
Please note that this code is not optimized for you case (in my case i have other logic that i omitted for being useless to your case - i had a multidimensional arrays with [data and value]).
if you want to parse data like that , you don't really have to use Json , becoz since yo don't update dynamically , you can just echo it like [34,32,24,25,12] bt first you hv to make that String from Ruby , and that's exactly what is json is used for too , check your Json output,
btw try echo some Ruby String like
=> 1,2,3,4,5 [<% echo str %> ]
and if your json out put hv no squre brackets [] then try adding them
data:[ <% #user.weigh_ins.each do |weight| %> ]

Resources