Visualize.Scale.Time (Visualize v0.2.25)

Copy Markdown View Source

A scale for temporal data (DateTime, Date, NaiveDateTime).

Maps time values to a continuous numeric range. Ticks follow d3-time: an interval (seconds, minutes, hours, days, weeks, months, years, or a multiple of years) is chosen so that about count ticks fit the domain, and every tick sits on a boundary of that interval — a whole multiple of the seconds below a day, midnight, Monday, the first of the month, or 1 January — inside the domain.

Display zone

zone/2 gives the scale an IANA zone (spec/03 §7.4, D-115). Values are still Unix seconds, so apply/2 and every position are unchanged; the boundaries are read in the zone's local calendar instead of UTC — local midnights, local Mondays, the 1st of a local month — and sub-day ticks are the real instants whose local time is aligned, so the hour a transition repeats is ticked twice and the hour it skips not at all. ticks/2, nice/1 and invert/2 return DateTime values in the zone. The zone is read through the host's Calendar.TimeZoneDatabase; a name it cannot show raises ArgumentError.

Summary

Types

A tick interval: a unit and how many of it make one step.

t()

Why the host's time zone database cannot show a zone.

Functions

Applies the scale to a time value

Returns 0: a time scale has no bandwidth

Whether the host's time zone database can show zone: :ok, or the database's reason, {:error, :time_zone_not_found} or {:error, :utc_only_time_zone_database} (a host with no database configured).

Enables or disables clamping

Sets the domain

The interval about count ticks would use over a span of seconds (spec/03 §7.3.1).

Inverts the scale to get a DateTime, in the scale's zone (UTC without one)

A time value as the scale shows it: a DateTime in the scale's zone, the value reduced as apply/2 reduces it (a NaiveDateTime read as UTC, a Date as midnight UTC). A scale without a zone returns the value unchanged.

Creates a new time scale

Extends the domain outward to the boundaries of the interval ten ticks would use

Identity: a time scale has no padding

Sets the range

Generates tick values: every boundary of the chosen interval inside the domain, as DateTime values in the scale's zone (UTC without one), the boundaries read in that zone's local calendar. A descending domain yields the same ticks descending.

Sets the display zone: an IANA name such as "America/New_York", or nil for UTC (spec/03 §7.4).

Types

interval()

@type interval() ::
  {:second | :minute | :hour | :day | :week | :month | :year, pos_integer()}

A tick interval: a unit and how many of it make one step.

t()

@type t() :: %Visualize.Scale.Time{
  clamp?: boolean(),
  domain: [DateTime.t() | Date.t() | NaiveDateTime.t()] | nil,
  range: [number()],
  zone: Calendar.time_zone() | nil
}

zone_error()

@type zone_error() :: :time_zone_not_found | :utc_only_time_zone_database

Why the host's time zone database cannot show a zone.

Functions

apply(time, value)

@spec apply(t(), DateTime.t() | Date.t() | NaiveDateTime.t()) :: float()

Applies the scale to a time value

bandwidth(time)

@spec bandwidth(t()) :: 0

Returns 0: a time scale has no bandwidth

check_zone(zone)

@spec check_zone(Calendar.time_zone()) :: :ok | {:error, zone_error()}

Whether the host's time zone database can show zone: :ok, or the database's reason, {:error, :time_zone_not_found} or {:error, :utc_only_time_zone_database} (a host with no database configured).

clamp(scale, clamp?)

@spec clamp(t(), boolean()) :: t()

Enables or disables clamping

domain(scale, list)

@spec domain(t(), [DateTime.t() | Date.t() | NaiveDateTime.t()]) :: t()

Sets the domain

interval(seconds, count)

@spec interval(non_neg_integer(), pos_integer()) :: interval()

The interval about count ticks would use over a span of seconds (spec/03 §7.3.1).

Exposed for tests and for callers that format ticks by their interval; not part of the scale protocol.

invert(time, value)

@spec invert(t(), number()) :: DateTime.t()

Inverts the scale to get a DateTime, in the scale's zone (UTC without one)

local(time, value)

@spec local(t(), DateTime.t() | Date.t() | NaiveDateTime.t()) ::
  DateTime.t() | Date.t() | NaiveDateTime.t()

A time value as the scale shows it: a DateTime in the scale's zone, the value reduced as apply/2 reduces it (a NaiveDateTime read as UTC, a Date as midnight UTC). A scale without a zone returns the value unchanged.

new()

@spec new() :: t()

Creates a new time scale

nice(scale)

@spec nice(t()) :: t()

Extends the domain outward to the boundaries of the interval ten ticks would use

padding(scale, padding)

@spec padding(t(), number()) :: t()

Identity: a time scale has no padding

range(scale, list)

@spec range(t(), [number()]) :: t()

Sets the range

ticks(time, count)

@spec ticks(t(), integer()) :: [DateTime.t()]

Generates tick values: every boundary of the chosen interval inside the domain, as DateTime values in the scale's zone (UTC without one), the boundaries read in that zone's local calendar. A descending domain yields the same ticks descending.

zone(scale, zone)

@spec zone(t(), Calendar.time_zone() | nil) :: t()

Sets the display zone: an IANA name such as "America/New_York", or nil for UTC (spec/03 §7.4).

Raises ArgumentError naming the zone when the host's Calendar.TimeZoneDatabase does not know it, or when the host has configured none — never a silent fallback to UTC.