Bland.DateTime (Elixir Technical Drawing v0.5.0)

Copy Markdown View Source

Date-axis support: conversion to a numeric representation, calendar- snapped tick generation, and strftime-based label formatting.

When a figure has xscale: :date (or yscale: :date), BLAND interprets axis values as epoch days — the integer day count since ~D[0000-01-01]. Series builders auto-convert Date.t() to this representation, and the renderer picks tick positions on calendar boundaries (month, quarter, or year starts depending on span).

Format the labels via the :xtick_format / :ytick_format option on Bland.axes/2. The format string is passed through to Calendar.strftime/2. The default format is picked from the chosen tick interval so labels stay legible at any zoom:

  • span < 60 days → "%b %d" (e.g. "Mar 14")
  • span < 1 yr → "%b %Y" (e.g. "Mar 2024")
  • span < 3 yr → "%b %Y" (quarter ticks)
  • span ≥ 3 yr → "%Y" (year ticks)

Summary

Functions

Converts a Date.t() to its numeric axis value (epoch days since ~D[0000-01-01]).

Formats an axis value as a date string via Calendar.strftime/2.

Returns {tick_axis_values, default_format} for the given axis-space domain {lo, hi} (epoch days) and approximate target tick count.

Functions

axis_to_date(days)

@spec axis_to_date(number()) :: Date.t()

Inverse of date_to_axis/1.

date_to_axis(d)

@spec date_to_axis(Date.t()) :: integer()

Converts a Date.t() to its numeric axis value (epoch days since ~D[0000-01-01]).

iex> Bland.DateTime.date_to_axis(~D[0000-01-01])
0

iex> Bland.DateTime.date_to_axis(~D[2024-01-01]) > 700_000
true

format(days, fmt)

@spec format(number(), String.t()) :: String.t()

Formats an axis value as a date string via Calendar.strftime/2.

nice_ticks(arg, target \\ 6)

@spec nice_ticks(
  {number(), number()},
  pos_integer()
) :: {[integer()], String.t()}

Returns {tick_axis_values, default_format} for the given axis-space domain {lo, hi} (epoch days) and approximate target tick count.

The format string picks an interval that yields roughly target ticks across the span:

  • span ≤ 60 days → daily/weekly snap
  • span ≤ 1 year → month-start snap
  • span ≤ 3 years → quarter-start snap
  • span > 3 years → year-start snap

Ticks are calendar-snapped: month ticks land on day-1 of each month, quarter ticks on Jan/Apr/Jul/Oct, year ticks on Jan 1.