improve analytics chart with hourly today view and readable labels
- add visitors_by_hour query for hourly breakdown on "today" period - replace SVG-only chart with HTML/CSS grid layout (bars + labels) - Y-axis scale with nice rounded max, midpoint, and zero - X-axis date labels (formatted as "Feb 18") spaced evenly - adaptive bar gaps (1px for sparse data, 0 for 365-day dense view) - labels use real HTML text so they're readable on mobile Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -148,6 +148,29 @@ defmodule Berrypod.Analytics do
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Hourly visitor counts for the trend chart (used for "today" period).
|
||||
|
||||
Returns a list of `%{hour: integer, visitors: integer}` maps for all 24 hours.
|
||||
"""
|
||||
def visitors_by_hour(date_range) do
|
||||
counts =
|
||||
base_query(date_range)
|
||||
|> where([e], e.name == "pageview")
|
||||
|> group_by([e], fragment("CAST(strftime('%H', ?) AS INTEGER)", e.inserted_at))
|
||||
|> select([e], %{
|
||||
hour: fragment("CAST(strftime('%H', ?) AS INTEGER)", e.inserted_at),
|
||||
visitors: count(e.visitor_hash, :distinct)
|
||||
})
|
||||
|> Repo.all()
|
||||
|> Map.new(&{&1.hour, &1.visitors})
|
||||
|
||||
# Fill in all 24 hours so the chart has no gaps
|
||||
Enum.map(0..23, fn h ->
|
||||
%{hour: h, visitors: Map.get(counts, h, 0)}
|
||||
end)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Top pages by unique visitors.
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user