View Source SparklineSvg (Sparkline SVG v0.1.1)

SparklineSvg is a library to generate SVG sparkline charts.

A sparkline is a small, simple chart that is drawn without axes or coordinates. It presents the general shape of the variation of a dataset at a glance.

SparklineSvg allows you to create a sparkline chart from various data shapes and show the dots, the line, and the area under the line. You can also add markers to the chart to highlight specific spots.

Usage example

# Datapoints and general options
datapoints = [1, 3, 2, 2, 5]
options = [width: 200, height: 40]

# A very simple line chart
sparkline = SparklineSvg.new(datapoints, options)

# Display what you want
line_options = [width: 0.3, color: "green"]
sparkline = SparklineSvg.show_line(sparkline, line_options)

# Render the chart to an SVG string
{:ok, svg} = SparklineSvg.to_svg(sparkline) # or
svg = SparklineSvg.to_svg!(sparkline)

Datapoints

Datapoints are the values that will be used to draw the chart. They can be:

  • A list of numbers, where each number is a value for the y axis. The x axis will be the index of the number in the list.
  • A list of tuples with two values. The first value is the x axis and the second value is the y axis. The x value can be a number, a DateTime, a Date, a Time, or a NaiveDateTime. The y value must be a number.

All values in the list must be of the same type.

Simple datapoints

# Number datapoints
datapoints = [1, 2, 3]
datapoints = [1.1, 1.2, 1.3]

# Datapoints with DateTime
datapoints = [~U[2021-01-01 00:00:00Z], ~U[2021-01-02 00:00:00Z], ~U[2021-01-03 00:00:00Z]]

# Datapoints with Date
datapoints = [~D[2021-01-01], ~D[2021-01-02], ~D[2021-01-03]]

# Datapoints with Time
datapoints = [~T[00:01:00], ~T[00:02:00], ~T[00:03:00]]

# Datapoints with NaiveDateTime
datapoints = [~N[2021-01-01 00:00:00], ~N[2021-01-02 00:00:00], ~N[2021-01-03 00:00:00]]

Tuple-based datapoints

# Datapoints
datapoints = [{1, 1}, {2, 2}, {3, 3}]
datapoints = [{1.1, 1}, {1.2, 2}, {1.3, 3}]

# Datapoints with DateTime
datapoints = [
  {~U[2021-01-01 00:00:00Z], 1},
  {~U[2021-01-02 00:00:00Z], 2},
  {~U[2021-01-03 00:00:00Z], 3}
]

# Datapoints with Date
datapoints = [{~D[2021-01-01], 1}, {~D[2021-01-02], 2}, {~D[2021-01-03], 3}]

# Datapoints with Time
datapoints = [{~T[00:01:00], 1}, {~T[00:02:00], 2}, {~T[00:03:00], 3}]

# Datapoints with NaiveDateTime
datapoints = [
  {~N[2021-01-01 00:00:00], 1},
  {~N[2021-01-02 00:00:00], 2},
  {~N[2021-01-03 00:00:00], 3}
]

Markers

Markers are used to highlight specific spots on the chart. They differ from the datapoints and therefore are set separately from it. You can add as many markers as you want to a chart.

There are two types of markers:

  • A single marker that will be rendered as a vertical line.
  • A range marker that will be rendered as a rectangle.

Markers are not used to calculate the boundaries of the chart. If a marker is set outside the range of the chart, it will be rendered but won't be visible.

Single marker

svg =
  datapoints
  |> SparklineSvg.new()
  |> SparklineSvg.show_line()
  |> SparklineSvg.add_marker(2)
  |> SparklineSvg.add_marker([3, 4])
  |> SparklineSvg.to_svg!()

Range marker

svg =
  datapoints
  |> SparklineSvg.new()
  |> SparklineSvg.show_line()
  |> SparklineSvg.add_marker({1, 2})
  |> SparklineSvg.add_marker([{3, 4}, {5, 6}])
  |> SparklineSvg.to_svg!()

Customization

SparklineSvg allows you to customize the chart showing or hiding the dots, the line, and the area under the line.

There are two ways to customize the chart:

  • Using the options like :color or :width.
  • Using the CSS classes option to give classes to SVG elements and then using CSS to style them.

Options

svg =
  datapoints
  |> SparklineSvg.new(width: 100, height: 40, padding: 0.5, smoothing: 0.1, placeholder: "No data")
  |> SparklineSvg.show_dots(radius: 0.1, color: "rgb(255, 255, 255)")
  |> SparklineSvg.show_line(width: 0.5, color: "rgb(166, 218, 149)")
  |> SparklineSvg.show_area(color: "rgba(166, 218, 149, 0.2)")
  |> SparklineSvg.add_marker(1, stroke_color: "red", stroke_width: 0.5)
  |> SparklineSvg.to_svg!()

