PhoenixLiveCalendar.Heatmap (PhoenixLiveCalendar v0.3.0)

Copy Markdown View Source

Maps per-day numeric data onto heatmap-style PhoenixLiveCalendar.DayMarkers — the GitHub-contributions look for the month and year views.

Give it a map (or list of pairs) of Date => value and it returns one marker per active day, carrying an intensity class from the palette as the marker color (which the month grid renders as the whole cell background and the year view as the mini-cell tint):

markers = Heatmap.markers(%{~D[2026-04-01] => 12, ~D[2026-04-02] => 95})

<.live_component
  module={PhoenixLiveCalendar.CalendarComponent}
  id="history"
  day_markers={markers}
/>

Options

  • :palette — intensity classes low → high, either a list or a preset: :success (default, green ramp), :heat (warning → error), :cool (info ramp), :mono (base-content greys). Custom classes must be COMPLETE Tailwind class names the host app already uses or safelists — interpolated names get purged
  • :style:fill (default): the class becomes the marker color, so the whole cell tints. :dot: the cell keeps its normal background and the views render a small intensity dot instead — much quieter next to event content
  • :scale:linear (bucket by value / max, default) or :quantile (bucket by rank, so outliers don't wash out the rest)
  • :max — explicit ceiling for the linear scale (default: the data's max)
  • :labelvalue -> String.t() for the marker label (used by tooltips and, when show_label: true, the corner chip). Pass nil for no label
  • :show_label — render the corner label chip (default false; heatmap days usually want just the tint)
  • :id_prefix — marker id prefix (default "heatmap")

Days with a zero, negative, or non-numeric value get no marker — no activity means no tint. The raw value is kept in marker.extra.value.

Summary

Functions

The raw bucketing: Date => value data to %{Date => %{class: intensity_class, value: value}} — for building custom heatmap renderings (the Widgets.activity_grid/1 year strip uses it). Same options as markers/2 (:palette, :scale, :max).

The default 5-step intensity palette.

Builds one heatmap DayMarker per active day from Date => value data.

A preset palette's class list (:success / :heat / :cool / :mono).

Functions

classes(data, opts \\ [])

@spec classes(
  %{optional(Date.t()) => number()} | Enumerable.t(),
  keyword()
) :: %{optional(Date.t()) => %{class: String.t(), value: number()}}

The raw bucketing: Date => value data to %{Date => %{class: intensity_class, value: value}} — for building custom heatmap renderings (the Widgets.activity_grid/1 year strip uses it). Same options as markers/2 (:palette, :scale, :max).

default_palette()

@spec default_palette() :: [String.t()]

The default 5-step intensity palette.

markers(data, opts \\ [])

@spec markers(
  %{optional(Date.t()) => number()} | Enumerable.t(),
  keyword()
) :: [PhoenixLiveCalendar.DayMarker.t()]

Builds one heatmap DayMarker per active day from Date => value data.

Accepts a map or an enumerable of {Date, value} pairs. See the moduledoc for options.

palette(classes)

@spec palette(atom() | [String.t()]) :: [String.t()]

A preset palette's class list (:success / :heat / :cool / :mono).