From 1ed12b2ccd7ef1b94746508e21466707daa8d0d8 Mon Sep 17 00:00:00 2001 From: abdelaz3r Date: Tue, 6 Feb 2024 15:13:46 +0100 Subject: [PATCH] Update documentation --- lib/sparkline.ex | 194 ++++++++++++++++++++++++++++++----------------- 1 file changed, 126 insertions(+), 68 deletions(-) diff --git a/lib/sparkline.ex b/lib/sparkline.ex index 9c8d817..40287a1 100644 --- a/lib/sparkline.ex +++ b/lib/sparkline.ex @@ -1,6 +1,6 @@ defmodule Sparkline do - @moduledoc """ - `Sparkline.Line` uses a list of datapoints to return a line chart in SVG format. + @moduledoc ~S""" + `Sparkline` uses a list of datapoints to return a line chart in SVG format. ## Usage example: @@ -8,26 +8,34 @@ defmodule Sparkline do # Datapoints datapoints = [{1, 1}, {2, 2}, {3, 3}] + # General options + options = [width: 100, height: 40] + # A very simple line chart - Sparkline.Line.to_svg(datapoints) - - # A line chart with different sizes - Sparkline.Line.to_svg(datapoints, width: 240, height: 80) - - # A complete example of a line chart - options = [ - width: 100, - height: 40, - padding: 0.5, - show_dot: false, - dot_radius: 0.1, - dot_color: "rgb(255, 255, 255)", - line_color: "rgba(166, 218, 149)", - line_width: 0.05, - line_smoothing: 0.1 - ] + sparkline = Sparkline.new(datapoints, options) + + # Display what you want + line_options = [width: 0.25, color: "black"] + sparkline = Sparkline.show_line(sparkline, line_options) - Sparkline.Line.to_svg(datapoints, options) + {:ok, svg} = Sparkline.to_svg(sparkline) # or + svg = Sparkline.to_svg!(sparkline) + ``` + + ### Customization + + `Sparkline` allows you to customize the chart showing or hiding the dots, the line, and the area + under the line. + + ``` elixir + # A more complex sparkline + {:ok, svg} = + datapoints + |> Sparkline.new(width: 100, height: 40, padding: 0.5, smoothing: 0.1, placeholder: "No data") + |> Sparkline.show_dot(radius: 0.1, color: "rgb(255, 255, 255)") + |> Sparkline.show_line(width: 0.05, color: "rgba(166, 218, 149)") + |> Sparkline.show_area(color: "rgba(166, 218, 149, 0.2)") + |> Sparkline.to_svg() ``` ## Options @@ -37,17 +45,25 @@ defmodule Sparkline do - `width`: The width of the chart, defaults to `200`. - `height`: The height of the chart, defaults to `100`. - `padding`: The padding of the chart, defaults to `6`. - - `show_dot`: A boolean to decide whether to show dots or not, defaults to `true`. - - `dot_radius`: The radius of the dots, defaults to `1`. - - `dot_color`: The color of the dots, defaults to `"black"`. - - `show_line`: A boolean to decide whether to show the line or not, defaults to `true`. - - `line_width`: The width of the line, defaults to `0.25`. - - `line_color`: The color of the line, defaults to `"black"`. - - `line_smoothing`: The smoothing of the line (`0` = no smoothing, above `0.5` it becomes unreadable), + - `smoothing`: The smoothing of the line (`0` = no smoothing, above `0.5` it becomes unreadable), defaults to `0.2`. - - `show_area`: A boolean to decide whether to show the area under the line or not, defaults to `false`. - - `area_color`: The color of the area under the line, defaults to `"rgba(0, 0, 0, 0.2)"`. - - `placeholder`: A placeholder for an empty chart, defaults to `"No data"`. + - `placeholder`: A placeholder for an empty chart, defaults to `nil`. If set to `nil`, the chart + will be an empty SVG document. Alternatively, you can set it to a string to display a message + when the chart is empty. + + ### Dots options + + - `radius`: The radius of the dots, defaults to `1`. + - `color`: The color of the dots, defaults to `"black"`. + + ### Line options + + - `width`: The width of the line, defaults to `0.25`. + - `color`: The color of the line, defaults to `"black"`. + + ### Area options + + - `color`: The color of the area under the line, defaults to `"rgba(0, 0, 0, 0.2)"`. ## Datapoints @@ -59,25 +75,29 @@ defmodule Sparkline do datapoints = [{1, 1}, {2, 2}, {3, 3}] # Datapoints with DateTime - 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}] + 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} + ] # 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:00:00], 1}, {~T[00:00:00], 2}, {~T[00:00:00], 3}] + datapoints = [{~T[00:01:00], 1}, {~T[00:02:00], 2}, {~T[00:03:00], 3}] ``` """ alias Sparkline.Datapoint alias Sparkline.Draw - @typedoc "Svg string." + @typedoc "A valid SVG string." @type svg :: String.t() @typedoc """ - A datapoint can be a pair of DateTime and number, Date and number, Time and number, - or simply two numbers. + A datapoint can be a pair of DateTime and number, Date and number, Time and number, or simply two + numbers. """ @type datapoint :: {DateTime.t(), number()} @@ -86,8 +106,7 @@ defmodule Sparkline do | {number(), number()} @typedoc """ - A list of datapoints. The data types in the list correspond to those defined for - datapoint. + A list of datapoints. The data types in the list correspond to those defined for datapoint. """ @type datapoints :: list({DateTime.t(), number()}) @@ -136,10 +155,7 @@ defmodule Sparkline do area: nil | map() } - @typedoc """ - TODO. - Sparkline struct. - """ + @typedoc false @type t :: %Sparkline{ datapoints: datapoints(), options: internal_options() @@ -147,8 +163,17 @@ defmodule Sparkline do @enforce_keys [:datapoints, :options] defstruct [:datapoints, :options] - @doc """ - TODO: Add documentation + @doc ~S""" + Create a new sparkline struct with the given datapoints and options. + + ## Examples + + iex> Sparkline.new([{1, 1}, {2, 2}]) + %Sparkline{datapoints: [{1, 1}, {2, 2}]} + + iex> Sparkline.new([{1, 1}, {2, 2}], width: 240, height: 80) + %Sparkline{datapoints: [{1, 1}, {2, 2}], options: %{width: 240, height: 80}} + """ @spec new(datapoints()) :: Sparkline.t() @spec new(datapoints(), options()) :: Sparkline.t() @@ -162,8 +187,19 @@ defmodule Sparkline do %Sparkline{datapoints: datapoints, options: options} end - @doc """ - TODO: Add documentation + @doc ~S""" + 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> Sparkline.new([{1, 1}, {2, 2}]) |> Sparkline.show_dots() + %Sparkline{datapoints: [{1, 1}, {2, 2}]} + + iex> Sparkline.new([{1, 1}, {2, 2}]) |> Sparkline.show_dots(radius: 0.5, color: "red") + %Sparkline{datapoints: [{1, 1}, {2, 2}], options: %{dots: %{radius: 0.5, color: "red"}}} + """ @spec show_dots(Sparkline.t()) :: Sparkline.t() @spec show_dots(Sparkline.t(), dots_options()) :: Sparkline.t() @@ -176,8 +212,19 @@ defmodule Sparkline do %Sparkline{sparkline | options: %{sparkline.options | dots: dots_options}} end - @doc """ - TODO: Add documentation + @doc ~S""" + 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> Sparkline.new([{1, 1}, {2, 2}]) |> Sparkline.show_line() + %Sparkline{datapoints: [{1, 1}, {2, 2}]} + + iex> Sparkline.new([{1, 1}, {2, 2}]) |> Sparkline.show_line(width: 0.25, color: "black") + %Sparkline{datapoints: [{1, 1}, {2, 2}], options: %{line: %{width: 0.25, color: "black"}}} + """ @spec show_line(Sparkline.t()) :: Sparkline.t() @spec show_line(Sparkline.t(), line_options()) :: Sparkline.t() @@ -190,8 +237,19 @@ defmodule Sparkline do %Sparkline{sparkline | options: %{sparkline.options | line: line_options}} end - @doc """ - TODO: Add documentation + @doc ~S""" + 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> Sparkline.new([{1, 1}, {2, 2}]) |> Sparkline.show_area() + %Sparkline{datapoints: [{1, 1}, {2, 2}]} + + iex> Sparkline.new([{1, 1}, {2, 2}]) |> Sparkline.show_area(color: "rgba(0, 0, 0, 0.2)") + %Sparkline{datapoints: [{1, 1}, {2, 2}], options: %{area: %{color: "rgba(0, 0, 0, 0.2"}}} + """ @spec show_area(Sparkline.t()) :: Sparkline.t() @spec show_area(Sparkline.t(), area_options()) :: Sparkline.t() @@ -204,16 +262,16 @@ defmodule Sparkline do %Sparkline{sparkline | options: %{sparkline.options | area: area_options}} end - @doc """ - Return a valid SVG document representing a line chart with the given datapoints. + @doc ~S""" + Return a valid SVG document from a sparkline struct. - ## Examples + Examples: - iex> Sparkline.Line.to_svg([{1, 1}, {2, 2}, {3, 3}]) - {:ok, svg_string} + iex> Sparkline.new([{1, 1}, {2, 2}]) |> Sparkline.to_svg() + {:ok, svg} - iex> Sparkline.Line.to_svg([{1, 1}, {2, 2}, {3, 3}], width: 240, height: 80) - {:ok, svg_string} + iex> Sparkline.new([{1, 1}, {2, 2}], width: 10, padding: 10) |> Sparkline.to_svg() + {:error, :invalid_dimension} """ @spec to_svg(Sparkline.t()) :: {:ok, svg()} | {:error, atom()} @@ -238,16 +296,16 @@ defmodule Sparkline do end end - @doc """ - Return a valid SVG document representing a line chart with the given datapoints. + @doc ~S""" + Return a valid SVG document from a sparkline struct. - ## Examples + Examples: - iex> Sparkline.Line.to_svg!([{1, 1}, {2, 2}, {3, 3}]) - svg_string + iex> Sparkline.new([{1, 1}, {2, 2}]) |> Sparkline.to_svg!() + svg - iex> Sparkline.Line.to_svg!([{1, 1}, {2, 2}, {3, 3}], width: 240, height: 80) - svg_string + iex> Sparkline.new([{1, 1}, {2, 2}], width: 10, padding: 10) |> Sparkline.to_svg!() + ** (Sparkline.Error) invalid_dimension """ @spec to_svg!(Sparkline.t()) :: svg() @@ -258,13 +316,13 @@ defmodule Sparkline do end end - @doc """ - Convert a svg string into a Base64 string to be used, for example. as a background-image. + @doc ~S""" + Convert a svg string into a Base64 string to be used, for example, as a background-image. - ## Examples + Examples: - iex> Sparkline.as_data_uri(svg_string) - "data:image/svg+xml,%3Csvg..." + iex> Sparkline.new([{1, 1}, {2, 2}]) |> Sparkline.to_svg!() |> Sparkline.as_data_uri() + "data:image/svg+xml;base64,PHN2ZyB3aWR0aD..." """ @spec as_data_uri(svg()) :: String.t()