A line chart: lines connecting points per data item across ordered categories.
Use a line chart to show a trend across ordered categories — metrics over time,
for example. Both single-series and multi-series charts are supported. Lines can
be solid or dashed (via :dashed => true, :style => :dashed, :stroke_dasharray,
or the :line_styles chart option), each series can have its own color, and series
can span subsets of the shared category axis.
Example
data = [
%{
name: "Trend",
data: [
%{label: "Jan", value: 10, attrs: %{"phx-click" => "select", "phx-value-id" => "1"}},
%{label: "Feb", value: 25}
]
},
%{
name: "Target",
dashed: true,
data: [
%{label: "Jan", value: 15},
%{label: "Feb", value: 20}
]
}
]
chart = Plotto.LineChart.new!(data, title: "Trend vs Target", legend: :top_right)
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 point (a small circle marker), 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. Series can also specify :dashed (true/false),
:style (:solid/:dashed), :stroke_dasharray (e.g. "6,4"), or :color (hex string).
The line chart struct.
Functions
Builds a line 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 point (a small circle marker), 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, tooltip: :data | :native | :title | false | nil | function(), label: boolean() | :label | :value | :top | nil | function(), line_styles: [atom() | String.t() | nil], stroke_width: number(), 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).
@type series() :: %{ :name => String.t() | nil, :data => [data_item()], optional(:dashed) => boolean(), optional(:dotted) => boolean(), optional(:style) => :solid | :dashed | :dotted, optional(:stroke_dasharray) => String.t(), optional(:stroke_width) => number(), optional(:line_width) => number(), optional(:color) => String.t() }
One data series: :name (required when there are 2+ series — see new/2) and its
list of data_item/0 points. Series can also specify :dashed (true/false),
:style (:solid/:dashed), :stroke_dasharray (e.g. "6,4"), or :color (hex string).
The line chart struct.
Functions
Builds a line chart. Returns {:ok, chart} or {:error, reason}.
data can be either a flat list of data_item/0 maps or a list of series/0 maps.
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 assigned to each series in order. 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.:line_styles- optional list of styles (:solid,:dashed,:dotted, or custom dash pattern strings like"6,4") corresponding to each series. Defaults to[].:stroke_width- optional stroke width in pixels for lines. Defaults to1.5. Can also be passed as:line_width, or specified per series.:label- optional point label placed immediately above each point. 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 points).: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.LineChart.new([%{name: "Trend", data: [%{label: "Jan", value: 10}]}])
iex> chart.data
[%{name: "Trend", data: [%{label: "Jan", value: 10}]}]
iex> {:ok, chart} =
...> Plotto.LineChart.new(
...> [%{name: "Trend", data: [%{label: "Jan", value: 10, attrs: %{"phx-click" => "select"}}]}],
...> title: "Trend",
...> colors: ["#000000"]
...> )
iex> {chart.opts.title, chart.opts.colors}
{"Trend", ["#000000"]}
iex> {:ok, chart} =
...> Plotto.LineChart.new(
...> [%{name: "Trend", data: [%{label: "Jan", value: 10}]}],
...> legend: :top_right
...> )
iex> chart.opts.legend
:top_right
iex> Plotto.LineChart.new([%{name: "Trend", data: [%{label: "Jan", value: 10}]}], legend: :middle)
{:error, "invalid legend position, got: :middle"}
iex> Plotto.LineChart.new([])
{:error, "data must not be empty"}
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.