Packages

A lightweight, extensible Elixir library for generating SVG images programmatically using Erlang's built-in :xmerl.

Current section

Files

Jump to
vectored lib vectored elements polyline.ex
Raw

lib/vectored/elements/polyline.ex

defmodule Vectored.Elements.Polyline do
@moduledoc """
The `<polyline>` element is an SVG basic shape that creates straight lines
connecting several points.
Unlike `<polygon>`, a `<polyline>` is typically an open shape (the last point
is not automatically connected to the first).
## Attributes
* `points` - A list of `{x, y}` coordinates.
* `path_length` - The total length of the polyline in user units.
## Examples
# `fill: "none"` matters here — an unfilled polyline is a stroke, not a shape
iex> Vectored.Elements.Polyline.new([{0, 0}, {20, 20}, {40, 0}])
...> |> Vectored.Elements.Polyline.with_fill("none")
...> |> Vectored.Elements.Polyline.with_stroke("blue")
...> |> Vectored.to_svg_string()
{:ok, ~s|<polyline fill="none" points="0,0 20,20 40,0" stroke="blue"/>|}
"""
use Vectored.Elements.Element,
attributes: [points: [], path_length: nil]
@type point :: {number(), number()}
@type t :: %__MODULE__{
points: list(point()),
path_length: number() | nil,
marker_start: String.t() | nil,
marker_mid: String.t() | nil,
marker_end: String.t() | nil
}
@doc """
Create a new polyline with an optional list of points.
"""
@spec new(list(point())) :: t()
@spec new() :: t()
def new(points \\ []) do
%__MODULE__{points: points |> List.wrap()}
end
@doc """
Append a point to the polyline.
"""
@spec append_points(t(), point()) :: t()
def append_points(%__MODULE__{points: points} = path, point) do
%{path | points: List.wrap(points) ++ [point]}
end
defimpl Vectored.Renderable do
def to_svg(%Vectored.Elements.Polyline{} = element) do
attrs = Vectored.Elements.Polyline.attributes(element)
children = Vectored.Elements.Element.render_common_children(element)
{_, attrs} =
Keyword.get_and_update(attrs, :points, fn
points ->
points_str =
Enum.map_join(points, " ", fn {x, y} -> "#{x},#{y}" end)
{points, points_str}
end)
{:polyline, attrs, children}
end
end
end