-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transition to the makeContent hook (in order to make the codebase eligible to exercise grid.force) #44
base: master
Are you sure you want to change the base?
Conversation
…eContent hook (grob is changed to gTree now)
…shape grobs as an extra (non-metadata) attribute (using a list object) of the data frame passed around
ae45330
to
feac076
Compare
e163675
to
807d0dd
Compare
Current approach at 807d0dd doesn't work for the shapeGrobs (only label is drawn) possibly because my attribute is a list object, and a The most obvious workaround (as I thought) would be to unwrap the list i.e. extract the individual grobs and then as comma separated items, put them inside as arguments within the library(grid)
textbox <- function(label, name = NULL, gp = NULL, vp = NULL) {
gt <- gTree(label = label, name = name, gp = gp, vp = vp, cl = "textbox")
grid.draw(gt)
}
makeContent.textbox <- function(x) {
groblist <- list()
tg <- textGrob(x$label, name = "text")
groblist[[1]] <- roundrectGrob(width = 1.5*grobWidth(tg), height = 1.5*grobHeight(tg), name = "box")
groblist[[2]] <- roundrectGrob(width = 2.5*grobWidth(tg), height = 2.5*grobHeight(tg), name = "box")
setChildren(x, eval(bquote(gList(..(groblist), tg), splice = TRUE)))
}
grid.newpage()
t <- textbox("test", name = "tb") |
The problem strictly lies with the shape grobs (polygons/rectangles), as for example, using a method which does not incorporate these boundary boxes around the labels or one that does not call # Example taken from https://github.com/Anirban166/GSoC21-Tests#medium-test
library(ggplot2)
library(directlabels)
alpha.data <- data.frame(size = c(1, 2, 3, 4, 5), power = c(1, 1.25, 1.75, 2.5, 3.5), type = "Alpha")
beta.data <- data.frame(size = c(1, 2, 3, 4, 5), power = c(1.5, 3, 5, 7.25, 9.5), type = "Beta")
gamma.data <- data.frame(size = c(1, 2, 3, 4, 5), power = c(2, 4, 6.5, 10, 13.5), type = "Gamma")
df <- rbind(alpha.data, beta.data, gamma.data)
g <- ggplot(df, aes(size, power, color = type)) + geom_line() + xlim(0, 6) + labs(x = "Particle Size", y = "Penetration Power") + coord_cartesian(clip = "off")
direct.label(g, method = "last.qp")
library(grid)
grid.force()
grid.ls(fullNames=TRUE) On the other hand, methods which use polygons/rectangles run without an error for the initial approach: (807d0dd) # Example taken from https://github.com/tdhock/directlabels/pull/41
df <- data.frame(i=1:10, label="more
than
one
line
really
a
lot")
library(ggplot2)
gg <- ggplot(df, aes(i, i, color=label))+
geom_line()
directlabels::direct.label(gg, "right.polygons")
grid::grid.force()
grid::grid.ls(fullNames = TRUE) Combined with the fact that they are showing the remaining forced grobs, (no shapeGrobs and no error means those grobs must not exist) this made me think - are the shapeGrobs even available inside makeContent, or are they collected properly within draw.polygons/rects? As it turns out, the grob list is in fact empty: (ran with the previous approach / changes in the last comment to trigger the error) |
…emplace them as arguments to the gList within setChildren inside the makeContent method
… the for loop in draw.polygons/rects
The assignment would work as normal (accessible outside the scope of the loop) within a regular for-loop but I realized a while ago that it was looping through the number of rows in the data frame with an environment constructed from it, i.e. using d <- data.frame(a = 1:3, b = 4:6, c = 7:9)
l <- list()
for(i in 1:nrow(d)) { l[[i]] <- i } # case 1
l # list with expected items: [[1]] 1 [[2]] 2 [[3]] 3
for(i in 1:nrow(d)) with(d[i, ], { l[[i]] <- i }) # case 2
l # list with 0 items As a solution for the second case, I'm using the However, makeContent still doesn't have access to the shape-grobs as because the attribute isn't being attached to the data frame (i.e. NULL values were being assigned in the gTree for |
While the approach for returning the data frame is okay in general, the way the functions are being called by each other, the data frame returned by d <- data.frame(a = 1:3, b = 4:6, c = 7:9)
f <- function(d) {
attr(d, 'newattrib') <- 1
return(d)
} In order to obtain the attribute, the data frame returned by use of this function must be used: attr(f(d), 'newattrib') # 1 Otherwise, it would return NULL, much like what I'm experiencing for my case. Thought to use the super assignment operator, (like |
In the current setup, @tdhock @bbolker what approach would you guys suggest to achieve this? |
first of all this is a great start, thanks for all the detailed debugging info. |
…from a list (values collected inside the for loop), and with separate ids for each row to distinguish between separate polygons and avoid contiguous drawing
…rts', include the grid version specification as an update, so as to have no conflicts with #44 (makecontent-transition branch)
Thanks, and you're welcome!
Done (also, there was a conflict with the description, so I updated that in master to match with the file here) Key was to use |
…s (or the total number of x/y values for one polygon based on a row)
… so as to use them in the call to polygonGrob() outside it
Codecov Report
@@ Coverage Diff @@
## master #44 +/- ##
=========================================
Coverage ? 44.45%
=========================================
Files ? 8
Lines ? 1046
Branches ? 0
=========================================
Hits ? 465
Misses ? 581
Partials ? 0 Continue to review full report at Codecov.
|
…ints in a row, and obtain them outside in polygonGrob (done with pg here)
51adde8
to
10e243b
Compare
Includes refactoring of:
dlgrob
(grob
togTree
) anddrawDetails
(drawDetails.dlgrob
tomakeContent.dlgrob
)draw.polygons
anddraw.rects
far.from.other.borders
,project.onto.segments
,calc.boxes
andempty.grid