scale() is now set_scale() (#36). glyph's scale() had the same name
as base::scale(), so library(glyph) masked the base function. It
printed "The following object is masked from 'package:base': scale", and
base uses such as scale(df$x) failed afterwards with an error about
glyph specs. set_scale() takes the same arguments. To update your code,
change each scale() step in a glyph pipeline to set_scale():r
# Before
glyph(mtcars, x = wt, y = mpg) |> mark_point() |> scale("y", zero = TRUE)
# After
glyph(mtcars, x = wt, y = mpg) |> mark_point() |> set_scale("y", zero = TRUE)
Base uses of scale() work again and need no change. scale_color(),
scale_log() and scale_time() keep their names. library(glyph) no
longer masks any function.
The compiled JSON (compile()$json and export(..., "plot.json")) has a
new data layout, marked by "$schema": "glyph/v0.2" (#8). Data is
{"columns": {...}, "n": rows}, and a mark that draws the plot's data has
{"from": "plot", "fields": [...], "rows": [...]}, where rows is null
or lists the 0-based rows it keeps after dropping missing values.
Boxplot, violin, histogram and polygon marks send {"values": [...]}, one
record per box, violin, bin or shape. Code that reads JSON written by
glyph 0.1 needs updating.
compile(engine = ...) accepts only "auto" and "html", and gives an
error for anything else. It used to accept "canvas" and "webgl" and
pick one by data size, but no such renderer has ever existed, so the
choice did nothing. The D3 and SVG renderer is the only one.
* Printing a compose() layout at the console now draws it, as printing a
single plot does (#13). The text description it used to print comes from
the new summary.glyph_layout().
glyphOutput() and renderGlyph() place
and draw a plot, and renderGlyph() takes a plot, a compose() layout or
a widget from render(). What the user selects reaches the server as
input$<outputId>_selected: the row numbers of the data frame given to
glyph(), so data[input$plot_selected, ] gives the selected rows. The
numbers stay right when rows with missing values are dropped and when a
mapping is computed, and selecting a box, bin or polygon selects the rows
it summarises. The value is sent when a brush ends, on a click select and
on a legend click, and clearing a selection sends NULL. A facet() grid
gives one vector, and a compose() layout gives a list with one entry per
panel, named after the panels when compose() is given names. shiny is
suggested, not required. A new article, "Using glyph in Shiny"
(vignette("shiny", package = "glyph")), is built around an example app
in inst/examples/shiny-brush.mark_boxplot(), mark_violin(),
mark_sina() and mark_histogram(). Their statistics are computed in R
when the plot is compiled, with stats::quantile(), stats::density()
and hist()-style bins, after computed mappings are evaluated and rows
with missing values are dropped. They work with facet() (summaries are
computed per panel), compose(), theme tokens, tooltips (which show the
statistics), hover, click and brushing. Each box, violin or bin knows which
rows it summarises, so brushing points or linked panels highlights the
boxes and bins that contain the selected rows, and brushing a box selects
its rows.mark_polygon() draws closed shapes from x/y vertices, one per value
of group (#7). Vertices are joined in row order, color fills each
shape, style sets the fill, outline colour, outline width and opacity,
and radius rounds the corners. Each polygon is one element: it gets one
tooltip, and brushing or clicking it selects all of its rows, including
in linked panels. It works with facet(), compose(), zoom, theme tokens,
computed mappings and NA dropping.render() (#13). glyph
registers knit_print() methods for glyph_spec and glyph_layout;
knitr stays a suggested package. render() is still there for setting
the width and height.compile() takes 0.1s instead of 65s, the
widget is ready for the Viewer in 0.4s, and the file is 5 MB instead of
14 MB. Plots look and behave as before.compose(linked_selections = TRUE). Pressing Escape clears brush
selections too, unless you are typing in a text field. Plots with a brush
but no zoom now get a controls bar for the button. When the controls don't
fit the plot's width, as in small facet panels, they show just their
symbols, with the full label in their tooltip.vignette("custom-marks")), walks
through adding a mark type end to end with a worked example (#9). It
covers the R function and add_mark(), how mappings are resolved when
the plot is compiled, how data reaches the browser, the drawing code in
glyph.js, axes, tooltips, hover, brushing, fitting the container, tests,
and marks that summarise data. It also says plainly that adding a mark
means editing glyph's source, and what would need to change for other
packages to add marks.ARCHITECTURE.md and the
Getting Started vignette in plainer language (#4). Removed the
comparisons with ggplot2 from the documentation, including the comparison
tables in the README and the "glyph vs ggplot2" vignette. The package
Title and Description now describe what glyph does (#5). The README and
the glyph-package help page have an "Acknowledgements" section crediting
the prior art glyph's design draws on.R CMD check on Windows, macOS and
Linux for every pull request (#31).set_scale() is used as given, including on the shared
axes of facet() and compose(). Point and line marks are unchanged.facet() grids, which also overflowed
narrow containers, and plots in R Markdown documents ran past their 400px
box into the text below. Plots and facet grids are now drawn at the size
of the container they are in, and are redrawn when it is resized.compose() with named arguments, such as compose(a = p1, b = p2), now
draws (#34). The panels were sent as an object keyed by name instead of a
list, and the widget showed a render error.export() to .html no longer fails on machines without pandoc (#3).
Instead of a low-level pandoc error, it now writes the HTML with its
JavaScript in a <name>_files folder alongside, and says so, including how
to get a single self-contained file (install pandoc, or run inside
RStudio). The pandoc requirement is now documented in ?export.interact(zoom = TRUE) now zooms plots that
have no point mark.factor(cyl)) instead of its internal column name, and tooltip templates
can refer to fields whose names contain dots, such as {.median} (#6).x = log(wt) or
color = factor(cyl), are now evaluated when the plot is compiled. They
used to be dropped without a message. The expression is used as the
default axis or legend label.x, y, x2,
y2, y_min, y_max) are now dropped from that mark when the plot is
compiled, with a warning that says how many rows were removed and for
which aesthetics.facet(rows =, cols =) now accepts a computed expression, such as
facet(cols = factor(cyl)), evaluated the same way as an aesthetic
mapping. The expression text used to be taken as a column name that
didn't exist, so faceting on anything but a plain column gave a single,
unlabelled panel.facet() with a computed mapping
or with missing values behaves the same as an unfaceted plot.?glyph no longer claims that
lists, URLs or Arrow tables are accepted as data, ?facet no longer says
panels get independent scales by default, and ?marks and
?interactivity drop features that don't exist. The description,
documentation, README and ARCHITECTURE.md no longer claim WebGL or
canvas rendering or standalone SVG export. A canvas renderer is planned
(#20).?mark_text now describes what smart_repel = TRUE does: it nudges
overlapping label boxes apart, pair by pair, over several passes. It
credits ggrepel as the inspiration.summary.glyph_spec and print.glyph_layout help topics were left
out because they had no title. They are back.Authors@R and inst/COPYRIGHTS as the
author of the bundled D3.js library (ISC license), as CRAN policy asks
for bundled JavaScript.aes() required).mark_point(), mark_line(), mark_bar(), mark_area(),
mark_text(), mark_rule(), mark_ribbon(), mark_link().interact(): tooltips, zoom, brush selection,
hover effects, cross-filtering, and named selections.animate(): entrance transitions and keyframe
animation through data states.scale() with convenience wrappers scale_color(),
scale_log(), scale_time().theme_tokens() with five built-in presets:
light, dark, minimal, publication, presentation.compose(), marginals(), inset(),
and facet().compile(), rendering to interactive HTML
widgets via D3.js.export() and Vega-Lite interoperability via
to_vegalite().Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.