Skip to content

Commit

Permalink
Showing difference comparing previous period (#39)
Browse files Browse the repository at this point in the history
* preparing for showing changes

comparing prior period.

* getting data from previous period

* let the start of the period be beginning of the day

* Cleaned up types

So we are not doing `.to_s` and `.to_i` after each other. no need anymore.
  • Loading branch information
confact committed Jun 16, 2020
1 parent f0e2c00 commit f68251c
Show file tree
Hide file tree
Showing 16 changed files with 159 additions and 37 deletions.
1 change: 1 addition & 0 deletions public/assets/svg/arrow-down-green.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/assets/svg/arrow-down-red.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/assets/svg/arrow-down.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/assets/svg/arrow-up-green.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/assets/svg/arrow-up-red.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/assets/svg/arrow-up.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/actions/domains/show.cr
Expand Up @@ -7,6 +7,6 @@ class Domains::Show < DomainBaseAction
if current_user.current_domain_id != domain.id
SaveUser.update!(current_user, current_domain_id: domain.id)
end
html ShowPage, domain: domain, total_unique: unique_query(domain), total_bounce: bounce_query(domain), total_sum: total_query(domain), period: period, period_string: period_string, sessions: SessionQuery.new.domain_id(domain_id), domains: domains
html ShowPage, domain: domain, total_unique: unique_query(domain), total_unique_previous: unique_query_previous(domain), total_bounce: bounce_query(domain), total_bounce_previous: bounce_query_previous(domain), total_sum: total_query(domain), total_previous: total_query_previous(domain), period: period, period_string: period_string, sessions: SessionQuery.new.domain_id(domain_id), domains: domains
end
end
44 changes: 41 additions & 3 deletions src/actions/mixins/domain_metric.cr
@@ -1,17 +1,55 @@
module DomainMetrics
def unique_query(domain) : String
def unique_query(domain) : Int64
metrics(domain).unique_query
end

def total_query(domain) : String
def total_query(domain) : Int64
metrics(domain).total_query
end

def bounce_query(domain) : String
def bounce_query(domain) : Int64
metrics(domain).bounce_query
end

def metrics(domain) : Metrics
@metrics ||= Metrics.new(domain, period)
end

def unique_query_previous(domain) : Int64
previous_metric(domain).unique_query
end

def total_query_previous(domain) : Int64
previous_metric(domain).total_query
end

def bounce_query_previous(domain) : Int64
previous_metric(domain).bounce_query
end

def previous_metric(domain) : MetricsNew
start_date, end_date = previous_period
@previous_metrics ||= MetricsNew.new(domain, start_date, end_date)
end

private def previous_period
case period
when "14d"
start_date = 15.days.ago.at_end_of_day
return [start_date - 14.days, start_date]
when "30d"
start_date = 31.days.ago.at_end_of_day
return [start_date - 30.days, start_date]
return "30 days"
when "60d"
start_date = 61.days.ago.at_end_of_day
return [start_date - 60.days, start_date]
when "90d"
start_date = 91.days.ago.at_end_of_day
return [start_date - 90.days, start_date]
else
start_date = 8.days.ago.at_end_of_day
return [start_date - 7.days, start_date]
end
end
end
2 changes: 1 addition & 1 deletion src/actions/share/show.cr
Expand Up @@ -12,6 +12,6 @@ class Share::Show < BrowserAction
domain = DomainQuery.find(ids.first)
DomainPolicy.show_share_not_found?(domain, current_user, context)

html ShowPage, domain: domain, share_page: true, total_unique: unique_query(domain), total_bounce: bounce_query(domain), total_sum: total_query(domain), period: period, period_string: period_string
html ShowPage, domain: domain, share_page: true, total_unique: unique_query(domain), total_unique_previous: unique_query_previous(domain), total_bounce: bounce_query(domain), total_bounce_previous: bounce_query_previous(domain), total_sum: total_query(domain), total_previous: total_query_previous(domain), period: period, period_string: period_string
end
end
51 changes: 51 additions & 0 deletions src/components/domains/difference_component.cr
@@ -0,0 +1,51 @@
class DifferenceComponent < BaseComponent
needs now : Int64
needs before : Int64
needs reverse : Bool = false

def render
div class: "flex items-center ml-4" do
if reverse?
if up?
img src: "/assets/svg/arrow-up-red.svg", class: "text-red-800 strong text-xs h-4 w-4 block mr-1"
span class: "text-red-800 strong text-xs" do
raw count_percentage + "%"
end
else
img src: "/assets/svg/arrow-down-green.svg", class: "text-green-800 strong text-xs h-4 w-4 block mr-1"
span class: "text-green-800 strong text-xs" do
raw count_percentage + "%"
end
end
else
if up?
img src: "/assets/svg/arrow-up-green.svg", class: "text-green-800 strong text-xs h-4 w-4 block mr-1"
span class: "text-green-800 strong text-xs" do
raw count_percentage + "%"
end
else
img src: "/assets/svg/arrow-down-red.svg", class: "text-red-800 strong text-xs h-4 w-4 block mr-1"
span class: "text-red-800 strong text-xs" do
raw count_percentage + "%"
end
end
end
end
end

private def up?
now > before
end

private def count_percentage : String
custom_now = now == 0 ? 0.1 : now
custom_before = before == 0 ? 0.1 : before
if up?
increase = custom_now - custom_before
((increase.to_f / custom_before)*100).format(decimal_places: 0, delimiter: "")
else
decrease = custom_before - custom_now
((decrease.to_f / custom_now)*100).format(decimal_places: 0, delimiter: "")
end
end
end
38 changes: 29 additions & 9 deletions src/components/domains/total_row_component.cr
@@ -1,24 +1,44 @@
class TotalRowComponent < BaseComponent
needs total_unique : String
needs total_sum : String
needs total_bounce : String
needs total_unique : Int64
needs total_sum : Int64
needs total_bounce : Int64
needs total_unique_previous : Int64
needs total_previous : Int64
needs total_bounce_previous : Int64

def render
div class: "big_letters" do
div class: "max-w-6xl mx-auto py-3 px-2 sm:px-0 grid grid-flow-col gap-6" do
div class: "p-3" do
para @total_unique.to_s, class: "text-3xl strong"
para "Unique Visitors", class: "text-sm uppercase"
div class: "text-4xl strong flex items-center" do
para normalize_number(@total_unique), class: "text-4xl strong"
mount DifferenceComponent.new(now: @total_unique, before: @total_unique_previous)
end
para "Unique", class: "text-sm uppercase font-bold"
end
div class: "p-3" do
para @total_sum.to_s, class: "text-3xl strong"
para "Total Pageviews", class: "text-sm strong uppercase"
div class: "text-4xl strong flex items-center" do
para normalize_number(@total_sum), class: "text-4xl strong"
mount DifferenceComponent.new(now: @total_sum, before: @total_previous)
end
para "Pageviews", class: "text-sm font-bold uppercase"
end
div class: "p-3" do
para "#{@total_bounce.to_s}%", class: "text-3xl strong"
para "Bounce rate", class: "text-sm strong uppercase"
div class: "text-4xl strong flex items-center" do
para "#{@total_bounce.to_s}%", class: "text-4xl strong"
mount DifferenceComponent.new(now: @total_bounce, before: @total_bounce_previous, reverse: true)
end
para "Bounce", class: "text-sm font-bold uppercase"
end
end
end
end

private def normalize_number(number : Int64) : String
if number >= 1000
number.humanize(precision: 2, significant: false)
else
number.to_s
end
end
end
11 changes: 7 additions & 4 deletions src/pages/domains/show_page.cr
@@ -1,9 +1,12 @@
class Domains::ShowPage < Domains::BasePage
needs sessions : SessionQuery
needs domains : DomainQuery
needs total_unique : String
needs total_sum : String
needs total_bounce : String
needs total_unique : Int64
needs total_sum : Int64
needs total_bounce : Int64
needs total_unique_previous : Int64
needs total_previous : Int64
needs total_bounce_previous : Int64
needs period_string : String
needs share_page : Bool = false
quick_def page_title, @domain.address
Expand All @@ -22,7 +25,7 @@ class Domains::ShowPage < Domains::BasePage
end

def render_total
mount TotalRowComponent.new(@total_unique, @total_sum, @total_bounce)
mount TotalRowComponent.new(@total_unique, @total_sum, @total_bounce, @total_unique_previous, @total_previous, @total_bounce_previous)
end

def render_canvas
Expand Down
11 changes: 7 additions & 4 deletions src/pages/shares/show_page.cr
@@ -1,10 +1,13 @@
class Share::ShowPage < MainGuestLayout
needs domain : Domain
needs period : String
needs total_unique : String
needs total_sum : String
needs total_bounce : String
needs total_unique : Int64
needs total_sum : Int64
needs total_bounce : Int64
needs period_string : String
needs total_unique_previous : Int64
needs total_previous : Int64
needs total_bounce_previous : Int64
needs share_page : Bool = true
quick_def page_title, @domain.address

Expand All @@ -28,7 +31,7 @@ class Share::ShowPage < MainGuestLayout
end

def render_total
mount TotalRowComponent.new(@total_unique, @total_sum, @total_bounce)
mount TotalRowComponent.new(@total_unique, @total_sum, @total_bounce, @total_unique_previous, @total_previous, @total_bounce_previous)
end

def render_canvas
Expand Down
4 changes: 2 additions & 2 deletions src/serializers/total_serializer.cr
@@ -1,8 +1,8 @@
class TotalSerializer < BaseSerializer
def initialize(@views : String, @bounce : String, @unique : String)
def initialize(@views : Int64, @bounce : Int64, @unique : Int64)
end

def render
{page_views: @views, bounce: @bounce, unique: @unique}
{page_views: @views.to_s, bounce: @bounce.to_s, unique: @unique.to_s}
end
end
10 changes: 5 additions & 5 deletions src/services/metrics.cr
Expand Up @@ -166,15 +166,15 @@ class Metrics
private def period_days : Time
case @period
when "14d"
return 14.days.ago
return 14.days.ago.at_beginning_of_day
when "30d"
return 30.days.ago
return 30.days.ago.at_beginning_of_day
when "60d"
return 60.days.ago
return 60.days.ago.at_beginning_of_day
when "90d"
return 90.days.ago
return 90.days.ago.at_beginning_of_day
else
return 7.days.ago
return 7.days.ago.at_beginning_of_day
end
end

Expand Down
17 changes: 9 additions & 8 deletions src/services/metrics_new.cr
Expand Up @@ -6,30 +6,31 @@ class MetricsNew
SessionQuery.new.domain_id(@domain.id).length.is_nil.select_count.to_s
end

def unique_query : String
def unique_query : Int64
sql = <<-SQL
SELECT COUNT(DISTINCT user_id) FROM events WHERE domain_id=#{@domain.id} AND created_at > '#{@from_date}' AND created_at < '#{@to_date}';
SQL
unique = AppDatabase.run do |db|
db.query_all sql, as: Int64
end
unique.first.to_s
unique.first
end

def total_query : String
EventQuery.new.domain_id(@domain.id).created_at.gt(@from_date).created_at.lt(@to_date).select_count.to_s
def total_query : Int64
EventQuery.new.domain_id(@domain.id).created_at.gt(@from_date).created_at.lt(@to_date).select_count
end

def bounce_query : String
return "0" if SessionQuery.new.domain_id(@domain.id).select_count == 0
def bounce_query : Int64
return 0.to_i64 if SessionQuery.new.domain_id(@domain.id).select_count == 0
sql = <<-SQL
SELECT round(sum(is_bounce * id) / sum(id) * 100) as bounce_rate
FROM sessions WHERE domain_id=#{@domain.id} AND created_at > '#{@from_date}' AND created_at < '#{@to_date}';
SQL
bounce = AppDatabase.run do |db|
db.query_all sql, as: PG::Numeric
db.query_all sql, as: PG::Numeric | Nil
end
bounce.first.to_s
return 0.to_i64 if bounce.first.nil?
bounce.first.not_nil!.to_s.to_i64
end

def get_referrers(limit : Int32 = 10) : Array(StatsReferrer)
Expand Down

0 comments on commit f68251c

Please sign in to comment.