# `Giggly.Factor`
[🔗](https://github.com/giggleton/giggly/blob/v0.1.0/lib/giggly/factor.ex#L1)

A column whose values have levels: the values it may hold, in an order of their own, which a
plot follows wherever it orders the column's values: on an axis, in a legend, in the groups a
stat counts and a position stacks, and in a facet's panels.

Put one in a table where a column would go:

    %{
      "cut" => Giggly.Factor.new(["Ideal", "Fair"], levels: ["Fair", "Good", "Ideal"]),
      "price" => [326, 327]
    }

A factor enumerates as its values, so anything that reads a table (`Table.Reader`, Explorer's
`DataFrame.new/1`, Kino's data table) reads the column as they are, without its levels.

`levels:` names each level as the values hold it (`[8, 4, 6]` for numbers), and a value not
among them is missing. Without it, the levels are the distinct values in order: numbers by
value, dates and times by time, strings by their bytes, `false` before `true`. `ordered: true`
marks the levels as ordered. The table refuses, when a plot reads it, levels that hold `nil`,
that name one value twice (`4` and `4.0` are one), or whose type is not the values'.

    iex> cut = Giggly.Factor.new(["Ideal", "Fair", "Ideal"], levels: ["Fair", "Good", "Ideal"])
    iex> Enum.to_list(cut)
    ["Ideal", "Fair", "Ideal"]
    iex> plot =
    ...>   %{"cut" => cut}
    ...>   |> Giggly.Plot.new(%{x: :cut})
    ...>   |> Giggly.Plot.geom_bar()
    iex> Giggly.panel_scales(plot, 1).x.levels
    ["Fair", "Ideal"]

A level no value holds takes no place on the axis, as `Good` takes none here.

# `t`

```elixir
@type t() :: %Giggly.Factor{
  levels: list() | :default,
  ordered: boolean(),
  values: list()
}
```

A factor: its values in row order, its levels, or `:default` for its distinct values in order,
and whether the levels are ordered.

# `new`

```elixir
@spec new(list(), keyword()) :: t()
```

A factor of `values`, a list in row order.

## Options

* `:levels` (list of `t:term/0`) - The values the factor may hold, in their order.

* `:ordered` (`t:boolean/0`) - Whether the levels are ordered. The default value is `false`.

---

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