Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dl/remove broken charts #23

Merged
merged 2 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 15 additions & 119 deletions app/controllers/analytics_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,30 @@ class AnalyticsController < ApplicationController
before_action :authenticate_user!

def index
@total_page_views = Rails.cache.fetch("#{cache_key_with_version}/total_page_views", expires_in: CACHE_EXPIRATION) do
current_user.page_views.count
end

@total_link_clicks = Rails.cache.fetch("#{cache_key_with_version}/total_link_clicks", expires_in: CACHE_EXPIRATION) do
current_user.link_clicks.count
end

@total_achievement_views = Rails.cache.fetch("#{cache_key_with_version}/total_achievement_views", expires_in: CACHE_EXPIRATION) do
current_user.achievement_views.count
end

@unique_visitors = Rails.cache.fetch("#{cache_key_with_version}/unique_visitors", expires_in: CACHE_EXPIRATION) do
current_user.page_views.select(:ip_address).distinct.count
end

@latest_daily_metric = Rails.cache.fetch("#{cache_key_with_version}/latest_daily_metric", expires_in: CACHE_EXPIRATION) do
current_user.daily_metrics.order(date: :desc).first
end

@link_analytics = Rails.cache.fetch("#{cache_key_with_version}/link_analytics", expires_in: CACHE_EXPIRATION) { fetch_link_analytics }
@achievement_analytics = Rails.cache.fetch("#{cache_key_with_version}/achievement_analytics", expires_in: CACHE_EXPIRATION) { fetch_achievement_analytics }
@geographic_data = Rails.cache.fetch("#{cache_key_with_version}/geographic_data", expires_in: CACHE_EXPIRATION) { fetch_geographic_data }
@daily_views = Rails.cache.fetch("#{cache_key_with_version}/daily_views", expires_in: CACHE_EXPIRATION) { fetch_daily_views }
@hourly_distribution = Rails.cache.fetch("#{cache_key_with_version}/hourly_distribution", expires_in: CACHE_EXPIRATION) { fetch_hourly_distribution }
@browser_data = Rails.cache.fetch("#{cache_key_with_version}/browser_data", expires_in: CACHE_EXPIRATION) { fetch_browser_data }
@top_referrers = Rails.cache.fetch("#{cache_key_with_version}/top_referrers", expires_in: CACHE_EXPIRATION) { fetch_top_referrers }
@total_page_views = fetch_cached_data("total_page_views") { current_user.page_views.count }
@total_link_clicks = fetch_cached_data("total_link_clicks") { current_user.link_clicks.count }
@total_achievement_views = fetch_cached_data("total_achievement_views") { current_user.achievement_views.count }
@unique_visitors = fetch_cached_data("unique_visitors") { current_user.page_views.select(:ip_address).distinct.count }
@latest_daily_metric = fetch_cached_data("latest_daily_metric") { current_user.daily_metrics.order(date: :desc).first }
@link_analytics = fetch_cached_data("link_analytics") { fetch_link_analytics }
@achievement_analytics = fetch_cached_data("achievement_analytics") { fetch_achievement_analytics }
@daily_views = fetch_cached_data("daily_views") { fetch_daily_views }
@browser_data = fetch_cached_data("browser_data") { fetch_browser_data }
end

private

def fetch_cached_data(key, &block)
Rails.cache.fetch("#{cache_key_with_version}/#{key}", expires_in: CACHE_EXPIRATION, &block)
end

def fetch_link_analytics
current_user.links.includes(:link_clicks).map do |link|
{
id: link.id,
title: link.title,
total_clicks: link.link_clicks.count,
unique_visitors: link.link_clicks.select(:ip_address).distinct.count,
top_referrers: link.link_clicks.group(:referrer).count.sort_by { |_, v| -v }.take(5),
browser_breakdown: link.link_clicks.group(:browser).count
unique_visitors: link.link_clicks.select(:ip_address).distinct.count
}
end
end
Expand All @@ -57,21 +41,10 @@ def fetch_achievement_analytics
end
end

def fetch_geographic_data
current_user.page_views.group(:ip_address).count.transform_keys do |ip|
location = Geocoder.search(ip).first
location ? "#{location.city}, #{location.country}" : "Unknown"
end
end

def fetch_daily_views
current_user.page_views.group_by_day(:visited_at, range: 30.days.ago..Time.now).count
end

def fetch_hourly_distribution
current_user.page_views.group_by_hour_of_day(:visited_at).count
end

