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 | :left_top | :top_right | :right_top | :bottom_left | :left_bottom | :bottom_right | :right_bottom | nil, tooltip: :data | :native | :title | false | nil | function(), label: boolean() | :label | :value | :top | nil | function(), line_styles: [atom() | String.t() | nil], stroke_width: number() }
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,:left_top,:top_right,:right_top,:bottom_left,:left_bottom,:bottom_right, or:right_bottom. Defaults tonil(no legend).: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).
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.