Backend-agnostic element representation for building scene graphs.
Elements represent visual primitives that can be rendered by any backend. The structure separates concerns:
type: The kind of element (:path, :rect, :circle, etc.)attrs: Geometric attributes (x, y, width, height, cx, cy, r, etc.)style: Visual styling (fill, stroke, opacity, etc.)transform: Transformation to applychildren: Child elements (for groups)content: Text content (for text elements)path: Path IR (for path elements)
Examples
iex> alias Visualize.IR.{Element, Path}
iex> path = Path.new() |> Path.move_to(0, 0) |> Path.line_to(100, 100)
iex> element = Element.path(path, %{stroke: "blue", fill: :none})
iex> element.type
:path
iex> element.style
%{stroke: "blue", fill: :none}
iex> element.path
%Visualize.IR.Path{commands: [{:M, 0, 0}, {:L, 100, 100}]}
Summary
Types
Where an element is drawn (spec/02 §2.1): only where the shape is, or only where it is not — how a stroke is kept inside or outside an edge (spec/14 §5.6).
Functions
Appends a child element.
Creates a circle element.
The element drawn only where shape is (:inside) or only where it is not
(:outside) (spec/02 §2.1). The shape's style is ignored by every backend.
Creates a clip path element.
Writes a datum's fields onto the element as the data attributes TooltipHook reads
(spec/10 §12.2, D-75).
Creates a defs element (for gradients, patterns, etc.).
Creates a desc element: the accessible description of its parent.
A drop shadow primitive of the offset and the blur radius, at 0.35 opacity.
Creates an ellipse element.
A filter (spec/02 §2.1): its id and its primitives, for an element's effect.
A Gaussian blur primitive of the radius.
Creates a group element.
Creates an image element.
Creates a line element.
Creates a linear gradient element.
Creates a new element of the specified type.
Creates a path element from a Path IR.
Creates a polygon element. Points should be a list of {x, y} tuples.
Creates a polyline element. Points should be a list of {x, y} tuples.
Prepends a child element.
The element with one attribute set: key — an atom, or a string for an attribute the
IR has no name for, such as a data- attribute — to value.
Creates a radial gradient element.
Creates a rectangle element.
Creates a root SVG element, role="img".
Sets attributes on an element, merging with existing attrs.
Sets the text content of an element.
Sets style properties on an element, merging with existing style.
Sets the transform on an element.
Creates a gradient stop element.
Creates a text element with dx/dy offsets (useful for tick labels).
Creates a text element.
Creates a title element: the accessible name of the element it is the first child of.
Adds a translation transform.
Wraps element(s) in a group with a translation transform.
One line of a :text (spec/02 §2.1): a :tspan with its content and attrs, x and dy
among them. A :text whose children are tspans and whose content is nil is a text of
several lines (spec/14 §7.1).
Types
@type clip() :: %{shape: t(), keep: :inside | :outside}
Where an element is drawn (spec/02 §2.1): only where the shape is, or only where it is not — how a stroke is kept inside or outside an edge (spec/14 §5.6).
@type element_type() ::
:path
| :rect
| :circle
| :ellipse
| :line
| :polyline
| :polygon
| :text
| :group
| :image
| :defs
| :clip_path
| :linear_gradient
| :radial_gradient
| :stop
| :filter
| :fe_drop_shadow
| :fe_gaussian_blur
| :tspan
| :root
| :title
| :desc
@type style() :: %{ optional(:fill) => String.t() | :none | :current_color, optional(:stroke) => String.t() | :none | :current_color, optional(:stroke_width) => number(), optional(:stroke_linecap) => :butt | :round | :square, optional(:stroke_linejoin) => :miter | :round | :bevel, optional(:stroke_dasharray) => String.t(), optional(:opacity) => number(), optional(:fill_opacity) => number(), optional(:stroke_opacity) => number(), optional(:font_size) => number() | String.t(), optional(:font_family) => String.t(), optional(:font_weight) => String.t() | number() | :normal | :bold, optional(:font_style) => :normal | :italic, optional(:text_anchor) => :start | :middle | :end, optional(:dominant_baseline) => atom(), optional(:class) => String.t(), optional(:line_height) => number(), optional(:blend) => atom(), optional(:effect) => :none | :shadow | :blur, optional(:effect_radius) => number() }
@type t() :: %Visualize.IR.Element{ attrs: map(), children: [t()], clip: clip() | nil, content: String.t() | nil, path: Visualize.IR.Path.t() | nil, style: style(), transform: Visualize.IR.Transform.t() | nil, type: element_type() }
Functions
Appends a child element.
Creates a circle element.
The element drawn only where shape is (:inside) or only where it is not
(:outside) (spec/02 §2.1). The shape's style is ignored by every backend.
iex> square = Visualize.IR.Element.rect(0, 0, 10, 10)
iex> Visualize.IR.Element.clip(square, square, :inside).clip.keep
:inside
Creates a clip path element.
Writes a datum's fields onto the element as the data attributes TooltipHook reads
(spec/10 §12.2, D-75).
fields is a map — written in Enum.sort/1 order — or a keyword list, in its order.
data-datum lists the field names; data-datum-<field> carries to_string/1 of each
value, with every _ in the name as -, and a nil value writes no attribute. The keys
are strings, so no atom is created from a row's names.
Examples
iex> Visualize.IR.Element.circle(1, 2, 3)
...> |> Visualize.IR.Element.datum(at: ~U[2024-01-01 00:00:00Z], big_v: 4, gap: nil)
...> |> Map.fetch!(:attrs)
%{
"data-datum" => "at big_v gap",
"data-datum-at" => "2024-01-01 00:00:00Z",
"data-datum-big-v" => "4",
cx: 1,
cy: 2,
r: 3
}
Creates a defs element (for gradients, patterns, etc.).
Creates a desc element: the accessible description of its parent.
A drop shadow primitive of the offset and the blur radius, at 0.35 opacity.
Creates an ellipse element.
A filter (spec/02 §2.1): its id and its primitives, for an element's effect.
A Gaussian blur primitive of the radius.
Creates a group element.
Creates an image element.
Creates a line element.
Creates a linear gradient element.
@spec new(element_type(), keyword()) :: t()
Creates a new element of the specified type.
@spec path(Visualize.IR.Path.t(), style()) :: t()
Creates a path element from a Path IR.
Creates a polygon element. Points should be a list of {x, y} tuples.
Creates a polyline element. Points should be a list of {x, y} tuples.
Prepends a child element.
The element with one attribute set: key — an atom, or a string for an attribute the
IR has no name for, such as a data- attribute — to value.
iex> Visualize.IR.Element.group([]) |> Visualize.IR.Element.put_attr("data-node", "marks[0]") |> Map.fetch!(:attrs)
%{"data-node" => "marks[0]"}
Creates a radial gradient element.
Creates a rectangle element.
Creates a root SVG element, role="img".
Options
:view_box- theviewBox(default"0 0 <width> <height>"):children- the child elements (default[]):preserve_aspect_ratio- thepreserveAspectRatioattribute; absent by default:responsive- when true,preserveAspectRatio="xMidYMid meet"(unless given) andstyle="width:100%;height:auto", so the<svg>fills its container's width at the drawing's aspect ratio whilewidthandheightstay its intrinsic size (D-54):title,:description- the accessible name and description (D-56): a<title>and a<desc>become the first children, each with an id, andaria-labelledbynames them:id- the root's id and the prefix of the two child ids (<id>-title,<id>-desc); defaults tovis-and a hash of the two texts, and is only set when a title or description is given
Sets attributes on an element, merging with existing attrs.
Sets the text content of an element.
Sets style properties on an element, merging with existing style.
@spec set_transform(t(), Visualize.IR.Transform.t()) :: t()
Sets the transform on an element.
Creates a gradient stop element.
Creates a text element with dx/dy offsets (useful for tick labels).
Creates a text element.
Creates a title element: the accessible name of the element it is the first child of.
Adds a translation transform.
Wraps element(s) in a group with a translation transform.
One line of a :text (spec/02 §2.1): a :tspan with its content and attrs, x and dy
among them. A :text whose children are tspans and whose content is nil is a text of
several lines (spec/14 §7.1).