CSS classes

svg =
  datapoints
  |> SparklineSvg.new(smoothing: 0.1, placeholder: "No data", class: "sparkline")
  |> SparklineSvg.show_dots(class: "sparkline-dots")
  |> SparklineSvg.show_line(class: "sparkline-line")
  |> SparklineSvg.show_area(class: "sparkline-area")
  |> SparklineSvg.add_marker(1, class: "sparkline-marker")
  |> SparklineSvg.to_svg!()

Tailwind classes

svg =
  datapoints
  |> SparklineSvg.new(smoothing: 0.1, placeholder: "No data", class: "bg-transparent")
  |> SparklineSvg.show_dots(class: "fill-green")
  |> SparklineSvg.show_line(class: "stroke-green stroke-[0.5px] fill-transparent")
  |> SparklineSvg.show_area(class: "fill-green/10")
  |> SparklineSvg.add_marker(1, class: "stroke-red stroke-[0.5px] fill-transparent")
  |> SparklineSvg.to_svg!()

When using the CSS classes to style the chart, the other options like :color or :width will be ignored. However, some options (:width, :height, padding, smoothing, and placeholder), are used internally to render the chart and are required in any case.

Available options

Use the following options to customize the chart:

  • :width - the width of the chart, defaults to 200.
  • :height - the height of the chart, defaults to 50.
  • :padding - the padding of the chart, defaults to 2. Not targetable with CSS classes. Padding has to be set to a value which padding * 2 < width and padding * 2 < height otherwise a :invalid_dimension error will be raised.
  • :smoothing - the smoothing of the line (0 = no smoothing, above 0.4 it becomes unreadable), defaults to 0.15. Not targetable with CSS classes.
  • :placeholder - a placeholder for an empty chart, defaults to nil. If set to nil, a chart with no datapoints will be an empty SVG document. Alternatively, you can set it to a string to display a message when the chart is empty. Not targetable with CSS classes.
  • :class - the value of the HTML class attribut of the chart, defaults to nil.
  • :placeholder_class - the value of the HTML class attribut of the placeholder, defaults to nil. It is the only way to style the placeholder.

Dots options

  • :radius - the radius of the dots, defaults to 1.
  • :color - the color of the dots, defaults to "black".
  • :class - the value of the HTML class attribut of the dots, defaults to nil.

Line options

  • :width - the width of the line, defaults to 0.25.
  • :color - the color of the line, defaults to "black".
  • :class - the value of the HTML class attribut of the line, defaults to nil.

Area options

  • :color - the color of the area under the line, defaults to "rgba(0, 0, 0, 0.1)".
  • :class - the value of the HTML class attribut of the area, defaults to nil.

Marker options

  • :stroke_width - the stroke width of the marker, defaults to 0.25.
  • :stroke_color - the stroke color of the marker, defaults to "red".
  • :fill_color - the fill color of an area marker, defaults to "rgba(255, 0, 0, 0.1)".
  • :class - the value of the HTML class attribut of the marker, defaults to nil.

Summary

Types

Keyword list of options for the area under the line of the chart.

A datapoint for the chart.

A list of datapoint.

Keyword list of options for the dots of the chart.

Keyword list of options for the line of the chart.

A value or a two-tuple value for the x axis of the chart.

Keyword list of options for a marker of the chart.

A list of values or a list of two-tuple values for the x axis of the chart.

Keyword list of options for the chart.

x()

A value for the x axis of the chart.

y()

A number value for the y axis of the chart.

Functions

Add one or many markers to a sparkline struct with the given options.

Convert a svg string into a Base64 string to be used, for example, as a background-image.

Create a new sparkline struct with the given datapoints and options.

Take a sparkline struct and return a new sparkline struct with the given area options.

Take a sparkline struct and return a new sparkline struct with the given dots options.

Take a sparkline struct and return a new sparkline struct with the given line options.

Return a valid SVG document from a sparkline struct.

Return a valid SVG document from a sparkline struct.

Types

@type area_options() :: [color: String.t(), class: nil | String.t()]

Keyword list of options for the area under the line of the chart.

@type datapoint() :: y() | {x(), y()}

A datapoint for the chart.

@type datapoints() ::
  [y()]
  | [{number(), y()}]
  | [{DateTime.t(), y()}]
  | [{Date.t(), y()}]
  | [{Time.t(), y()}]
  | [{NaiveDateTime.t(), y()}]

A list of datapoint.

It can be a list of various types of datapoints, but all the datapoints in the list must be of the same type.

