PhoenixKitWebAnalytics.Web.Components (PhoenixKitWebAnalytics v0.5.0)

Copy Markdown View Source

The shared building blocks of the six report pages: the filter bar, stat tiles, the trend chart, and the ranked breakdown card.

The charts are CSS, not JavaScript

A module whose whole premise is "no client-side weight on your pages" would be a strange place to pull in a charting library for its own admin. Every visual here is divs with a percentage height or width — themed by daisyUI variables, responsive without a resize listener, and readable in both light and dark themes with no configuration. Values are exposed through title attributes, so hovering still tells you the exact number.

Summary

Functions

A ranked list: a label and one or two counts per row, with each row's share drawn as a bar behind it. Column headers sit on top, in the same fixed-width columns as the numbers, and the title's (i) explains where the data comes from and what the columns count.

The label for a stored channel (referrer_medium) value.

The label for a stored browser or operating-system name: real names (Chrome, macOS) are shown as they are; the two placeholders the User-Agent parser stores are translated.

The standard explanation of a breakdown card's Visitors / Views columns.

Percentage change from previous to current, or nil when there is no meaningful comparison (no previous data, or no previous period at all).

The label for a stored device class.

A short call to action shown when tracking is installed but off.

The period selector shared by every report page — plus the site selector, only when the app actually served more than one host (an app on one domain has nothing to choose), and the page-filter chip when one is active.

Formats a duration in seconds as 1m 05s.

Formats a millisecond duration.

Formats an integer with thousands separators.

Formats a percentage to one decimal place.

A timestamp for a list: the time alone for today, the date and time otherwise.

One hit described in words, with an icon — "Viewed page", "Clicked add_to_cart", "Left after 1m 05s" — for the live feed and session timelines.

A small (i) that opens an explanation — a card under the icon on wide screens, a full-width card on a phone. Opens and closes on the client, with no server round trip.

The label for an interaction name recorded by the client script.

A Reports.top_interactions/2 row as words: "Outbound link · github.com/x".

Top-interaction rows with their labels in words, for a breakdown card.

"N online" — people on the site now — linking to the Right now page.

"Newer" / "Older" paging under a list, with an optional summary between. Either phx-click events (newer_event / older_event) or links (newer_path / older_path, patched) move between pages.

The label for a period value: "7d" is "Last 7 days".

A titled card around a table or list, with an optional (i) explanation and actions on the right — the frame every report section shares.

Where a visit came from: the referring source, else its channel.

A list of visits (rows from Reports.sessions/2): when, who, where they landed and left, how many pages, what they did, how long, where from. Each row opens the visit's timeline. Cards on narrow screens.

A headline number, optionally with its change against the previous period and an (i) explanation (the :info slot).

The top row of every report page: the filters on the left, the online badge on the right. On the Right now page, pass no period (there is no window to choose) and no live_path.

The trend chart — core's server-rendered SVG bar_chart, one bar per bucket, with dates in a row beneath it that uses the chart's own slot widths, so every date sits under its bar. Only every few buckets are labelled (at most about seven), which keeps a month of days readable on a phone. Hovering a bar shows its exact date and count.

A visit's visitor: the signed-in user's display name, or "Anonymous".

Functions

breakdown_card(assigns)

A ranked list: a label and one or two counts per row, with each row's share drawn as a bar behind it. Column headers sit on top, in the same fixed-width columns as the numbers, and the title's (i) explains where the data comes from and what the columns count.

labels names a vocabulary the row labels come from (:channel, :device) so raw stored values ("organic", "desktop") are shown translated.

Attributes

  • id (:string) - needed for the (i) explanation. Defaults to nil.
  • title (:string) (required)
  • rows (:list) (required)
  • icon (:string) - Defaults to nil.
  • empty_message (:string) - Defaults to nil.
  • label_header (:string) - Defaults to nil.
  • metric_header (:string) - Defaults to nil.
  • link (:string) - Defaults to nil.
  • link_label (:string) - Defaults to nil.
  • labels (:atom) - Defaults to nil.Must be one of nil, :channel, :device, or :client.
  • show_visitors (:boolean) - Defaults to true.
  • info_align (:string) - Defaults to "start". Must be one of "start", or "end".

Slots

  • info

channel_label(medium)

@spec channel_label(String.t() | nil) :: String.t()

The label for a stored channel (referrer_medium) value.

client_label(name)

@spec client_label(String.t() | nil) :: String.t() | nil

The label for a stored browser or operating-system name: real names (Chrome, macOS) are shown as they are; the two placeholders the User-Agent parser stores are translated.

columns_explained(assigns)

The standard explanation of a breakdown card's Visitors / Views columns.

delta(current, previous)

@spec delta(number() | nil, number() | nil) :: float() | nil

Percentage change from previous to current, or nil when there is no meaningful comparison (no previous data, or no previous period at all).

device_label(other)

@spec device_label(String.t() | nil) :: String.t()

The label for a stored device class.

disabled_notice(assigns)

A short call to action shown when tracking is installed but off.

Attributes

  • settings_path (:string) (required)

filter_bar(assigns)

The period selector shared by every report page — plus the site selector, only when the app actually served more than one host (an app on one domain has nothing to choose), and the page-filter chip when one is active.

Emits phx-change="filter" with period, site and path params.

