Merge pull request #10 from ZeusWPI/cute-little-statistics
Cute little statistics
This commit is contained in:
commit
7da6b0fed6
8 changed files with 103 additions and 51 deletions
|
@ -1,4 +1,35 @@
|
||||||
// Place all the styles related to the pages controller here.
|
// Place all the styles related to the pages controller here.
|
||||||
// They will automatically be included in application.css.
|
// They will automatically be included in application.css.
|
||||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||||
.shame-percentage { text-align: right }
|
.shame-percentage {
|
||||||
|
text-align: right
|
||||||
|
}
|
||||||
|
|
||||||
|
a.login-button {
|
||||||
|
font-size: 200%;
|
||||||
|
margin: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.columns-title {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-column {
|
||||||
|
text-align: right;
|
||||||
|
padding: 1em 3em;
|
||||||
|
border-right: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-column {
|
||||||
|
text-align: left;
|
||||||
|
padding: 1em 3em;
|
||||||
|
border-left: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-column {
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
|
@ -2,31 +2,35 @@
|
||||||
class Statistics < Rails::Application
|
class Statistics < Rails::Application
|
||||||
|
|
||||||
def shameful_users
|
def shameful_users
|
||||||
User.where('balance > :amount', amount: config.shameful_balance)
|
User.humans
|
||||||
.order(balance: :desc)
|
.where('-balance > :amount', amount: config.shameful_balance)
|
||||||
|
.order(:balance)
|
||||||
end
|
end
|
||||||
|
|
||||||
def total_debt
|
def total_debt
|
||||||
User.where.not(id: User.zeus).where('balance > 0').sum(:balance)
|
-User.humans.where('balance < 0').sum(:balance)
|
||||||
end
|
end
|
||||||
|
|
||||||
def shamehash
|
def shamehash
|
||||||
none_shaming = shameful_users.sum(:balance)
|
none_shaming = total_debt + shameful_users.sum(:balance)
|
||||||
shameful_users.inject({'None-shameful users' => none_shaming}) do |h, u|
|
shameful_users.inject({'Reputable users' => none_shaming.to_f / total_debt}) do |h, u|
|
||||||
h.merge({u.name => u.balance})
|
h.merge({u.name => - u.balance.to_f / total_debt})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def by_issuer
|
def by_issuer
|
||||||
Transaction.group(:issuer_id).count.inject(Hash.new) do |hash, (id, count)|
|
Client.joins(:issued_transactions).group(:name).count.merge({
|
||||||
hash.merge({User.find(id).name => count})
|
"User created" => Transaction.where(issuer_type: "User").count
|
||||||
end
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
def amount_distribution
|
def creation_counts
|
||||||
Transaction.group("round(amount / 10)").count.inject(Hash.new) do |hash, (group, count)|
|
User
|
||||||
hash.merge({10 * group.to_i => count})
|
.joins(:issued_transactions)
|
||||||
end
|
.group(:name)
|
||||||
|
.order("count_all DESC")
|
||||||
|
.count
|
||||||
|
.take([shameful_users.count, 4].max)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -36,3 +40,4 @@ class Statistics < Rails::Application
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ class User < ActiveRecord::Base
|
||||||
|
|
||||||
validates :name, presence: true, uniqueness: true
|
validates :name, presence: true, uniqueness: true
|
||||||
|
|
||||||
|
scope :humans, -> { where.not(id: self.zeus) }
|
||||||
|
|
||||||
def transactions
|
def transactions
|
||||||
Transaction.where("creditor_id = ? OR debtor_id = ?", id, id)
|
Transaction.where("creditor_id = ? OR debtor_id = ?", id, id)
|
||||||
end
|
end
|
||||||
|
@ -42,4 +44,5 @@ class User < ActiveRecord::Base
|
||||||
def self.zeus
|
def self.zeus
|
||||||
find_or_create_by name: 'Zeus'
|
find_or_create_by name: 'Zeus'
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
- if current_user.penning
|
- if current_user.penning
|
||||||
%li.pure-menu-item
|
%li.pure-menu-item
|
||||||
=link_to "Zeus", User.zeus, class: "pure-menu-link"
|
=link_to "Zeus", User.zeus, class: "pure-menu-link"
|
||||||
- else
|
|
||||||
= link_to "Sign in", user_omniauth_authorize_path(:zeuswpi), class: "pure-menu-link" unless current_user
|
|
||||||
.pure-u-1
|
.pure-u-1
|
||||||
= render 'partials/flash'
|
= render 'partials/flash'
|
||||||
= yield
|
= yield
|
||||||
|
|
|
@ -1,33 +1,43 @@
|
||||||
%h1 Tab!
|
%h1.columns-title Tab
|
||||||
%h2 Authentication
|
|
||||||
- if user_signed_in?
|
|
||||||
%p Yeah! Je bent ingelogd.
|
|
||||||
- else
|
|
||||||
Log een keer in!
|
|
||||||
%p= link_to "Log in met Zeus WPI", user_omniauth_authorize_path(:zeuswpi)
|
|
||||||
%h2 Cute Little Statistics
|
|
||||||
= javascript_include_tag "//www.google.com/jsapi", "chartkick"
|
= javascript_include_tag "//www.google.com/jsapi", "chartkick"
|
||||||
.pure-g
|
- unless user_signed_in?
|
||||||
.pure-u-1-2
|
.pure-g
|
||||||
%h3 Table of Shame
|
.pure-u-1-2.left-column
|
||||||
%table.pure-table
|
%h2 Authentication
|
||||||
%thead
|
Log een keer in en betaal uw schulden!
|
||||||
%th Shame on
|
= link_to "Log in met Zeus WPI", user_omniauth_authorize_path(:zeuswpi), class: "pure-button pure-button-primary login-button"
|
||||||
%th Contribution to Zeus' lack of money
|
.pure-u-1-2.right-column
|
||||||
%tbody
|
%h2 Pie of Shame
|
||||||
- @statistics.shameful_users.each do |user|
|
= pie_chart @statistics.shamehash
|
||||||
%tr
|
- else
|
||||||
%td.shameful-person= user.name
|
%h2.columns-title Cute Little Statistics
|
||||||
// Won't divide by zero because there won't be any users with
|
.pure-g
|
||||||
// a shameful debt if the total debt is zero.
|
.pure-u-1-2.landing-column
|
||||||
%td.shame-percentage= "#{100 * user.balance / @statistics.total_debt}%"
|
%h3.columns-title Pie of Shame
|
||||||
.pure-u-1-2
|
= pie_chart @statistics.shamehash
|
||||||
%h3 Pie of Shame
|
%h3.columns-title Table of Shame
|
||||||
= pie_chart @statistics.shamehash
|
%table.pure-table.full-table
|
||||||
.pure-g
|
%thead
|
||||||
.pure-u-1-2
|
%th Shame on
|
||||||
%h3 Distribution of Debt Sources
|
%th Contribution to Zeus' lack of money
|
||||||
= pie_chart @statistics.by_issuer
|
%tbody
|
||||||
.pure-u-1-2
|
- @statistics.shameful_users.each do |user|
|
||||||
%h3 Distribution of Transaction Amounts
|
%tr
|
||||||
= column_chart @statistics.amount_distribution
|
%td.shameful-person= user.name
|
||||||
|
// Won't divide by zero because there won't be any users with
|
||||||
|
// a shameful debt if the total debt is zero.
|
||||||
|
%td.shame-percentage= "#{-100 * user.balance / @statistics.total_debt}%"
|
||||||
|
.pure-u-1-2.landing-column
|
||||||
|
%h3.columns-title Distribution of Debt Sources
|
||||||
|
= pie_chart @statistics.by_issuer
|
||||||
|
%h3.columns-title Top Debt Creators
|
||||||
|
%table.pure-table.full-table
|
||||||
|
%thead
|
||||||
|
%th Issuer
|
||||||
|
%th Number of Transactions issued
|
||||||
|
%tbody
|
||||||
|
- @statistics.creation_counts.each do |name, count|
|
||||||
|
%tr
|
||||||
|
%td.shameful-person= name
|
||||||
|
%td.shame-percentage= count
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,6 @@ module Tab
|
||||||
config.active_record.raise_in_transactional_callbacks = true
|
config.active_record.raise_in_transactional_callbacks = true
|
||||||
|
|
||||||
# Which is the lowest balance you should be ashamed of.
|
# Which is the lowest balance you should be ashamed of.
|
||||||
config.shameful_balance = 50 # In eurocents!
|
config.shameful_balance = 5000 # In eurocents!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,12 @@ unless Rails.env.production?
|
||||||
users = FactoryGirl.create_list(:user, 20)
|
users = FactoryGirl.create_list(:user, 20)
|
||||||
100.times do
|
100.times do
|
||||||
sample_users = users.sample(2)
|
sample_users = users.sample(2)
|
||||||
FactoryGirl.create :transaction, debtor: sample_users[0], creditor: sample_users[1], amount: 1 + rand(100)
|
FactoryGirl.create :transaction, debtor: sample_users[0], creditor: sample_users[1]
|
||||||
|
end
|
||||||
|
clients = FactoryGirl.create_list(:client, 5)
|
||||||
|
100.times do
|
||||||
|
debtor, creditor = users.sample(2)
|
||||||
|
FactoryGirl.create :client_transaction, issuer: clients.sample, debtor: debtor, creditor: creditor
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,7 +19,7 @@ FactoryGirl.define do
|
||||||
association :debtor, factory: :user
|
association :debtor, factory: :user
|
||||||
association :creditor, factory: :user
|
association :creditor, factory: :user
|
||||||
issuer { debtor }
|
issuer { debtor }
|
||||||
amount { 1 + rand(100) }
|
amount { 1 + rand(10000) }
|
||||||
message { Faker::Lorem.sentence }
|
message { Faker::Lorem.sentence }
|
||||||
factory :client_transaction do
|
factory :client_transaction do
|
||||||
association :issuer, factory: :client
|
association :issuer, factory: :client
|
||||||
|
|
Loading…
Reference in a new issue