@type dots_options() :: [radius: number(), color: String.t(), class: nil | String.t()]

Keyword list of options for the dots of the chart.

@type line_options() :: [width: number(), color: String.t(), class: nil | String.t()]

Keyword list of options for the line of the chart.

@type marker() :: x() | {x(), x()}

A value or a two-tuple value for the x axis of the chart.

@type marker_options() :: [
  fill_color: String.t(),
  stroke_color: String.t(),
  stroke_width: number(),
  class: nil | String.t()
]

Keyword list of options for a marker of the chart.

@type markers() ::
  [number()]
  | [DateTime.t()]
  | [Date.t()]
  | [Time.t()]
  | [NaiveDateTime.t()]
  | [{number(), number()}]
  | [{DateTime.t(), DateTime.t()}]
  | [{Date.t(), Date.t()}]
  | [{Time.t(), Time.t()}]
  | [{NaiveDateTime.t(), NaiveDateTime.t()}]

A list of values or a list of two-tuple values for the x axis of the chart.

@type options() :: [
  width: number(),
  height: number(),
  padding: number(),
  smoothing: number(),
  placeholder: nil | String.t(),
  class: nil | String.t(),
  placeholder_class: nil | String.t()
]

Keyword list of options for the chart.

@type x() :: number() | DateTime.t() | Date.t() | Time.t() | NaiveDateTime.t()

A value for the x axis of the chart.

@type y() :: number()

A number value for the y axis of the chart.

Functions

Link to this function

add_marker(sparkline, markers, options \\ [])

View Source
@spec add_marker(t(), marker() | markers(), marker_options()) :: t()

Add one or many markers to a sparkline struct with the given options.

When calling this function with a list of markers, the options will be applied to all the markers.

If you want to apply different options to different markers, you can call this function multiple times with a single marker and the desired options.

Markers are not used to calculate the boudaries of the chart. If you set a marker outside the range of the chart, it will be rendered but won't be visible.

Examples

iex> chart = SparklineSvg.new([1, 3]) |> SparklineSvg.add_marker(2)
iex> SparklineSvg.to_svg!(chart)
~S'<svg width="100%" height="100%" viewBox="0 0 200 50" xmlns="http://www.w3.org/2000/svg"><path d="M394.0,0.0V50" fill="none" stroke="red" stroke-width="0.25" /></svg>'

iex> chart = SparklineSvg.new([1, 3]) |> SparklineSvg.add_marker({2.1, 2.4})
iex> SparklineSvg.to_svg!(chart)
~S'<svg width="100%" height="100%" viewBox="0 0 200 50" xmlns="http://www.w3.org/2000/svg"><rect x="413.6" y="-0.25" width="58.8" height="50.5" fill="rgba(255, 0, 0, 0.1)" stroke="red" stroke-width="0.25" /></svg>'

iex> chart = SparklineSvg.new([1, 3]) |> SparklineSvg.add_marker(2, stroke_color: "rgba(0, 255, 0, 0.2)")
iex> SparklineSvg.to_svg!(chart)
~S'<svg width="100%" height="100%" viewBox="0 0 200 50" xmlns="http://www.w3.org/2000/svg"><path d="M394.0,0.0V50" fill="none" stroke="rgba(0, 255, 0, 0.2)" stroke-width="0.25" /></svg>'
@spec as_data_uri(String.t()) :: String.t()

Convert a svg string into a Base64 string to be used, for example, as a background-image.

Note that using SVG as a background-image has some limitations. For example, CSS Selectors in a host document cannot query an SVG document that is embedded as an external resource as opposed to being inlined with the host document markup.

Examples

iex> svg = SparklineSvg.new([1, 2]) |> SparklineSvg.to_svg!()
iex> SparklineSvg.as_data_uri(svg)
"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgMjAwIDUwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg=="
Link to this function

new(datapoints, options \\ [])

View Source
@spec new(datapoints(), options()) :: t()

Create a new sparkline struct with the given datapoints and options.

If neither SparklineSvg.show_dots/2, SparklineSvg.show_line/2, nor SparklineSvg.show_area/2 are called, the rendered chart will be an empty SVG document.

Examples

iex> chart = SparklineSvg.new([1, 2])
iex> SparklineSvg.to_svg!(chart)
~S'<svg width="100%" height="100%" viewBox="0 0 200 50" xmlns="http://www.w3.org/2000/svg"></svg>'

iex> chart = SparklineSvg.new([1, 2], width: 240, height: 80)
iex> SparklineSvg.to_svg!(chart)
~S'<svg width="100%" height="100%" viewBox="0 0 240 80" xmlns="http://www.w3.org/2000/svg"></svg>'
Link to this function