Attributes

  • id (:string) - Defaults to "web-analytics-filter".
  • period (:string) (required)
  • site (:string) - Defaults to nil.
  • sites (:list) - Defaults to [].
  • path (:string) - the active path filter, if any. Defaults to nil.
  • base_path (:string) - this report's URL, to clear the path filter. Defaults to nil.

format_duration(seconds)

@spec format_duration(number() | nil) :: String.t()

Formats a duration in seconds as 1m 05s.

iex> PhoenixKitWebAnalytics.Web.Components.format_duration(65.4)
"1m 05s"

format_ms(ms)

@spec format_ms(number() | nil) :: String.t()

Formats a millisecond duration.

format_number(value)

@spec format_number(integer() | float() | nil) :: String.t()

Formats an integer with thousands separators.

iex> PhoenixKitWebAnalytics.Web.Components.format_number(1234567)
"1,234,567"

format_percent(value)

@spec format_percent(number() | nil) :: String.t()

Formats a percentage to one decimal place.

format_time(at, now)

@spec format_time(DateTime.t() | NaiveDateTime.t() | nil, DateTime.t() | nil) ::
  String.t()

A timestamp for a list: the time alone for today, the date and time otherwise.

hit_summary(assigns)

One hit described in words, with an icon — "Viewed page", "Clicked add_to_cart", "Left after 1m 05s" — for the live feed and session timelines.

Attributes

  • hit (:map) (required)

info_tip(assigns)

A small (i) that opens an explanation — a card under the icon on wide screens, a full-width card on a phone. Opens and closes on the client, with no server round trip.

Attributes

  • id (:string) (required)
  • title (:string) (required)
  • align (:string) - Defaults to "start". Must be one of "start", or "end".

Slots

  • inner_block (required)

interaction_label(name)

@spec interaction_label(String.t() | nil) :: String.t()

The label for an interaction name recorded by the client script.

interaction_row_label(arg)

@spec interaction_row_label(map()) :: String.t()

A Reports.top_interactions/2 row as words: "Outbound link · github.com/x".

label_interactions(rows)

@spec label_interactions([map()]) :: [map()]

Top-interaction rows with their labels in words, for a breakdown card.

online_badge(assigns)

"N online" — people on the site now — linking to the Right now page.

Attributes

  • count (:integer) (required)
  • path (:string) - where the badge links; nil on the Right now page itself. Defaults to nil.

pager(assigns)

"Newer" / "Older" paging under a list, with an optional summary between. Either phx-click events (newer_event / older_event) or links (newer_path / older_path, patched) move between pages.

Attributes

  • newer? (:boolean) (required)
  • older? (:boolean) (required)
  • newer_event (:string) - Defaults to nil.
  • older_event (:string) - Defaults to nil.
  • newer_path (:string) - Defaults to nil.
  • older_path (:string) - Defaults to nil.
  • summary (:string) - Defaults to nil.

period_label(other)

@spec period_label(String.t()) :: String.t()

The label for a period value: "7d" is "Last 7 days".

report_card(assigns)

A titled card around a table or list, with an optional (i) explanation and actions on the right — the frame every report section shares.

Attributes

  • id (:string) (required)
  • title (:string) (required)
  • icon (:string) - Defaults to nil.
  • info_align (:string) - Defaults to "start". Must be one of "start", or "end".
  • class (:any) - Defaults to nil.

Slots

  • info
  • actions
  • inner_block (required)

session_source(session)

@spec session_source(map()) :: String.t()

Where a visit came from: the referring source, else its channel.

sessions_table(assigns)

A list of visits (rows from Reports.sessions/2): when, who, where they landed and left, how many pages, what they did, how long, where from. Each row opens the visit's timeline. Cards on narrow screens.

Attributes

  • id (:string) (required)
  • sessions (:list) (required)
  • names (:map) - Defaults to %{}.
  • now (:any) - Defaults to nil.
  • empty_message (:string) - Defaults to nil.

stat_tile(assigns)

A headline number, optionally with its change against the previous period and an (i) explanation (the :info slot).

Attributes

  • id (:string) (required)
  • label (:string) (required)
  • value (:string) (required)
  • delta (:float) - Defaults to nil.
  • delta_good (:atom) - Defaults to :up. Must be one of :up, or :down.
  • info_align (:string) - Defaults to "start". Must be one of "start", or "end".

Slots

  • info

top_row(assigns)

The top row of every report page: the filters on the left, the online badge on the right. On the Right now page, pass no period (there is no window to choose) and no live_path.

Attributes

  • period (:string) - Defaults to nil.
  • site (:string) - Defaults to nil.
  • sites (:list) - Defaults to [].
  • path (:string) - Defaults to nil.
  • base_path (:string) - Defaults to nil.
  • online (:integer) (required)
  • live_path (:string) - Defaults to nil.

traffic_chart(assigns)

The trend chart — core's server-rendered SVG bar_chart, one bar per bucket, with dates in a row beneath it that uses the chart's own slot widths, so every date sits under its bar. Only every few buckets are labelled (at most about seven), which keeps a month of days readable on a phone. Hovering a bar shows its exact date and count.

Attributes

  • id (:string) - Defaults to "web-analytics-trend".
  • series (:list) (required)
  • metric (:atom) - Defaults to :pageviews. Must be one of :pageviews, or :visitors.
  • bucket (:atom) - Defaults to :day.

visitor_name(arg1, names)

@spec visitor_name(map(), map()) :: String.t()

A visit's visitor: the signed-in user's display name, or "Anonymous".