# `GanttEx.Zoom`
[🔗](https://github.com/rocket4ce/gantt_ex/blob/v0.1.0/lib/gantt_ex/zoom.ex#L1)

Zoom levels: named combinations of scales and column width.

Levels are ordered from the most detailed to the least detailed. The
default levels are `:hour`, `:day`, `:week`, `:month`, `:quarter` and `:year`.

Custom levels can be given to `GanttEx.Live.Gantt` through its `zoom_levels`
attribute:

    [
      %{name: :sprint, column_width: 60, scales: [[unit: :month, format: :month_year], [unit: :week, step: 2]]},
      %{name: :month, column_width: 80, scales: [[unit: :year], [unit: :month]]}
    ]

## Examples

    iex> levels = GanttEx.Zoom.default_levels()
    iex> Enum.map(levels, & &1.name)
    [:hour, :day, :week, :month, :quarter, :year]
    iex> GanttEx.Zoom.zoom_in(levels, :week)
    :day
    iex> GanttEx.Zoom.zoom_out(levels, :year)
    :year

# `level`

```elixir
@type level() :: %{
  name: atom(),
  column_width: pos_integer(),
  scales: [GanttEx.Scale.t(), ...]
}
```

A zoom level.

# `can_zoom?`

```elixir
@spec can_zoom?([level()], atom(), :in | :out) :: boolean()
```

Returns `true` if `name` can be zoomed further in the given direction.

    iex> GanttEx.Zoom.can_zoom?(GanttEx.Zoom.default_levels(), :hour, :in)
    false

# `default_levels`

```elixir
@spec default_levels() :: [level()]
```

Returns the default zoom levels.

# `find`

```elixir
@spec find([level()], atom()) :: level()
```

Finds a level by name, falling back to the first level.

    iex> GanttEx.Zoom.find(GanttEx.Zoom.default_levels(), :month).column_width
    80

# `normalize!`

```elixir
@spec normalize!([map()]) :: [level()]
```

Validates and normalizes a list of levels, building `GanttEx.Scale` structs.

    iex> [level] = GanttEx.Zoom.normalize!([%{name: :custom, scales: [[unit: :day]]}])
    iex> {level.column_width, hd(level.scales).unit}
    {60, :day}

# `zoom_in`

```elixir
@spec zoom_in([level()], atom()) :: atom()
```

Returns the name of the next, more detailed level.

# `zoom_out`

```elixir
@spec zoom_out([level()], atom()) :: atom()
```

Returns the name of the next, less detailed level.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
