blob: b22e7a9f79c8532917a35ac39fce127c192c32f1 [file] [log] [blame]
Changes from grid_3.5.* to grid_3.6.0:
-------------------------------------
1. New functions deviceLoc() and deviceDim().
2. Improve handling of graphics devices in grid.grabExpr().
Should now work when multiple graphics devices already open
(e.g., within 'knitr' document).
3. Fix bug in grid.layout() when viewport has negative width/height
(e.g., due to being sized in "native" units within viewport
with flipped scales).
Thanks to report by Silas Dean.
4. Add 'wrap.grob' argument to grid.grab() and grid.grabExpr()
to allow wrapping of grobs as well as viewports (if both
'wrap' and 'wrap.grob' are TRUE.
Also, no longer check for duplicate grob names at top-level
if 'wrap' is TRUE.
Also, do not start new page if 'wrap' is TRUE.
Thanks to report from John Bullock.
5. Exported makeContent.default() (so that
external packages can do more stuff with grobs)
6. New 'pathId' and 'pathId.lengths' arguments for grid.path()
to allow multiple paths to be drawn at once.
Contributed by Thomas Lin Pedersen.
7. New grobCoords() and grobPoints() functions to calculate points
along the perimeter (or length) of a grob.
8. Internal changes to graphical parameter setting to speed things
up a bit.
Contributed by Thomas Lin Pedersen.
Changes from grid_3.4.* to grid_3.5.0:
-------------------------------------
1. Fix for current.vpTree() so that it puts you back in the right
place in the viewport tree if there are nested viewports with
the same name (e.g., pushViewport(vp, vp)).
Reported by Prem Thomas.
2. Added 'device' (and 'width' and 'height') arguments to grid.grabExpr()
Suggestion from Claus Wilke.
Changes from grid_3.3.* to grid_3.4.0:
-------------------------------------
1. Added format() method for units, so, for example, the number of
digits printed for numeric values can be controlled.
grid.show.layout() now uses format() for annotating layout
widths and heights.
2. More robust handling of NA values in graphical parameter settings
that affect text. NA values for fontsize, lineheight, cex, and
fontfamily are ignored, i.e., inherited from parent drawing context.
A mixture of NA and non-NA generates an error.
3. Improved support for calcStringMetric() function (and
stringAscent() and stringDescent() and grobAscent() and
grobDescent()) so that text encoding is now handled.
Reported by Hakon Malmedal and Hadley Wickham.
Changes from grid_3.2.* to grid_3.3.0:
-------------------------------------
1. Added "pseudonym" units to check made in absolute.size() so that,
for example, absolute.size(unit(1, "in")) works properly
(reported by Baptiste Auguie).
2. Registered absolute.units() methods in NAMESPACE, so that, for
example, a call to absolute.size(unit(1,"npc") + unit(2,"mm"))
works outside of 'grid' (reported by Baptiste Auguie).
3. Refactored grid.draw() so that grid.draw(NULL) now works
(by doing nothing). Reported by Hadley Wickham.
4. Modified grid.ls() so that it returns nothing if there are no
active devices (rather than opening a new device).
5. Modified grid.grep() so that it returns an empty list (rather than
throwing an error) when the 'grid' display list is empty.
6. Added subassignment methods for unit objects
(e.g., x <- unit(1:3, "cm"); x[2] <- unit(.5, "npc"))
Thanks to Baptiste Auguie for code suggestions.
Changes from grid_3.1.* to grid_3.2.0:
-------------------------------------
1. Fixed evaluation of "pure null" units (by making evaluation recursive).
Previously, for example, a unit list with a unit list as its first
component would evaluate to NA. This typically only affects layouts
in grid.
Problem reported by Baptiste Auguie.
2. Fixed problem in validDetails.beziergrob(), which used to fail if
you tried to specify 'id.lengths'
3. Fixed bug in downViewport() when descending more than one
viewport. It was possible for this to end up with the wrong
clipping region (because if you ended up in a viewport that
inherited its clipping region from a parent, that clipping region
was not enforced).
Changes from grid_3.0.* to grid_3.1.0:
-------------------------------------
1. New current.rotation() function.
2. vpPath() and gPath() now automatically expand any embedded path
separators in their input.
3. New functions depth(), for determining the depth of a viewport
hierarchy or path, and explode(), for expanding a path into
its components.
4. New function grid.grep()
(based on ideas and code from Simon Potter).
5. The grid.force() function now accepts an explicit grob to (draw
and) force or a gPath to force a specific already-drawn grob.
Ditto the grid.revert() function.
6. New current.parent() function to return parent of current viewport.
7. New resolveRasterSize() function.
8. Made 'vp' argument of current.viewport() defunct.
9. Deprecated functions made defunct:
grid.grob, grid.arrows, arrowsGrob, grid.convert, grid.convertX,
grid.convertY, grid.convertWidth, grid.convertHeight,
grid.collection, push.viewport, pop.viewport, viewport.transform,
draw.details, convertNative.
10. Down viewports are now recorded on the display list as full-depth
strict vpPaths even when downViewport() is called with non-strict
vpPath (which can produce a down viewport of greater depth than
the depth of the vpPath).
11. Exported generic forceGrob().
12. Bug fix for recording viewport pushes on the graphics engine display
list (reported by the friendly folks from RStudio).
The bug could be tickled by copying a grid scene from one graphics
device to another and then attempting to navigate within
viewports on the original graphics device.
13. Better defenses against division-by-zero in unit resolution/conversion
(see ./DivByZero.txt).
Changes from grid_3.0.0 to grid_3.0.1:
-------------------------------------
1. Added str() method for "unit.arithmetic"
Reported by Andreas Leha.
Changes from grid_2.15.0 to grid_3.0.0:
--------------------------------------
1. Bug fix for showViewport() when the viewport is a
"vpStack" and one of the components of the stack
is NOT just a simple viewport (e.g., when one of
the components of the "vpStack" is a "vpStack").
2. Bug fix for grid.ls(viewports = TRUE) when listing a
"vpStack" and one of the components of the stack
is NOT just a simple viewport (e.g., when one of
the components of the "vpStack" is a "vpStack").
3. Added support for "vpPaths" within a "vpStack",
"vpList", or "vpTree" (i.e., mixing of viewports
and "vpPaths").
4. New functions grid.reorder() and reorderGrob() to
modify the order in which the children of a gTree
are drawn.
5. Bug fix for grid.ls() to report children of a gTree
in the correct order.
6. New makeContext() and makeContent() "hook" functions
to allow alternative method for creating custom grobs.
7. Standard behaviour for grobs is now to use upViewport()
rather than popViewport() on the 'vp' slot.
8. New grid.force() function to provide access to grobs
that are generated only at drawing time (for grobs that
use the new makeContent() hook).
9. New grid.revert() function to revert the effect of
grid.force().
10. Implementation of "xaxis", "yaxis", "frame", "cellGrob",
"roundrect", "beziergrob", "curve", and "functiongrob"
changed to use makeContext() and makeContent() hooks.
11. New grid.delay() and delayGrob() functions; analogues
of grid.record() and recordGrob() that are implemented
via makeContent() hooks.
Changes from grid_2.14.0 to grid_2.15.0:
---------------------------------------
1. Added calcStringMetric() function.
2. Added "strascent" and "strdescent" units, plus
stringAscent() and stringDescent() convenience functions.
3. Added "grobascent" and "grobdescent" units, plus
grobAscent() and grobDescent() convenience functions.
The "ascent" of a grob is equivalent to its height by default,
but ascentDetails() methods can be written
(e.g., text grobs are different).
The "descent" of a grob is zero by default,
but descentDetails() methods can be written
(e.g., text grobs are different).
4. Fix for xsplinePoints() so that it copes with xspline grob
with non-NULL 'id' AND so that it takes the 'vp' and 'gp'
settings into account.
5. Added grid.bezier() function to draw Bezier curve
(using an X-spline approximation).
Also added bezierPoints() function.
6. Added grid.DLapply() function.
Changes from grid_2.12.0 to grid_2.13.0:
---------------------------------------
1. Added grid.function() for drawing lines to represent functions.
2. Fixed bug in calculation of x, y, width, and height of segments
grobs.
3. Fixed bug in grid.grab(wrap = TRUE) when the scene includes
downViewport()s.
4. Added showGrob() function.
Changes from grid_2.11.0 to grid_2.12.0:
---------------------------------------
1. Neither width nor height need to be specified in
grid.raster(). The image aspect ratio will be used
to calculate an appropriate image size for the
current viewport.
2. Added [x|y|width|height]Details() methods for "rastergrob"s
3. "roundrect" grobs now obey their 'just' setting
(bug reported by Beau Benjamin Bruce)
4. Added grid.path() for rendering paths with holes.
Changes from grid_2.10.0 to grid_2.11.0:
---------------------------------------
1. Added xsplinePoints() function to return the (x, y)
locations that an Xspline would be drawn through.
Useful for, e.g., clipping an Xspline against a
boundary.
2. Added grid.raster() function for rendering raster images.
3. Added grid.cap() function for capturing output on
current graphics device as a raster image.
4. Fixed PROTECT() bug in grid.rect() PR#14199
Thanks to Andrew Runnalls for the bug report.
5. Fixed multiple problems in rep.unit() and unit subsetting.
Motivated by PR#14170. Thanks to Bert Gunter.
Changes from grid_2.9.0 to grid_2.10.0:
--------------------------------------
1. Added showViewport() function for displaying viewport trees
graphically.
2. Fixed bug in unit() indexing; negative integer indices now work.
3. Modified behaviour of editGrob() and addGrob() so that they
return the original grob if the specified gPath does not exist,
and issue a warning (if new argument 'warn' is TRUE).
Changes from grid_2.8.0 to grid_2.9.0:
-------------------------------------
1. Copied grid.roundRect() from 'RGraphics' package into 'grid'.
Renamed to grid.roundrect() and also used roundrectGrob()
rather than roundRect(), partly for more consistent naming,
partly to avoid namespace collision until original functions
get removed from 'RGraphics' package.
2. Fixed bug in grid.curve() when curve is horizontal or vertical
straight line.
3. Exposed is.grob() and valid.just() via the NAMESPACE.
4. Fixed bug in downViewport(), which meant that unsuccessful
downViewport()s were still being recorded on the graphics
engine display list. This could cause interesting results
when a window is resized (i.e., when the display list is
replayed).
Bug reported by Felix Andrews.
5. Added some pseudonyms for come units. For example, it is now
possible to specify just "in" instead of "inches".
Changes from grid_2.7.0 to grid_2.8.0:
-------------------------------------
1. Added grid.null() and nullGrob(); grob that is guaranteed
to have zero-width, zero-height, and draw nothing.
Useful as zero-size placeholder AND as invisible reference
point for other grobs to draw relative to.
2. Fixed bug in listing, via grid.ls(), of frame grobs. If the frame
had a vpPath in its 'vp' component, you got an error from vpStack().
Problem reported by Hadley Wickham.
3. Fixed a bug in grid.ls() when attempting to list the display list
following the removal of a grob (i.e., so that there were NULLs
in the display list).
Problem reported by Felix Andrews.
Changes from grid_2.6.0 to grid_2.7.0:
-------------------------------------
1. Grid will no longer complain about clipping to a rotated
viewport if the rotation is a multiple of 90 degrees.
Prompted by report from Gustaf Rydevik.
2. Open Xsplines must have zero shape for first and last
control point, but this was not being enforced correctly
for the case where there were multiple Xsplines in a
single grid.xspline() call (i.e., with use of 'id' or
'id.length'). The problem can be seen with this code
(most curves do not connect to the first control point
[there are also subtle errors in the curve shapes]):
grid.newpage()
pushViewport(viewport(w=.5, h=.5))
grid.xspline(x=outer(c(0, .5, 1, .5), 5:1/5),
s=1,
y=outer(c(.5, 1, .5, 0), 5:1/5),
id.lengths=rep(4, 5),
gp=gpar(col=1:5, lwd=3))
grid.rect()
3. Frame grobs have been improved so that all of the viewports
that are generated during the drawing of a frame (and its
cells) are left on the display list (previously, they were
popped).
This has implications particularly for ggplot[2] because
it means that it is now possible to downViewport() to
viewports created during the drawing of a ggplot[2] plot
to, for example, add further annotations to the plot.
4. Small fixes to grid.ls():
- viewports pushed by cellGrobs within frames are now
shown by grid.ls()
- fixed warning (bug really) when display list contains
only one grob (and padPrefix() is called).
Changes from grid_2.5.0 to grid_2.6.0:
-------------------------------------
1. Added grid.gedit() as convenience wrapper for grid.edit()
based on usage patterns of Hadley Wickham when working with
'ggplot' package.
Ditto, grid.gget() and grid.gremove().
2. Improved implementation of 'id' and 'id.lengths' arguments
for drawing multiple polygons/polylines/xsplines to gain
order 2 speed improvement.
Problem independently reported by Luke Tierney, Deepayan Sarkar and
Vilmos Prokaj.
3. Bug fixes for grid.remove(), especially for grep=TRUE and global=TRUE
(i.e., removing all grobs from DL where the name matches a pattern).
Also some fixes to grid.remove() error messages when no match found.
Bug reports from Hadley Wickham.
4. New function grid.ls() for listing grob trees and viewport trees
(including both grob trees and viewport trees interlaced).
Useful for exploring current grob/viewport tree, explaining
grob/viewport trees, and programming on or debugging
grob/viewport trees.
Changes from grid_2.4.0 to grid_2.5.0:
-------------------------------------
1. Added 'open' argument to grid.curve(). This allows, for example,
filling the segment of a circle.
2. Fixed bug in arrow() function: segfault produced if either
'ends' or 'type' argument are given as NULL. Thanks to
Sebastien Luque for the report.
Changes from grid_2.3.0 to grid_2.4.0:
-------------------------------------
1. Bug fix for colour used when drawing a rectangle in a
rotated viewport (reported by Olaf Burger).
2. Removed 'units.per.obs' argument from grid.lines() and
grid.segments()
(This is a bug fix; should have been removed long ago).
3. Added extra check on 'data' argument of unit(), which means
that if you supply a non-NULL value where the 'unit' is
not "str[width|height]" or "grob[x|y|width|height]", you
get an error. This may impact on existing code.
4. Radii in grid.circle() are now silently converted to their
absolute value (negative values used to trigger an error).
5. New function grobName() for generating unique (within-session)
grob names (based on class of grob).
Also, modified default naming of grobs to be based on class
of grob. This should not impact on existing code because
noone should be depending on the default names generated by grid.
Changes from grid_2.2.0 to grid_2.3.0:
-------------------------------------
1. Bug fix for stringWidth() and stringHeight() with mathematical
annotation.
These used to always convert the argument to "character".
Now they let language objects (e.g., expressions) pass through.
2. New grid.xspline() function to draw X-splines (a general curve
approximated or interpolated relative to control points).
3. New 'arrow' argument to grid.line.to(), grid.lines(), and
grid.segments(). This provides a new way to specify arrow
heads on either end of a line.
grid.arrows() has been deprecated.
NOTE: that the new 'arrow' arguments have been added BEFORE
the name, gp and vp arguments so existing code that specifies
any of these arguments *by position* (not by name) will fail.
4. Added "[" (subset) methods for "gpar" objects.
5. New grobX() and grobY() functions for producing units
describing a location on the boundary of a grob.
6. Units produced by grobX() and grobY() make use of new
xDetails() and yDetails() generic functions to calculate the
boundary of a grob. Methods for these functions are provided
for all grid graphical primitives.
7. Bug fix for grid.polygon() when 'x' is not just a simple unit
(e.g., it is unit arithmetic); 'index' was being calculated
incorrectly so not all of polygon would be drawn or, if
'id' or 'id.length' were used, only a single polygon would
be drawn (with unexpected shape).
8. New grid.curve() primitive for drawing a curve between two
locations.
Together with new grobX() and grobY() provides support for
drawing simple node-and-edge graphs and flow diagrams.
9. New grid.clip() primitive for setting the clipping region
(more accurately, the clipping rectangle). Has effect until
the next grid.clip() or when the current viewport is popped.
10. New dim.layout() method for layout objects. Allows easy
access to dimensions of layout via nrow() and ncol().
11. unit.rep() deprecated in favour of unit method(s) for rep() function.
12. unit.length() deprecated in favour of unit method(s) for length() function.
13. New grid.polyline() primitive. Just like grid.lines() except has
'id' and 'id.lengths' arguments.
These work like the corresponding arguments in grid.polygon() and
grid.xspline(), allowing multiple polylines to be drawn from a
single grid.polyline() call.
14. Fixed drawing of top-level gList objects so that they
(actually the grobs in the gList) are recorded on the
grid display list.
Allowed a gList to be component of a gList
(the gList constructor merges sub-gList into resulting gList).
Added subset method for gList objects
(so that result is still a gList).
15. Bug fix for grid.rect() and grid.circle() with gpar(lty="blank").
(problem was actually in the graphics engine).
Reported by John Braun (private correspondence).
Changes from grid_2.1.0 to grid_2.2.0:
-------------------------------------
1. current.vpPath() now exported.
2. Grid now uses the 'fg' and 'bg' settings (if any) for
graphics devices to set the initial graphical parameter
settings of the top-level viewport (i.e., the 'gp' arg
of viewport[ROOT]).
3. Fixed bug in evaluation of grobWidth(polygonGrob()).
The C function L_locnBounds was not exported AND
the widthDetails.polygon method was not exposed properly
via the NAMESPACE.
Reported in private correspondence by Deepayan Sarkar.
Also corrected export of heightDetails, validDetails, and
widthDetails for arrows, circle, polygon, points, rect, and
segments primitives.
Changes from grid_2.0.1 to grid_2.1.0:
------------------------------------
1. preDrawDetails(), drawDetails(), and postDrawDetails()
methods are now recorded on the graphics engine
display list. This means that calculations within these
methods are now run when a device is resized or
when output is copied from one device to another. A simple
example (the rectangle remains 1inch wide when resizing the
device -- it does not in previous versions) ...
testgrob <- grob(cl="test")
drawDetails.test <- function(x, recording) {
w <- convertWidth(unit(1, "inches"), "npc")
grid.rect(width=w)
}
grid.draw(testgrob)
2. Fixed bug in grid.text() when "rot" argument has length 0.
(privately reported by Emmanuel Paradis)
3. New getNames() function to return just the names of all top-level
grobs on the display list.
4. Recording on the grid display list is turned off within
preDrawDetails(), drawDetails(), and postDrawDetails() methods.
This means that you do not need to worry about specifying
recording=FALSE within these methods.
5. Grid should recover better from errors or user-interrupts
during drawing (i.e., not leave you in a strange viewport
or with strange graphical parameter settings).
6. New function grid.refresh() to redraw the grid display list.
7. New function grid.record() to capture calculations
with grid graphics output. For example ...
grid.record({
w <- convertWidth(unit(1, "inches"), "npc")
grid.rect(width=w)
},
list())
8. grobWidth and grobHeight ("grobwidth" and "grobheight" units)
for primitives (text, rects, etc, ...) are now
calculated based on a bounding box for the relevant grob.
These used to be calculated assuming a grob was scalar
rather than vector. For example, the following now behaves
much more sensibly ...
txt <- textGrob(c("This is a repeat", "This is a repeat"),
y=1:2/3, rot=45)
grid.draw(txt)
grid.rect(width=grobWidth(txt), height=grobHeight(txt))
NOTE: this has changed the calculation of the size of a scalar
rect (or circle or lines) so that, for example, something like ...
grid.pack(frame, rectGrob())
... needs to become ...
grid.pack(frame, rectGrob(),
width=unit(1, "null"), height=unit(1, "null"))
... if you just want a rectangle that fills the space available.
9. New arguments "warn" and "wrap" for function grid.grab()
If warn>0 will warn if know (or, if warn>1, if even suspect)
that the grab has not faithfully captured the output.
If wrap=TRUE, will capture output by wrapping all non-grobs
on the display list in grobs. Resulting gTree is less
elegant and harder to work with, but should always faithfully
capture output.
10. New function grid.grabExpr() which captures the output from
an expression (i.e., not from the current scene) without
doing any drawing (i.e., no impact on the current scene).
11. upViewport() now (invisibly) returns the path that it goes up
(suggested by Ross Ihaka).
This makes it possible to do things like ...
upPath <- upViewport(n)
...
downViewport(upPath)
... (i.e., navigate up and then back down to where you came from).
12. The "gamma" gpar has been deprecated (this is a device property
not a property of graphical objects; suggested by Ross Ihaka).
13. New "lex" gpar; a line width multiplier.
The final line width is calculated as ...
gpar("lex")*gpar("lwd")
... and the multiplier is cumulative (like cex) ...
grid.rect(height=0.5, width=0.5,
gp=gpar(lwd=16)) # lex = 1
pushViewport(viewport(gp=gpar(lex=0.5)))
grid.rect(height=0.5, width=0.5,
gp=gpar(lwd=16, col="red")) # lex = 0.5
pushViewport(viewport(gp=gpar(lex=0.5)))
grid.rect(height=0.5, width=0.5,
gp=gpar(lwd=16, col="green")) # lex = 0.25!
This (along with cex) provides support for "zooming" a grid scene.
14. grid.text() now handles any language object as mathematical
annotation (instead of just expressions). For example ...
grid.text(call("sin", pi))
15. plotViewport() has default value for "margins" argument (that match
the default value for par(mar)).
16. The "extension" argument to dataViewport() can now be vector,
in which case the first value is used to extend the xscale and
the second value is used to extend the y scale.
(suggested by Ross Ihaka).
17. All "just" arguments (for viewports, layouts, rectangles, text)
can now be numeric values (typically between 0 [left] and 1 [right])
as well as character values ("left", "right", ...).
For rectangles and text, there are additional "hjust" and "vjust"
arguments which allow numeric vectors of justification in
each direction (e.g., so that several pieces of text can have
different justifications). If these are specified, they
override the "just" argument.
(suggested by Ross Ihaka)
18. New "edits" argument for grid.xaxis() and grid.yaxis() to
allow specification of on-the-fly edits to axis children
(when at == NULL, so children are generated on-the-fly).
19. applyEdit(x, edit) returns x if target of edit (i.e., child
specified by a gPath) cannot be found.
20. Fix for calculation of length of max/min/sum unit. Length is
now (correctly) reported as 1 (was reported as length of first arg).
21. Viewport names can now be any string (they used to have to be a
valid R symbol).
The documentation now says that grob names can be any string
(they always could be, but the documentation said they had to
be a valid R symbol)
22. The "label" argument for grid.xaxis() and grid.yaxis() can now
also be a language object or string vector, in which case it
specifies custom labels for the tick marks.
Changes from grid_2.0.0 to grid_2.0.1:
------------------------------------
1. Fixed bug in grid.newpage(); it was not starting new page
on first grid call if there was already traditional graphics
output on the device (i.e., the device was "dirty" but not
"grid dirty").
2. Fixed bug in grid.grab() when no viewports have been pushed.
Changes from grid_1.9.0 to grid_2.0.0:
------------------------------------
1. Calculation of number of circles to draw in circleGrob now
looks at length of y and r as well as length of x.
2. Calculation of number of rectangles to draw in rectGrob now
looks at length of y, w, and h as well as length of x.
3. All primitives (rectangles, lines, text, ...) now handle
non-finite values (NA, Inf, -Inf, NaN) for locations and
sizes.
Non-finite values for locations, sizes, and scales of
viewports result in error messages.
There is a new vignette("nonfinite") which describes this
new behaviour.
4. Fixed (unreported) bug in drawing circles. Now checks that
radius is non-negative.
5. downViewport() now reports the depth it went down to find a
viewport. Handy for "going back" to where you started, e.g., ...
depth <- downViewport("vpname")
<draw stuff>
upViewport(depth)
6. The "alpha" gpar() is now combined with the alpha channel of
colours when creating a gcontext as follows:
finalAlpha = gpar("alpha")*(R_ALPHA(col)/255)
This means that gpar(alpha=) settings now affect internal
colours so grid alpha transparency settings now are sent to
graphics devices.
The alpha setting is also cumulative. For example, ...
grid.rect(width=0.5, height=0.5,
gp=gpar(fill="blue")) # alpha = 1
pushViewport(viewport(gp=gpar(alpha=0.5)))
grid.rect(height=0.25, gp=gpar(fill="red")) # alpha = 0.5
pushViewport(viewport(gp=gpar(alpha=0.5)))
grid.rect(width=0.25, gp=gpar(fill="red")) # alpha = 0.25 !
7. Editing a gp slot in a grob is now incremental. For example ...
grid.lines(name="line")
grid.edit("line", gp=gpar(col="red")) # line turns red
grid.edit("line", gp=gpar(lwd=3)) # line becomes thick AND STAYS red
8. The "cex" gpar is now cumulative. For example ...
grid.rect(height=unit(4, "char")) # cex = 1
pushViewport(viewport(gp=gpar(cex=0.5)))
grid.rect(height=unit(4, "char")) # cex = 0.5
pushViewport(viewport(gp=gpar(cex=0.5)))
grid.rect(height=unit(4, "char")) # cex = 0.125 !!!
9. New childNames() function to list the names of children
of a gTree.
10. The "grep" and "global" arguments have been implemented for
grid.[add|edit|get|remove]Grob() functions.
The "grep" argument has also been implemented for the
grid.set() and setGrob().
11. New function grid.grab() which creates a gTree from the
current display list (i.e., the current page of output can
be converted into a single gTree object with all grobs
on the current page as children of the gTree and all the
viewports used in drawing the current page in the childrenvp
slot of the gTree).
12. New "lineend", "linejoin", and "linemitre" gpar()s:
line end can be "round", "butt", or "square".
line join can be "round", "mitre", or "bevel".
line mitre can be any number larger than 1
(controls when a mitre join gets turned into a bevel join;
proportional to angle between lines at join;
very big number means that conversion only happens for lines
that are almost parallel at join).
13. New grid.prompt() function for controlling whether the user is
prompted before starting a new page of output.
Grid no longer responds to the par(ask) setting in the "graphics"
package.
Changes from grid_1.9.0 to grid_1.9.1:
------------------------------------
1. Fixed (unreported) bug in internal calculation of unitArithmetic
object when op = * and numeric operand longer than unit operand
2. Fixed (unreported) bug in creation of unitArithmetic objects
when numeric operand is integer. All numeric operands are now
coerced to real.
Changes from grid_1.8.0 to grid_1.9.0:
------------------------------------
1. Renamed push/pop.viewport() to push/popViewport().
2. Added upViewport(), downViewport(), and seekViewport() to
allow creation and navigation of viewport tree
(rather than just viewport stack).
3. Added id and id.lengths arguments to grid.polygon() to allow
multiple polygons within single grid.polygon() call.
4. Added vpList(), vpStack(), vpTree(), and current.vpTree()
to allow creation of viewport "bundles" that may be pushed
at once (lists are pushed in parallel, stacks in series).
current.vpTree() returns the current viewport tree.
5. Added vpPath() to allow specification of viewport path
in downViewport() and seekViewport().
See ?viewports for an example of its use.
NOTE: it is also possible to specify a path directly,
e.g., something like "vp1::vp2", but this is only
advised for interactive use (in case I decide to change the
separator :: in later versions).
6. Added "just" argument to grid.layout() to allow justification
of layout relative to parent viewport *IF* the layout is not
the same size as the viewport. There's an example in
help(grid.layout).
7. Allowed the "vp" slot in a grob to be a viewport name or a
vpPath. The interpretation of these new alternatives is to
call downViewport() with the name or vpPath before drawing the
grob and upViewport() the appropriate amount after drawing the
grob. Here's an example of the possible usage:
pushViewport(viewport(w=.5, h=.5, name="A"))
grid.rect()
pushViewport(viewport(w=.5, h=.5, name="B"))
grid.rect(gp=gpar(col="grey"))
upViewport(2)
grid.rect(vp="A", gp=gpar(fill="red"))
grid.rect(vp=vpPath("A", "B"), gp=gpar(fill="blue"))
8. Added engine.display.list() function. This allows the user to
tell grid NOT to use the graphics engine display list and to handle
ALL redraws using its own display list (including redraws after
device resizes and copies).
This provides a way to avoid some of the problems with resizing
a device when you have used grid.convert(), or the gridBase package,
or even base functions such as legend().
There is a document discussing the use of display lists in grid
on the grid web site
(http://www.stat.auckland.ac.nz/~paul/grid/grid.html)
9. Changed the implementation of grob objects. They are no longer
implemented as external references. They are now regular R objects
which copy-by-value. This means that they can be saved/loaded
like normal R objects. In order to retain some existing grob
behaviour, the following changes were necessary:
- grobs all now have a "name" slot. The grob name is used to
uniquely identify a "drawn" grob (i.e., a grob on the display
list).
- grid.edit() and grid.pack() now take a grob name as the first
argument instead of a grob. (Actually, they take a gPath -
see below)
- the "grobwidth" and "grobheight" units take either a grob
OR a grob name (actually a gPath - see below). Only in the
latter case will the unit be updated if the grob "pointed to"
is modified.
In addition, the following features are now possible with grobs:
- grobs now save()/load() like any normal R object.
- many grid.*() functions now have a *Grob() counterpart. The
grid.*() version is used for its side-effect of drawing
something or modifying something which has been drawn; the
*Grob() version is used for its return value, which is a grob.
This makes it more convenient to just work with grob objects without
producing any graphical output (by using the *Grob() functions).
- there is a gTree object (derived from grob), which is a grob
which can have children. A gTree also has a "childrenvp" slot
which is a viewport which is pushed and then "up"ed before the
children are drawn; this allows the children of a gTree to
place themselves somewhere in the viewports specified in the
childrenvp by having a vpPath in their vp slot.
- there is a gPath object, which is essentially a concatenation
of grob names. This is used to specify the child of (a child of ...)
a gTree.
- there is a new API for creating/accessing/modifying grob objects:
grid.add(), grid.remove(), grid.edit(), grid.get() (and their
*Grob() counterparts can be used to add, remove, edit, or extract
a grob or the child of a gTree. NOTE: the new grid.edit() API
is incompatible with the previous version.
10. Added stringWidth(), stringHeight(), grobWidth(), and grobHeight()
convenience functions (they produce "strwidth", "strheight",
"grobwidth", and "grobheight" unit objects, respectively).
11. Allowed viewports to turn off clipping altogether. Possible settings
for viewport clip arg are now:
"on" = clip to the viewport (was TRUE)
"inherit" = clip to whatever parent says (was FALSE)
"off" = turn off clipping
Still accept logical values (and NA maps to "off")
Changes from grid_1.8.0 to grid_1.8.1:
------------------------------------
1. I have effectively disabled the "mystrwidth", "mystrheight",
"mychars", and "mylines" units. These are now identical in
behaviour to the equivalent units without the "my".
Another way to look at it is that I have modified the behaviour
of "lines", "chars", "strwidth", and "strheight" so that they
ALWAYS obey the latest gpar settings (including any gpar
settings in a grob).
Some examples ...
This text is sized AND positioned in terms of a fontsize of 6:
grid.text("small text and small lines", y=unit(2, "lines"),
gp=gpar(fontsize=6))
This text is 6 pt in size, but is positioned in terms of the
(default on X11) fontsize 12:
push.viewport(viewport(y=unit(2, "lines")))
grid.text("small test and big lines", gp=gpar(fontsize=6))
pop.viewport()
2. Fixed a bug in the calculation of "grobwidth" and "grobheight"
units. The following code demonstrates the problem (the black
rectangle should snugly bound the grey rectangles):
grid.newpage()
# Create a frame with fontsize=6
gf <- grid.frame(layout=grid.layout(10, 10,
widths=unit(rep(1, 10), "strwidth",
as.list(rep("o", 10))),
heights=unit(rep(1, 10), "strheight",
as.list(rep("o", 10)))),
gp=gpar(fontsize=6))
# Add a rect to the frame
for (i in 1:10)
grid.place(gf, grid.rect(gp=gpar(col="grey"), draw=FALSE),
col=i, row=i)
grid.draw(gf)
# Now draw a rect around the frame
grid.rect(width=unit(1, "grobwidth", gf),
height=unit(1, "grobheight", gf))
3. Fixed a bug in the implementation of the "cex" gpar. This is now
used correctly in the transformation code in unit.c
The bug was demonstrated by the following simple example
(the second set of points should be twice the radius of the
first set of points):
grid.newpage()
push.viewport(viewport())
grid.points()
grid.points(gp = gpar(cex = 2))
Another demonstration from the original bug report from David Hinds:
xyplot(1:4~1:4, cex=1:4, pch=1)
4. Fixed a bug in multiplication of scalar by unit object, when the
scalar has length > 1. The following example demonstrates
the problem:
grid.segments(x0=1:3/4, y0=0.1, x1=1:3/4,
y1=1:3/4*unit(1, "npc"))
This should behave the same as:
grid.segments(x0=1:3/4, y0=0.1, x1=1:3/4,
y1=unit(1:3/4, "npc"))
Changes from grid_0.7-4 to grid_1.8.0:
------------------------------------
1. grid.text() now checks that the rot argument is numeric and finite.
2. dataViewport() checks for is.null(<arg>) rather than missing(<arg>)
and has renamed arguments x and y to xData and yData.
All to avoid confusion with specifying x= and y= in the ... argument.
This also fortuitously fixed a bug in dataViewport where the
calculation of the x-range was partially dependent on the y-range(!)
Thanks to Russell Norvell for spotting and reporting the bug.
3. unit() checks that units argument is character mode.
Fix for bug (first reported by Achim Zeileis) produced by,
for example ...
unit(1, 2)
4. The function absolute.units() was recursive and now uses a loop.
Fixes the following problem (from Deepayan Sarkar):
gf <- grid.frame(layout = grid.layout(nrow=1, ncol=1), draw = FALSE)
grob.rect <- grid.rect(x = 1:99/100, y = 1:99/100,
h = rep(.01, 100), w = rep(.05, 100),
gp = gpar(col = terrain.colors(100)),
draw = FALSE)
grid.pack(frame = gf, row = 1, col = 1,
grob = grob.rect,
draw = FALSE)
grid.draw(gf) # Fails with stack overflow
5. There is now a grid.locator() function for interactively selecting
locations within the current grid viewport with a mouse.
6. There is a new grid.convert() function for converting between
different coordinate systems.
The convertNative() function has been deprecated.
7. The default "top-level" viewport that is generated by grid
now has its "native" coordinate system set to the "native"
coordinate system of the device. For example, "native"
units at the top-level correspond to points on a PostScript
device, pixels on an X11 device, and so on.
For example, try the following:
library(grid)
x11()
grid.rect(x=10, y=10, width=10, height=10,
default.units="native")
This may cause consternation if you ever plot grid.points()
at the top-level because the default units for grid.points()
are "native" ... I consider this an unlikely occurrence.
8. Added a new gpar called "alpha" for specifying transparency.
This is supposed to be a number from 1 (opaque) to 0 (transparent).
No R devices will take any notice of this whatsoever as yet.
9. Modified "xaxis" and "yaxis" grobs so that they extend the
"collection" class. This means that, when a new generic function
is created, it may be possible to write methods just for the
collection class and not also separate xaxis and yaxis methods.
10. Modified unit subsetting so that logical indices work.
For example ...
unit(1:4, "npc")[1:4 == 3]
11. Fixed detaching/reloading of grid package (was causing an error).
12. There is a new grid.arrows() primitive.
See the help file for example usage.
13. Grid is now a base package (hence version number leap!)
Changes from grid_0.7-3 to grid_0.7-4:
------------------------------------
1. Fixed the bug in the bug-fix in item 7. below.
Changes from grid_0.7-2 to grid_0.7-3:
------------------------------------
1. Properly removed "origin" settings from viewports.
2. Modified grid.pretty() slightly so that it would respond
sensibly/usefully to things like ...
grid.pretty(c(10, 0))
A side-effect of this is that the following sort of viewport
scale specifications become sensible/useful ...
push.viewport(viewport(layout=grid.layout(1, 2)))
push.viewport(viewport(layout.pos.col=1))
push.viewport(viewport(w=.8, h=.8,
xscale=c(10,0)))
grid.points(1:10, 1:10/11)
grid.xaxis()
grid.yaxis()
pop.viewport(2)
push.viewport(viewport(layout.pos.col=2))
push.viewport(viewport(w=.8, h=.8,
yscale=c(10,0)))
grid.points(1:10/11, 1:10)
grid.xaxis()
grid.yaxis()
pop.viewport(3)
3. Fixed the calculation of number of "vertices" in grid.lines so that
it is the maximum of length(x) and length(y).
Used to be calculated solely on length(x).
4. Grid now throws an error if you try to create a unit of length 0.
This to fix a bug reported by Bud Gibson, the essence of which was ...
grid.points(size=unit(numeric(0), "mm"))
5. The default value of the "at" argument for grid.xaxis() and
grid.yaxis() is NULL (was NA; NA was inconsistent with other
default argument settings and basically a dumb idea)
6. Grid now throws an error if you try to create a gpar object with
an element of length 0.
This is to fix a bug reported by Michael Friendly (and diagnosed by
Brian Ripley), the essence of which was ...
grid.lines(gpar(fontsize=numeric(0)))
7. grid.text() now converts its label argument to a string.
This is to fix a bug where "grobwidth" or "grobheight" would
segfault if given a text grob for which the label was not a string.
(The fix involved including a check for "mystrwidth" and "mystrheight"
units in valid.data).
The bug could be produced by ...
grid.rect(w=unit(1, "grobwidth", data=grid.text(5)))
Changes from grid_0.7-1 to grid_0.7-2:
-------------------------------------
1. Fixed some generic/method incompatibilities (pointed out by Kurt).
Changes from grid_0.7 to grid_0.7-1:
------------------------------------
1. Fixed a bug where layout matrix respect was not being applied to
the correct cell. For example, the following caused the cell
1,3 to be respected rather than 1,2 ...
lt.resp <- matrix(0, 2, 3)
lt.resp[1,2] <- 1
grid.show.layout(grid.layout(2, 3, respect = lt.resp))
Reported by Deepayan Sarkar.
Changes from grid_0.6 to grid_0.7:
------------------------------------
1. The web pages for grid have moved to ...
http://www.stat.auckland.ac.nz/~paul/grid/grid.html
2. Mathematical annotation is now available in grid.
Wherever grid expects a string, an expression may be used instead.
This covers not only producing mathematical annotation output,
but also correctly calculating width and height of expressions,
and checking for overlapping expressions.
3. If you try to save/load a grid grob, it will now fail gracefully
rather than seg faulting.
4. If you save a display list containing grid output, then detach
grid, then try to run the display list again, it will now fail
gracefully rather than seg faulting.
5. All gpar() settings can now be vectors. Well, they could always
be vectors, but now values other than the first one will have an
effect. This will not happen in all contexts, for example,
viewports will only take notice of the first value in each setting,
but for graphics functions where multiple items can be output,
multiple settings may be sensibly given. Some examples are:
# multiple points with different colours
grid.points(1:10/11, 1:10/11, gp=gpar(col=1:10))
# multiple segments with different colours
grid.segments(1:10/11, 0, 1:10/11, 1, gp=gpar(col=1:10))
# multiple points with different sizes
grid.points(1:10/11, 1:10/11, size=unit(1:10, "mm"))
# multiple pieces of text with different font sizes
grid.text(1:10, x=1:10/11, gp=gpar(fontsize=10:20))
# multiple rects with different lineheights (and height is in "lines")
grid.rect(width=.05, x=1:10/11,
height=unit(1, "mylines"),
gp=gpar(lineheight=1:10))
6. (Because of a fix to R/src/main/engine.c ...)
Multiple-line text (i.e., text with "\n"s in it) is now correctly
spaced vertically (i.e., takes notice of the current value of
"fontsize").
NOTE, however, that multiple-line text still takes no notice of the
current value of "lineheight".
7. Fixed a bug in grid.layout(). It was the case that, if you
entered widths or heights which were not unit objects, they
were not converted properly to unit objects.
8. Modified the defaulting of "just" arguments when a single value
is provided. See the new example in grid.text.
9. Fixed a bug where grid.points(pch=NULL) would cause a crash.
This now defaults pch to the value 1.
10. Added "fontfamily" and "fontface" gpar() settings. The fontfamily
setting will mostly be ignored until devices are modified to take
notice of the extra information, BUT this can be used NOW to
specify a Hershey Font family (on all devices). The fontface
setting is designed to take over from the old "face" setting,
but the latter is retained for backward compatibility.
Changes from grid_0.5-1 to grid_0.6:
------------------------------------
1. Some internal changes to speed up creation of unit objects.
This may have a noticeable effect on drawing legends and anything
that relies on grid frames (e.g., "key"s in lattice).
2. A couple of bug fixes for "grobwidth" and "grobheight" units.
Symptoms were legends not being allocated the correct amount of
space.
Thanks to Deepayan Sarkar and Peter Kleiweg for help diagnosing
the bug and testing the fix.
3. Added plotViewport() and dataViewport()
convenience function for creating a
viewport that has the typical layout of an R plot.
4. Altered viewport() function so that layout.pos.row and layout.pos.col
can be specified as a sequence and only the range() of that
sequence is used.
5. Removed most documentation from the package to reduce the download
size. The user's guide and changes file are included with the
tar ball, but the other documents are only available via
http://www.stat.auckland.ac.nz/PEOPLE/paul/grid/grid.html
Also changed the format of the user's guide from postscript to pdf.
6. Fixed bug in unit.length where the length of a unit.arithmetic object
was calculated incorrectly if the length() of the scalar multiplier
was longer than the unit.length() of the unit object being multiplied.
7. Allowed character settings for pch in grid.points()
8. The crash on Windows platforms when plot history is turned on
has been fixed in R version 1.5.
This fix means that grid_0.6 will only run on R version >= 1.5.0
9. Added handling of NULL values for gpar elements. Except for col
and fill, this now means the same as specifying no setting at all
for the element -- previous behaviour was a segfault.
Changes from grid_0.5 to grid_0.5-1:
------------------------------------
1. Fix for some grid bugs.
The problems were:
(i) grid output could not be saved in metafile format
(ii) non-grid output could not be saved in metafile format when
grid was loaded
(iii) empty page at start of grid postscript output
(iv) empty page at start of non-grid postscript output when
grid was loaded
(v) copying grid output from x11 to postscript (dev.copy)
produced blank pages in postscript
These problems were due to two things in grid:
(i) grid created a new page whenever a new device was started.
(ii) grid created a new page whenever the display list was
replayed (e.g., when a device was resized or the output
was copied from one device to another)
Grid now only creates a new page the first time grid output is
produced on a device AND only creates a new page for replaying
the display list IF there has already been grid output on the device.
Changes from grid_0.2 to grid_0.5:
----------------------------------
1. R has a new device API and a new graphics engine. Grid uses these.
This means that this version will NOT work on R versions before 1.4.0
Another known "bug" is that this version of grid will crash R if
used in Windows with plot history recording turned on (although
"add"ing individual grid "plots" to the plot history should still
work).
2. Added "mystrwidth" and "mystrheight" units; basically these just
complete the set of units which depend on font, fontsize, and/or
lineheight and therefore may refer to the current viewport settings
of these parameters OR to the current settings of the grob being
drawn.
3. Added unit.rep function (the base rep() function is not generic
so I could not simply write a rep.unit method).
4. Added new gpar, "gamma", for gamma-correction of colours
(defaults to 1). NOTE that only windows devices will currently
respond to on-the-fly changes in gamma.
5. Added "clip" flag to viewports. If "clip" is TRUE, then output
is clipped to the viewport.
Clipping obeys only the most recent viewport clip setting.
For example, if you clip to viewport1, then clip to viewport2,
the clipping region is determined wholly by viewport2, the
size and shape of viewport1 is irrelevant (until viewport2
is popped of course).
If a viewport is rotated (because of its own "angle" setting
or because it is within another viewport which is rotated) then
the "clip" flag is ignored.
6. The functions grid.start() and grid.stop() have been removed.
grid automatically "registers" with devices.
7. Grid no longer automatically opens a device when it is loaded.
Instead, a device is created, if there are none open, when the
first drawing occurs or when the first viewport is pushed.
8. Added new functions unit.pmin() and unit.pmax() which are unit
versions of pmax() and pmin()
9. Added new function grid.place() which provides a simpler
interface to grid.pack() and is useful for using grid "frame"s
as just a convenient way of defining a layout and sticking
things in it.
Changes from grid_0.1 to grid_0.2:
----------------------------------
1. Fixed bug in rotating viewports; this should be more reliable now.
2. Added grid.line.to() and grid.move.to(). These allow drawing BETWEEN
different coordinate systems. See example in inst/doc/demo3.ps.
3. Added some more demonstrations to the doc directory.
4. Added more test code to the tests directory.
5. Added "grobwidth" and "grobheight" units. See the document
grid/inst/doc/advanced/parentchild.ps
6. Added more detailed documentation to grid/inst/doc/advanced. This
stuff is not as friendly for the reader, but may be useful if you're
tearing your hair out wondering why some strange effect is occurring.
7. Changed frames and packing to use the new "grobwidth" and "grobheight"
units. This fixes some problems with frames and packing.
8. Fixed a bug where the gpar settings for "fontsize" and "lineheight"
_within a grob_ would not affect the location or size of the grob
if they were specified in "lines" or "char" units.
This required adding new "mylines" and "mychar" units (alternative
suggestions for names welcome !) so that you can specify whether
a grob's a location/size is in terms of the current viewport's
fontsize and lineheight ("lines" and "char") or in terms of its own
fontsize and lineheight ("mylines" and "mychar").
9. Added grid.polygon() and grid.circle() primitives
10. Added newpage=TRUE argument to grid.start() so that you can restart
grid graphics mode without having to move to a new page.
For example, try ...
postscript()
grid.start()
grid.polygon()
grid.stop()
grid.start() # moves to new page
grid.circle()
grid.stop()
grid.start(newpage=FALSE) # does NOT move to new page
grid.rect()
grid.stop()
dev.off()
11. Changed interface for pop.viewport(). This now just takes a
number of viewports to pop, which defaults to 1.
For example ...
push.viewport(viewport())
pop.viewport(current.viewport())
... becomes ...
push.viewport(viewport())
pop.viewport()
... and ...
vp1 <- viewport()
vp2 <- viewport()
push.viewport(vp1, vp2)
pop.viewport(vp2, vp1)
... becomes ...
vp1 <- viewport()
vp2 <- viewport()
push.viewport(vp1, vp2)
pop.viewport(2)
12. Speed-up of pushing and popping viewports. This will probably not
be noticeable in normal usage, but makes a big difference for
frames and packing.
Changes from lattice_0.2 to grid_0.1:
-------------------------------------
0. Change of package name from "lattice" to "grid" (!!!!)
This means that most user functions have changed from l<something>
to grid.<something>
1. Slight speed up of grid.push.viewport and grid.pop.viewport.
2. Added sum() method for units.
For example, try ...
grid.rect(w=sum(unit(c(.25,.25), "npc")))
grid.rect(w=sum(unit(c(.25,.25), "npc"), unit(1, "cm")), border="red")
3. Changed the usage of grid.edit() slightly. If you want to specify
several new values at once, you must use grid.prop.list() rather
than just list(). For example, for a single new value use ...
grid.edit(<grob>, col="red")
... as before, but for multiple new values use ...
grid.edit(<grob>, grid.prop.list(col="red", lty="dashed"))
... rather than ...
grid.edit(<grob>, list(col="red", lty="dashed"))
4. Added a new grid.frame() grob. This acts a bit like a simple
grid.collection() BUT controls the placement of its children.
You add children using the grid.pack() function.
5. All viewports and grobs now have a "gp" slot which contains a
"gpar" object. This is a list of graphical parameters, which
replaces the specification of individual graphical parameters
for each different type of grob.
For example, instead of the old ...
grid.rect(w=.8, h=.8, border="red")
... we have the new ...
grid.rect(w=.8, h=.8, gp=gpar(border="red"))
This may seem like a loss (because you have to type more stuff),
and it is a loss, but the (hopefully greater) win is that (i) you only
have one parameter for all graphical settings, for example, ...
grid.rect(w=.8, h=.8, gp=gpar(border="red", lwd=3))
... and (ii) this applies for all grobs, for example, ...
grid.text("hi", gp=gpar(col="red", fontsize=10))
... and (iii) you can add more graphical parameters with minimal fuss,
for example, ...
grid.text("hi", gp=gpar(col="red", fontsize=10, new.par=whatever))
... and (iv) its easier to automate things (see below).
Graphical parameter settings are "permanent" so, for example, if
an axis sets the colour to "red" then all of its children are
drawn in "red" unless they set colour to something else.
For example, try ...
grid.multipanel(vp = grid.viewport(0.5, 0.5, 0.8, 0.8,
gp=gpar(fontsize=20)))
... and notice that all of the components of the multipanel take
notice of the fontsize setting of the parent viewport (except the
axis labels because they explicitly set the fontsize to 20 themselves).
The setting of graphical parameters is automated;
if you have a slot called "gp" in your grob, Lattice will
set the graphical parameters in that slot before calling
draw.details() and unset the parameters afterwards.
6. The pushing and popping of "local" viewports has been automated.
If you have a slot called "vp" in your grob, Lattice will call
grid.push.viewport() on that slot before calling draw.details()
and grid.pop.viewport() afterwards.
7. "collection" grobs and "[x|y]axis" grobs no longer pass editing
operations down to their children.
This was mainly (only ?) for sharing graphical parameter settings
and that duty is now performed by the gpar stuff in point 5 above.
This is a good thing because there are some cases where passing
down editing operations could cause serious damage. For example,
consider what would have happened if you had edited the "vp" slot
of a collection grob (!)