Package 'easeling'

Title: Minimal 'DrawingML' Graphics Device for 'openxlsx2'
Description: A base R graphics device that writes plots directly as 'OOXML' 'DrawingML' vector shapes (ECMA-376, <https://ecma-international.org/publications-and-standards/standards/ecma-376/>), for adding editable graphics to spreadsheets with 'openxlsx2' (via its wb_add_drawing() function). Has no dependency on 'cairo', 'FreeType', 'fontconfig', or 'xml2'; real font metrics are used when the 'systemfonts' package is available.
Authors: Jan Marvin Garbuszus [aut, cre]
Maintainer: Jan Marvin Garbuszus <[email protected]>
License: MIT + file LICENSE
Version: 0.3.1
Built: 2026-09-29 16:12:21 UTC
Source: https://github.com/JanMarvin/easeling

Help Index


Open a DrawingML graphics device for openxlsx2

Description

Draws directly to a standalone DrawingML XML file containing 'xdr:sp' shapes, suitable for 'openxlsx2::wb_add_drawing(xml = file)'. No dependency on Cairo, FreeType, fontconfig, or xml2.

Usage

easel_dev(
  file = tempfile(fileext = ".xml"),
  width = 6,
  height = 6,
  units = "in",
  pointsize = 12,
  fontname = "Calibri",
  bg = NA,
  symbolfamily = "",
  underline = FALSE,
  strikeout = FALSE,
  dims = NULL,
  wb = NULL,
  sheet = 1,
  text_voff = 0.35,
  metrics = NULL
)

Arguments

file

Path of the XML file to write. Defaults to a temp file. For a plain string instead of a file, see [easel_xml()].

width, height

Device size, in 'units'.

units

Unit for 'width' and 'height': '"in"' (default), '"cm"', '"mm"' or '"px"'. Pixels are 96 per inch, the value spreadsheet applications use. Ignored when 'dims' is given, since a cell region already fixes the size.

pointsize

Default font pointsize.

fontname

Default font typeface (matches ‘openxlsx2::wb_add_font()'’s 'name' argument), e.g. '"Calibri"', '"Arial"'. Used whenever R itself doesn't request a specific family — i.e. whenever a plot's own ‘family'/'fontfamily' is unset or is one of R’s generic aliases ('"sans"', '"serif"', '"mono"', '"symbol"', or '""'). If a plot sets an actual font name (e.g. 'par(family = "Georgia")' or 'theme_minimal(base_family = "Georgia")'), that takes priority over this default.

bg

Background colour drawn behind the plot. The default, 'NA', leaves the drawing transparent so the sheet shows through.

symbolfamily

Typeface asked for on plotmath symbols. The glyphs are written as Unicode either way, so this only matters when 'fontname' lacks them: '"Cambria Math"' is the usual choice on Windows. Empty (the default) keeps symbols in 'fontname'.

underline, strikeout

Apply underline/strikeout to all text on this device. Unlike 'fontname', these have no per-call R equivalent (base graphics has no underline/strikeout concept), so they're a device-wide setting.

dims

Optionally, a cell range such as '"A1:G15"'. If given, 'width' and 'height' are ignored and computed from the region via [easel_size()], so the plot fills that region exactly when later anchored to the same 'dims'.

wb, sheet

Passed to [easel_size()] when 'dims' is given: the 'openxlsx2' workbook (and sheet) to read actual column widths and row heights from.

text_voff

Vertical text calibration in em: text boxes are centre-anchored, and the baseline is placed 'text_voff' em below the box centre. The default ‘0.35' was calibrated against Excel’s line layout for Calibri; LibreOffice's optimum is around 0.24, so text there sits ~0.1 em low. Increase to shift rendered text up, decrease to shift it down, if your spreadsheet application's line layout places it visibly off; see 'system.file("examples", "calibrate_text.R", package = "easeling")'.

metrics

Font metrics used for text layout (string widths, vertical centring, margins). 'NULL' (default): use real metrics for 'fontname' via the 'systemfonts' package when it is installed, otherwise the built-in Calibri-like table. 'FALSE': always use the built-in table. Or a list with numeric components 'widths', 'ascents', 'descents', each of length 95 giving em fractions for the ASCII characters 32..126. Metrics only affect what R computes - rendering is always done by the spreadsheet application with the real font - but better metrics mean legend boxes, margins, and centring are sized for the text that will actually appear.

The machine writing the file need not have the font it will be opened with, and 'systemfonts' substitutes without saying so; [font_match()] reports which font was measured. To get real metrics for a font this machine lacks, install a replacement built to match it (Carlito for Calibri, Liberation Sans for Arial, Liberation Serif for Times New Roman), point 'systemfonts' at the actual file with 'systemfonts::register_font("Calibri", plain = "calibri.ttf")' before opening the device, or pass the numbers in 'metrics' yourself.

Value

The output file path, invisibly.

Examples

f <- easel_dev(width = 6, height = 4, fontname = "Georgia")
plot(1:10, (1:10)^2, type = "b")
dev.off()

Compute the device size for a spreadsheet cell region

Description

Translates a cell range like '"A1:G15"' into a device size in inches, so that a plot drawn at that size fills the region exactly when anchored to the same 'dims' — the dims-first workflow: pick the region, size the device from it, then plot. Because the device is opened at the final size, R lays out text, margins, and legends for that size; nothing needs to be rescaled afterwards (DrawingML cannot rescale text in groups).

Usage

easel_size(dims, wb = NULL, sheet = 1)

Arguments

dims

A cell range such as '"A1:G15"' (both corners inclusive).

wb

Optionally, an 'openxlsx2' workbook ('wbWorkbook') to read the actual column widths and row heights from.

sheet

Sheet index in 'wb'. Default '1'.

Details

Column widths and row heights are taken from 'wb' when given, including custom widths/heights and the sheet defaults stored in its ‘sheetFormatPr'. Without 'wb', Excel’s defaults are assumed (Calibri 11: 8.43 character column width = 64px, 15pt row height = 20px). The character-to-pixel conversion uses Excel's formula for a maximum digit width of 7px; workbooks with a different base font will be off by the ratio of their digit widths.

Value

Named numeric vector 'c(width = , height = )' in inches.

Examples

easel_size("A1:G15")

Render plotting code straight to a DrawingML string

Description

Evaluates 'code' on an in-memory easeling device and returns the resulting drawing as a single character string - no file is involved. The device is opened before and closed after 'code', also on error.

Usage

easel_xml(code, ...)

Arguments

code

Plotting code; a braced block for multiple statements. Remember that ggplot2/tmap/lattice objects only draw when printed, so wrap them in 'print()'.

...

Passed to [easel_dev()] (everything except 'file').

Value

The DrawingML as a length-one character vector, ready for 'openxlsx2::wb_add_drawing(xml = )'.

Examples

xml <- easel_xml(plot(1:10), width = 4, height = 3)

Which font is actually measured for a typeface

Description

The machine writing a drawing need not have the font the drawing will be opened with. 'systemfonts' substitutes without saying so, and the plot is then laid out with one font's widths while the drawing asks the spreadsheet application for another. Often that costs nothing, because some substitutes exist to match: Carlito for Calibri, Liberation Sans for Arial, Liberation Serif for Times New Roman. Others are unrelated fonts of quite different width. The device does not check, so call this when a drawing's layout looks wrong and you want to know which font produced it.

Usage

font_match(fontname)

Arguments

fontname

Typeface the drawing will name.

Value

A list with 'requested', 'matched' and 'substituted', or 'NULL' when 'systemfonts' is not installed.

Examples

font_match("Calibri")