A bar chart: one or more series, each rendered as a group of bars per category,
bar height proportional to :value.
Use a bar chart to compare values across categories — sales per month, votes per
candidate, and similar "one or more numbers per category" data. With multiple
series, each category shows one bar per series, grouped side by side and colored
per series (see :colors); a legend (see :legend) can label each series.
Example
data = [
%{
name: "Sales",
data: [
%{label: "Jan", value: 10, attrs: %{"phx-click" => "select", "phx-value-id" => "1"}},
%{label: "Feb", value: 25}
]
}
]
chart = Plotto.BarChart.new!(data, title: "Sales", colors: ["#4E79A7"])
svg = Plotto.to_svg!(chart)
png = Plotto.to_png!(chart)
Summary
Types
One data point: a category :label, its numeric :value, and optional :attrs —
arbitrary attribute/value pairs (e.g. "phx-click", "data-*") copied verbatim onto
the corresponding SVG/PNG element for that bar, without Plotto depending on Phoenix
or LiveView in any way.
One data series: :name (required when there are 2+ series — see new/2) and its
list of data_item/0 points. All series in a chart must share identical,
identically-ordered :labels across their :data.
The bar chart struct.
Functions
Builds a bar chart. Returns {:ok, chart} or {:error, reason}.
Same as new/2, but raises ArgumentError on invalid data instead of returning an
error tuple. See new/2 for the accepted data shape and available options.
Types
@type data_item() :: %{ :label => String.t(), :value => number(), optional(:attrs) => %{optional(String.t()) => String.t()} }
One data point: a category :label, its numeric :value, and optional :attrs —
arbitrary attribute/value pairs (e.g. "phx-click", "data-*") copied verbatim onto
the corresponding SVG/PNG element for that bar, without Plotto depending on Phoenix
or LiveView in any way.
@type options() :: %{ width: pos_integer(), height: pos_integer(), title: String.t() | nil, colors: [String.t()], legend: :top_left | :top_center | :top_right | :left_top | :left_middle | :left_bottom | :right_top | :right_middle | :right_bottom | :bottom_left | :bottom_center | :bottom_right | :top | :bottom | nil, legend_orientation: :vertical | :horizontal, mode: :grouped | :stacked, tooltip: :data | :native | :title | false | nil | function(), label: boolean() | :label | :value | :top | nil | function(), y_max: number() | nil, y_min: number() | nil, y_max_soft: boolean(), y_min_soft: boolean(), y_max_guide: false | {:solid | :dashed | :dotted, String.t()}, y_min_guide: false | {:solid | :dashed | :dotted, String.t()}, value_prefix: String.t() | nil, value_suffix: String.t() | nil, x_guidelines: false | {:solid | :dashed | :dotted, String.t()}, y_guidelines: false | {:solid | :dashed | :dotted, String.t()} }
Chart options, after defaults have been applied. Passed as a keyword list to
new/2/new!/2; stored in this resolved map form on the chart struct
(t/0's :opts field).
One data series: :name (required when there are 2+ series — see new/2) and its
list of data_item/0 points. All series in a chart must share identical,
identically-ordered :labels across their :data.
The bar chart struct.
Functions
Builds a bar chart. Returns {:ok, chart} or {:error, reason}.
data is a list of series/0 maps — one or more series, each with a :name
and a list of data_item/0 points. All series must have identical,
identically-ordered :labels; :name may be nil only when there is exactly one
series (2+ series must each have a non-nil :name, since it's shown in the
legend).
Options
:width- chart width in pixels. Defaults to600.:height- chart height in pixels. Defaults to400.:title- optional chart title, centered above the plot. Defaults tonil(no title).:colors- list of"#RRGGBB"hex color strings, cycled per series — all bars within one series share the same color (Theme.color(colors, series_index)). Defaults to["#4E79A7", "#F28E2B", "#E15759", "#76B7B2", "#59A14F"].:legend- optional legend position::top_left,:top_center,:top_right,:left_top,:left_middle,:left_bottom,:right_top,:right_middle,:right_bottom,:bottom_left,:bottom_center, or:bottom_right. Defaults tonil(no legend).:legend_orientation- optional legend layout orientation::verticalor:horizontal. Applies when:legendis a top or bottom position. Defaults to:vertical.:mode- bar chart layout mode::grouped(bars per series side by side) or:stacked(bars per series stacked vertically summing the total). Defaults to:grouped.:label- optional bar label placed immediately above each bar. Whentrue(or:label), displays the point's:label. Can also be:valueto display the numeric value, or a custom 1-2 arity function(item)or(item, series_name). Defaults tofalse(no label above bars).:y_max- optional maximum target or upper bound for the Y axis. Defaults tonil.:y_min- optional minimum target or lower bound for the Y axis. Defaults tonil.:y_max_soft- boolean indicating if:y_maxcan be exceeded if data values are greater. Defaults totrue.:y_min_soft- boolean indicating if:y_mincan be exceeded if data values are smaller. Defaults tofalse.:y_max_guide- optional horizontal guide line drawn aty_max:false,true, or{:solid | :dashed | :dotted, color}. Defaults tofalse.:y_min_guide- optional horizontal guide line drawn aty_min:false,true, or{:solid | :dashed | :dotted, color}. Defaults tofalse.:value_prefix- optional string prefix prepended to numeric values (e.g."$","€"). Can also be passed as:prefix. Defaults tonil.:value_suffix- optional string suffix appended to numeric values (e.g."%"). Can also be passed as:suffix. Defaults tonil.:x_guidelines- optional vertical guidelines drawn at each category:false,true, or{:solid | :dashed | :dotted, color}. Defaults tofalse.:y_guidelines- optional horizontal guidelines drawn at each Y-axis tick:false,true, or{:solid | :dashed | :dotted, color}. Defaults tofalse.
Examples
iex> {:ok, chart} = Plotto.BarChart.new([%{name: "Sales", data: [%{label: "Jan", value: 10}]}])
iex> chart.data
[%{name: "Sales", data: [%{label: "Jan", value: 10}]}]
iex> {:ok, chart} =
...> Plotto.BarChart.new(
...> [%{name: "Sales", data: [%{label: "Jan", value: 10, attrs: %{"phx-click" => "select"}}]}],
...> title: "Sales",
...> colors: ["#000000"]
...> )
iex> {chart.opts.title, chart.opts.colors}
{"Sales", ["#000000"]}
iex> {:ok, chart} =
...> Plotto.BarChart.new(
...> [%{name: "Sales", data: [%{label: "Jan", value: 10}]}],
...> legend: :top_right
...> )
iex> chart.opts.legend
:top_right
iex> Plotto.BarChart.new([%{name: "Sales", data: [%{label: "Jan", value: 10}]}], legend: :middle)
{:error, "invalid legend position, got: :middle"}
iex> Plotto.BarChart.new([])
{:error, "data must not be empty"}
iex> data = [
...> %{name: "Sales", data: [%{label: "Jan", value: 10}]},
...> %{name: nil, data: [%{label: "Jan", value: 5}]}
...> ]
iex> Plotto.BarChart.new(data)
{:error, "series name is required when there are multiple series"}
Same as new/2, but raises ArgumentError on invalid data instead of returning an
error tuple. See new/2 for the accepted data shape and available options.