Helban
Helban

Reputation: 81

[help]RoR, Chartkick, bar chart with all users and number of endorsements for each

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

Answers (1)

Helban
Helban

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:

enter image description here

Which is satisfactory. Hope this helps someone one day.

Upvotes: 1

Related Questions