@@ -4,6 +4,7 @@ dotstackGrob <- function(
44 stackaxis = " y" ,
55 dotdia = unit(1 , " npc" ), # Dot diameter in the non-stack axis, should be in npc
66 stackposition = 0 , # Position of each dot in the stack, relative to origin
7+ stackdir = " up" , # Stacking direction ("up", "down", "center", or "centerwhole")
78 stackratio = 1 , # Stacking height of dots (.75 means 25% dot overlap)
89 default.units = " npc" , name = NULL , gp = gpar(), vp = NULL )
910{
@@ -17,7 +18,7 @@ dotstackGrob <- function(
1718 warn(" Unit type of dotdia should be 'npc'" )
1819
1920 grob(x = x , y = y , stackaxis = stackaxis , dotdia = dotdia ,
20- stackposition = stackposition , stackratio = stackratio ,
21+ stackposition = stackposition , stackdir = stackdir , stackratio = stackratio ,
2122 name = name , gp = gp , vp = vp , cl = " dotstackGrob" )
2223}
2324# Only cross-version reliable way to check the unit of a unit object
@@ -31,14 +32,27 @@ makeContext.dotstackGrob <- function(x, recording = TRUE) {
3132 xmm <- convertX(x $ x , " mm" , valueOnly = TRUE )
3233 ymm <- convertY(x $ y , " mm" , valueOnly = TRUE )
3334
35+ # When stacking up (or down), stackratios != 1 will cause the bottom (top)
36+ # edge of the first dot in a stack to no longer touch the origin, as
37+ # stackpositions are expanded or contracted away from the dotstack's origin.
38+ # The stackoffset corrects that misalignment so that the first dot just
39+ # touches the dotstack's origin.
40+ if (is.null(x $ stackdir ) || x $ stackdir == " up" ) {
41+ stackoffset <- (1 - x $ stackratio ) / 2
42+ } else if (x $ stackdir == " down" ) {
43+ stackoffset <- - (1 - x $ stackratio ) / 2
44+ } else {
45+ stackoffset <- 0
46+ }
47+
3448 if (x $ stackaxis == " x" ) {
3549 dotdiamm <- convertY(x $ dotdia , " mm" , valueOnly = TRUE )
36- xpos <- xmm + dotdiamm * (x $ stackposition * x $ stackratio + ( 1 - x $ stackratio ) / 2 )
50+ xpos <- xmm + dotdiamm * (x $ stackposition * x $ stackratio + stackoffset )
3751 ypos <- ymm
3852 } else if (x $ stackaxis == " y" ) {
3953 dotdiamm <- convertX(x $ dotdia , " mm" , valueOnly = TRUE )
4054 xpos <- xmm
41- ypos <- ymm + dotdiamm * (x $ stackposition * x $ stackratio + ( 1 - x $ stackratio ) / 2 )
55+ ypos <- ymm + dotdiamm * (x $ stackposition * x $ stackratio + stackoffset )
4256 }
4357
4458 circleGrob(
0 commit comments