Reputation: 81
Edit: I'ts been over 3 weeks now, and i can't seem to solve the problem without making even more problems. Can anyone be so kind and take a look please??
I want to create a bar chart listing all users and number of their endorsements. Would be nice to also have a drilldown on each number to display the number of endorsements the user got for each month in current year. Like:
User1 - 5
User2 - 8
User3 - 3
And clicking on each number would drill down and show data for the clicked user like this:
January - 2
February - 2
March - 1
And I am totally lost and have no idea how to approach this, so any help will be greatly appreciated.
In my view all I managed to do was to just show a blank chart with users listed below it:
<% provide(:title, "Statistics") %>
<h1>Statistics</h1>
<%= bar_chart @users.group(:name) %>
<% end %>
I am using chartkick and dateslices instead of groupdate because im using SQlite.
Also, to get the number of endorsements i have to do something like:
<% @users.each do |user| %>
<ul class="user">
<%= user.name %>
<%= user.inbound_endorsements.count %>
</ul>
where @users is basically User.all
You can see the relations below.
Now some info about my Users and endorsements controllers/models with cut out parts of unrelevant info like password settings and such
Users Model:
class User < ActiveRecord::Base
has_many :inbound_endorsements, class_name: "Endorsement",
foreign_key: "endorsed_user_id",
dependent: :destroy
has_many :outbound_endorsements, class_name: "Endorsement",
foreign_key: "endorsing_user_id",
dependent: :destroy
has_many :endorsing_users, through: :inbound_endorsements, source: :endorsing_user
has_many :endorsed_users, through: :outbound_endorsements, source: :endorsed_user
.
.
.
# Endorses a user.
def endorse(other_user, comment)
outbound_endorsements.create(endorsed_user_id: other_user.id, comment: comment)
end
# Unendorses a user.
def unendorse(other_user)
outbound_endorsements.find_by(endorsed_user_id: other_user.id).destroy
end
# Returns true if this is endorsing the other user.
def endorsing?(other_user)
Endorsement.current.exists?(endorsing_user: self, endorsed_user: other_user)
end
# Returns true if this can endorse other user.
def can_endorse?(other_user)
if (current_outbound_endorsements_count < 3)
unless endorsing?(other_user)
return true
end
end
return false
end
def current_outbound_endorsements_count
outbound_endorsements.current.count
end
.
.
.
Endorsements model:
class Endorsement < ActiveRecord::Base
belongs_to :endorsing_user, class_name: "User"
belongs_to :endorsed_user, class_name: "User"
validates :endorsing_user_id, presence: true
validates :endorsed_user_id, presence: true
validates :comment, presence: true, length: { maximum: 140}
scope :current, -> { where(created_at: (Time.now.beginning_of_month..Time.now)) }
end
And this is my static_pages controller, with only this defined for the statistics page where i want the chart displayed:
class StaticPagesController < ApplicationController
before_filter :require_user, :require_admin, only: :statistics
def home
if logged_in?
end
end
def statistics
@users = User.all
@endorsements = Endorsement.all
end
def help
end
def about
end
def contact
end
end
Any help and tips will be greatly appreciated!
Perhaps there is an easier way to do this? If you know such, let me know!
Upvotes: 1
Views: 531
Reputation: 81
After 2 months I've managed to solve my problem.. Well, not exactly, I cannot get the drilldown to work, but managed to make a simple bar chart for all users that have endorsements, users with 0 are not displayed.
This is how I did it:
In my static pages controller for the statistics page i made something like this:
def statistics
@users = User.all
@endorsements = Endorsement.all
@data = @users.map { |user|
amount = user.inbound_endorsements.joins(:endorsed_user).group(:name).count
if !amount.empty?
{name: user.name, data: amount}
end
}
end
and in my view for statistics I made this:
<% provide(:title, "Statistics") %>
<h1>Statistics</h1>
<%= pie_chart({"Users" => @users.count, "Endorsements" => @endorsements.count}) %>
<%= column_chart @data.compact, library: {yAxis: {allowDecimals: false}} %>
@data.compact removed the nil values from the hash, resulting in a hash looking like this:
[{:name=>"Jess Corwin", :data=>{"Jess Corwin"=>1}}, {:name=>"Rhiannon Nicolas", :data=>{"Rhiannon Nicolas"=>1}}, {:name=>"Assunta Pfeffer", :data=>{"Assunta Pfeffer"=>2}}, {:name=>"Rafaela Farrell", :data=>{"Rafaela Farrell"=>1}}, {:name=>"Maurine Hettinger", :data=>{"Maurine Hettinger"=>1}}]
And that data resulted in a chart like this:
Which is satisfactory. Hope this helps someone one day.
Upvotes: 1