def fetch_browser_data
current_user.page_views.group(:browser).count.transform_keys do |user_agent|
case user_agent
Expand Down Expand Up @@ -111,84 +84,7 @@ def fetch_browser_data
end
end

def fetch_top_referrers
referrers = current_user.page_views.group(:referrer).count

# Normalize referrers to group similar ones together
normalized_referrers = referrers.each_with_object(Hash.new(0)) do |(referrer, count), hash|
normalized_referrer = normalize_referrer(referrer)
hash[normalized_referrer] += count
end

normalized_referrers.sort_by { |_, v| -v }.take(10)
end

def normalize_referrer(referrer)
return 'Direct' if referrer.blank?

uri = URI.parse(referrer)
host = uri.host.downcase

# Remove 'www.' prefix for consistency
host = host.start_with?('www.') ? host[4..-1] : host

# Normalize common referrers
case host
when 't.co'
'Twitter'
when 'facebook.com', 'fb.com'
'Facebook'
when 'instagram.com'
'Instagram'
when 'linkedin.com'
'LinkedIn'
when 'pinterest.com'
'Pinterest'
when 'youtube.com', 'youtu.be'
'YouTube'
when 'reddit.com'
'Reddit'
when 'tumblr.com'
'Tumblr'
when 'snapchat.com'
'Snapchat'
when 'whatsapp.com'
'WhatsApp'
when 'telegram.org'
'Telegram'
when 'discord.com', 'discordapp.com'
'Discord'
when 'google.com', 'google.co.uk', 'google.fr', 'google.de', 'google.es',
'google.it', 'google.ca', 'google.com.au', 'google.co.in', 'google.co.jp'
'Google'
when 'bing.com'
'Bing'
when 'yahoo.com', 'yahoo.co.jp'
'Yahoo'
when 'duckduckgo.com'
'DuckDuckGo'
when 'baidu.com'
'Baidu'
when 'yandex.com', 'yandex.ru'
'Yandex'
when 'amazon.com', 'amazon.co.uk', 'amazon.de', 'amazon.fr', 'amazon.co.jp'
'Amazon'
when 'ebay.com', 'ebay.co.uk'
'eBay'
when 'quora.com'
'Quora'
when 'medium.com'
'Medium'
when 'wikipedia.org'
'Wikipedia'
else
host.capitalize # Default to capitalized host if not matched
end
rescue URI::InvalidURIError
'Unknown'
end

def cache_key_with_version
"user_#{current_user.id}_analytics_v1"
end
end
end
34 changes: 2 additions & 32 deletions app/views/analytics/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -99,25 +99,7 @@
</div>

<!-- Charts Section -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
<!-- Geographic Data -->
<div class="bg-gray-800 rounded-lg shadow p-4">
<h2 class="text-xl font-semibold mb-4">Visitor Locations</h2>
<%= pie_chart @geographic_data,
colors: ["#84CC16", "#22D3EE", "#E879F9", "#F87171", "#A78BFA"],
library: {
backgroundColor: 'transparent',
legend: { position: 'bottom', labels: { color: 'white', fontSize: 12 } },
title: { display: true, text: 'Visitor Locations', color: 'white', fontSize: 16 },
responsive: true,
plugins: { datalabels: { color: 'white', font: { weight: 'bold' } } }
},
donut: true,
prefix: "",
thousands: ",",
round: 2,
height: "300px" %>
</div>
<div class="grid grid-cols-1 gap-6 mb-6">

<!-- Time-based Analytics -->
<div class="bg-gray-800 rounded-lg shadow p-4">
Expand All @@ -143,7 +125,7 @@
</div>

<!-- Browser Usage and Top Sources -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="grid grid-cols-1 gap-6">
<!-- Browser Usage -->
<div class="bg-gray-800 rounded-lg shadow p-4">
<h2 class="text-xl font-semibold mb-4">Browser Usage</h2>
Expand All @@ -159,16 +141,4 @@
donut: true,
height: "250px" %>
</div>

<!-- Top Sources -->
<div class="bg-gray-800 rounded-lg shadow p-4">
<h2 class="text-xl font-semibold mb-4">Top Sources</h2>
<ul class="list-disc list-inside">
<% @top_referrers.each do |referrer, count| %>
<li class="text-lime-400 bg-gray-700 rounded-lg px-3 py-2 my-1">
<%= format_referrer(referrer) %>: <%= number_with_delimiter(count) %> visits
</li>
<% end %>
</ul>
</div>
</div>
Loading