| 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 <jan.garbuszus@ruhr-uni-bochum.de> |
| License: | MIT + file LICENSE |
| Version: | 0.3.1 |
| Built: | 2026-09-29 16:12:21 UTC |
| Source: | https://github.com/JanMarvin/easeling |
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.
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 )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 )
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. |
The output file path, invisibly.
f <- easel_dev(width = 6, height = 4, fontname = "Georgia") plot(1:10, (1:10)^2, type = "b") dev.off()f <- easel_dev(width = 6, height = 4, fontname = "Georgia") plot(1:10, (1:10)^2, type = "b") dev.off()
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).
easel_size(dims, wb = NULL, sheet = 1)easel_size(dims, wb = NULL, sheet = 1)
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'. |
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.
Named numeric vector 'c(width = , height = )' in inches.
easel_size("A1:G15")easel_size("A1:G15")
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.
easel_xml(code, ...)easel_xml(code, ...)
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'). |
The DrawingML as a length-one character vector, ready for 'openxlsx2::wb_add_drawing(xml = )'.
xml <- easel_xml(plot(1:10), width = 4, height = 3)xml <- easel_xml(plot(1:10), width = 4, height = 3)
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.
font_match(fontname)font_match(fontname)
fontname |
Typeface the drawing will name. |
A list with 'requested', 'matched' and 'substituted', or 'NULL' when 'systemfonts' is not installed.
font_match("Calibri")font_match("Calibri")