show_area(sparkline, options \\ [])

View Source
@spec show_area(t(), area_options()) :: t()

Take a sparkline struct and return a new sparkline struct with the given area options.

Calling this function multiple times will override the previous area options. If no options are given, the area will be shown with the default options.

Examples

iex> chart = SparklineSvg.new([1, 2]) |> SparklineSvg.show_area()
iex> SparklineSvg.to_svg!(chart)
~S'<svg width="100%" height="100%" viewBox="0 0 200 50" xmlns="http://www.w3.org/2000/svg"><path d="M2.0,48.0C31.4,41.1 168.6,8.9 198.0,2.0V50H2.0Z" fill="rgba(0, 0, 0, 0.1)" stroke="none" /></svg>'

iex> chart = SparklineSvg.new([1, 2]) |> SparklineSvg.show_area(color: "rgba(0, 255, 255, 0.2)")
iex> SparklineSvg.to_svg!(chart)
~S'<svg width="100%" height="100%" viewBox="0 0 200 50" xmlns="http://www.w3.org/2000/svg"><path d="M2.0,48.0C31.4,41.1 168.6,8.9 198.0,2.0V50H2.0Z" fill="rgba(0, 255, 255, 0.2)" stroke="none" /></svg>'
Link to this function

show_dots(sparkline, options \\ [])

View Source
@spec show_dots(t(), dots_options()) :: t()

Take a sparkline struct and return a new sparkline struct with the given dots options.

Calling this function multiple times will override the previous dots options. If no options are given, the dots will be shown with the default options.

Examples

iex> chart = SparklineSvg.new([1, 2]) |> SparklineSvg.show_dots()
iex> SparklineSvg.to_svg!(chart)
~S'<svg width="100%" height="100%" viewBox="0 0 200 50" xmlns="http://www.w3.org/2000/svg"><circle cx="2.0" cy="48.0" r="1" fill="black" /><circle cx="198.0" cy="2.0" r="1" fill="black" /></svg>'

iex> chart = SparklineSvg.new([1, 2]) |> SparklineSvg.show_dots(radius: 0.5, color: "red")
iex> SparklineSvg.to_svg!(chart)
~S'<svg width="100%" height="100%" viewBox="0 0 200 50" xmlns="http://www.w3.org/2000/svg"><circle cx="2.0" cy="48.0" r="0.5" fill="red" /><circle cx="198.0" cy="2.0" r="0.5" fill="red" /></svg>'
Link to this function

show_line(sparkline, options \\ [])

View Source
@spec show_line(t(), line_options()) :: t()

Take a sparkline struct and return a new sparkline struct with the given line options.

Calling this function multiple times will override the previous line options. If no options are given, the line will be shown with the default options.

Examples

iex> chart = SparklineSvg.new([1, 2]) |> SparklineSvg.show_line()
iex> SparklineSvg.to_svg!(chart)
~S'<svg width="100%" height="100%" viewBox="0 0 200 50" xmlns="http://www.w3.org/2000/svg"><path d="M2.0,48.0C31.4,41.1 168.6,8.9 198.0,2.0" fill="none" stroke="black" stroke-width="0.25" /></svg>'

iex> chart = SparklineSvg.new([1, 2]) |> SparklineSvg.show_line(width: 0.1, color: "green")
iex> SparklineSvg.to_svg!(chart)
~S'<svg width="100%" height="100%" viewBox="0 0 200 50" xmlns="http://www.w3.org/2000/svg"><path d="M2.0,48.0C31.4,41.1 168.6,8.9 198.0,2.0" fill="none" stroke="green" stroke-width="0.1" /></svg>'
@spec to_svg(t()) :: {:ok, String.t()} | {:error, atom()}

Return a valid SVG document from a sparkline struct.

Examples

iex> SparklineSvg.new([1, 2]) |> SparklineSvg.to_svg()
{:ok, ~S'<svg width="100%" height="100%" viewBox="0 0 200 50" xmlns="http://www.w3.org/2000/svg"></svg>'}

iex> SparklineSvg.new([1, 2], width: 10, padding: 10) |> SparklineSvg.to_svg()
{:error, :invalid_dimension}
@spec to_svg!(t()) :: String.t()

Return a valid SVG document from a sparkline struct.

Examples

iex> SparklineSvg.new([1, 2]) |> SparklineSvg.to_svg!()
~S'<svg width="100%" height="100%" viewBox="0 0 200 50" xmlns="http://www.w3.org/2000/svg"></svg>'

iex> SparklineSvg.new([1, 2], width: 10, padding: 10) |> SparklineSvg.to_svg!()
** (SparklineSvg.Error) invalid_dimension