from ggplotly, open all new hyperlinks in the same new window/tab - r

I am using the following example code where click on the point opens a link:
data(mtcars)
mtcars$urlD <- paste0("http://google.com/search?q=", gsub(" ", "+", rownames(mtcars)))
p <- ggplot(data=mtcars, aes(x=wt, y=mpg, color=factor(carb), customdata=urlD)) + geom_point()
pp <- ggplotly(p)
ppp <- htmlwidgets::onRender(pp, "
function(el, x) {
el.on('plotly_click', function(d) {
var url = d.points[0].customdata;
window.open(url);
});
}
")
It works fine but every new click opens new window/tab. Is there any way to make it use the same window? (I mean not the window with the plot but the window where the first link was opened) In usual javascript, I would use the name parameter of window.open(), like this: window.open(url, 'MyTargetWindow'); - but it doesn't help here. Any workarounds?

You must be using Rstudio. window.open(url, 'MyTargetWindow') works in browser but not in Rstudio. If you click the "show in new window" button and open the plot in your browser, it works. The reason is window name is recognized in the same browser, but when you open a new browser (from Rstudio Viewer to the actual browser in this case), the name info is not passed. I am not aware of a solution to solve this cross-browser issue.

Related

Shiny interactive document download button overwrites original R markdown

So I'm trying to write an html R markdown document with interactive shiny bits that allow the user to edit a graph and then download the results to a pdf. However, there is something catastrophically wrong with the way that I'm trying to do this because as soon as the html starts, it overwrites the original markdown file with the contents of the pdf - turning it into complete gibberish right in the editor.
I doubt that I've found a completely new way to fail at R but I haven't been able to find where anybody else has had this issue. Additionally, I've looked over the shiny reference material and I'm just going in circles at this point, so any help would be greatly appreciated.
I'm using Rstudio 1.0.44, rmarkdown 1.2 and shiny 0.14.2. A small (not)working example:
---
title: "Minimum Failing Example"
author: "wittyalias"
date: "December 5, 2016"
output: html_document
runtime: shiny
---
```{r echo = FALSE}
library(ggplot2)
today <- Sys.Date()
inputPanel(downloadButton("dnld", label = "Download pdf"))
renderPlot({
# Example code from http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2)/
p1 <<- ggplot(ChickWeight, aes(x=Time, y=weight, colour=Diet, group=Chick)) +
geom_line() +
ggtitle("Growth curve for individual chicks")
p1
})
reactive({
fname <- paste0("Chick Weight - ", today, ".pdf")
output$dnld <- downloadHandler(filename = fname,
content = makethepdf(file))
makethepdf <- function(fname) {
pdf(fname,
width = 14,
height = 8.5)
p1
dev.off()
}
})
```
EDIT: To be clear: I want the user to be able to download multiple pages of graphs, some of which will have different formatting. The user won't be downloading just a pdf version of the markdown document.
This happens because reasons I weren't able to identify makethepdf runs with the file = [name of the file]. Insert a print(fname) to see. The download handler isn't supposed to be inside an observer though. You need to have it outside on its own. I also failed to make pdf() dev.off() combination work for some reason so here's a working version below.
output$dnld = downloadHandler(filename = paste0("Chick Weight - ", today, ".pdf"),
content = function(file){
ggsave(file, plot = p1, width = 14, height = 8.5)
})
Use tempfile() and tempdir() to create a temporary file:
output$downloadReport = downloadHandler(
filename = function() {
normalizePath(tempfile("report_", fileext = ".docx"), winslash = "/")
},
content = function(file) {
out = rmarkdown::render("./report.Rmd",
output_file = file,
output_dir = tempdir(),
output_format = "pdf_document",
intermediates_dir = tempdir(),
envir = new.env(),
params = list( fontSize = 10)
)
})
I usually use a separate .Rmd template for my downloaded reports as the layout and text are usually similar but not identical to what works in an app.
I also find using parameters is a convenient way to pass input settings from my app to my report. See this RStudio post for details
Alright, so there are a number of problems with my code, but using some of the suggestions in the other answers I've been able to work it out.
The primary problem with this little document is that content in the downloadHandler is a function, but in my code I set content equal to the result of a function call. It looks like when the shiny app is first run it compiles content, thinking that it is a function, but actually ends up calling the function. It sends file as an arguement, which doesn't seem to exist except as a base function. Calling makethepdf with just file throws an error when I use it in the console, but for whatever reason in this app it just goes with the call, apparently with file = [name of the .Rmd] (just as OganM said).
To fix, change this:
output$dnld <- downloadHandler(filename = fname,
content = makethepdf(file))
to
output$dnld <- downloadHandler(filename = fname,
content = makethepdf)
To be clear: this code does not overwrite the .Rmd file if content calls makethepdf with any argument other than file. For instance, content = makethepdf(fnm)) causes the download button to display an object not found error and content = makethepdf(fname)) causes the download button to throw an attempt to apply non-function error when pressed.

Shiny downloadHandler doesn't save PNG files

I've got my download function to do everything right, when the save as screen comes up, the file name I specified appears. When I click on save the window closes, but no file gets saved...
The same plot works fine in the app, the only problem is I cant seem to save it to a PNG file.
I run the shine app on my laptop and use RStudio.
Here is some extracts of my code.
ui.R
downloadButton('downloadSMemPlot', 'Download Graph')
server.R
'#draw membersip plot
s.MemPlotInput <- reactive({
'#some code to get data
s.MemPlot <- ggplot() +
geom_density(aes(x=Age, fill = Years), data=s.ben, alpha = 0.5) +
ggtitle("Density of beneficiary ages") +
theme_igray() +
theme(plot.title = element_text(lineheight=.8, face="bold")) +
xlab("Age in full years") + ylab("Density")+
scale_fill_hue()
})
output$s.memplot <- renderPlot({
print(s.MemPlotInput())
})
'#download membership plot
output$downloadSMemPlot <- downloadHandler(
filename = "MembershipPlot.png",
content = function(file) {
png(file, type='cairo')
print(s.MemPlotInput())
dev.off()
},
contentType = 'application/png'
)
You want
contentType = 'image/png'
not
contentType = 'application/png'
Although I don't think that's the problem. Are you running it within RStudio's preview pane or in an external browser? I had the same problem with downloading when using the preview pane but it worked fine on my browser.

R : How to control the right click of mouse in gWidgets

In gWidget GUI I have seen a feature on right click on mouse
Copy
Save
How can I use that Save handler so save my shown dataset in table ?
Kindly refer to the image below :
Also in my code I have used graphicspane1 <- ggraphics(cont = group1)
Kindly suggest answers ASAP
Here is a sample code,
library(cairoDevice)
library(gWidgets)
library(gWidgetsRGtk2)
require(RGtk2)
fun <- function(){
tbl <- data.frame(A=c(1,2,3),X=c('A','B','C'))
grid.draw(tableGrob(tbl, gp=gpar(fontsize=8, lwd=1.2)))
}
options(guiToolkit = "RGtk2")
w <-gwindow("GUI")
g <-ggroup(cont=w)
plotbutton4 <- gbutton('Draw Table', cont = g, handler=function(h,...){
fun()})
graphic1 <- ggraphics(cont=g)
Steps : 1. Click on the button "Draw Table"
Step : 2. Right Click and try to save the data.
How can I make a relation with that Save & Copy Button, more focus on SAVE

How do I update a gedit box instantly after using gfile to specify a filepath, using gWidgetsRGtk2, in R

I am trying to create a GUI using gWidgetsRGtk2 for a program that I have written in R. My GUI has a gedit() text box in which the user can type a file path for the input data file to be put into the program. It also has a 'browse' button, which, when clicked, opens up a gfile() box so that they can browse for the file that they want. What I am having trouble with is updating the value in my gedit() box, after the user has selected their file using the 'browse' button. The code below may make this clearer:
dir <- getwd()
sfilepath <- paste0(dir,"/")
win = gwindow("Set Parameters:",width=400,height=550)
nb = gnotebook(cont=win)
tab2 <- glayout(cont=nb, label = "Advanced Settings")
tab1 <- glayout(cont=nb, label = "Basic Settings")
tab1[2,2] <- glabel("BD:",cont=tab1)
tab1[2,4:5] <- gedit(1,cont=tab1)
addhandlerkeystroke(tab1[2,4],handler=function(h,...){BD <<- as.numeric(svalue(h$obj))})
tab1[3,2:5] <- gseparator(cont=tab1)
tab1[4,2:5] <- glabel("File path:",cont=tab1)
tab1[5,2:4] <- gedit(paste0(dir,"/"),cont=tab1)
tab1[5,5] <- gbutton(text="Browse", handler=function(h,...){ gfile("Select a file",type="open", filter = list("text files" = list(patterns = c("*.csv","*.txt")), "R files" =list(patterns = c("*.R","*.Rdata"))), handler = function(h,...){ sfilepath <<- h$file},cont=TRUE)},cont=tab1)
addhandlermousemotion(tab1[5,2],handler=function(h,...){svalue(h$obj) <- sfilepath})
So far I have tried using addhandlermousemotion, as in the code above, so the text in the gedit() box is only updated when you move the mouse over the box itself. However, I would prefer it if the text in the box updated instantly.
I have also tried using addhandleridle(), with an interval of 1 second, so that the text in the box will be automatically updated every 1 second. This worked. However, it made it impossible to type in the box properly, because the text box was being updated with the old 'sfilepath' before it had saved the new 'sfilepath' that was being typed in.
I am a beginner at making at GUIs (I have written a program for work, but it needs to be used by someone else once I leave, so decided last Friday that I should figure out how to make it into a GUI). So any help that anyone can offer would be greatly appreciated.
Here is the pattern you want (passing a handler to gfilebrowse):
w <- gwindow("test")
g <- ggroup(cont=w, horizontal=FALSE)
file_upload <- gfilebrowse(cont=g, handler=function(h,...) {
svalue(e) <- svalue(h$obj)
})
e <- gedit("", cont=g)

Adding a GIF image to a TclTk window

I wish to insert a 'loading' GIF image to my tcltk window but just can't get my head around it. Following is a reproducible example:-
backg <- 'white'
pdlg <- tktoplevel(background=backg)
tcl('wm', 'geometry', pdlg, '500x100+450+350')
tilg <- 'Package installation in progress'
tkwm.title(pdlg, tilg)
fn <- tkfont.create(family = 'helvetica', size = 12)
nwlabel <- " The requisite packages are being installed. This may take several \nminutes... \n"
tllab <- tklabel(pdlg, text = nwlabel, font = fn, pady = 0, background=backg)
clickEv <- tclVar(0)
OK.but <- tkbutton(pdlg, text=' Stop ', command=function() tclvalue(clickEv) <- 1, font=fn, background='grey', pady=0)
tkgrid(tllab, columnspan=1)
tkgrid(OK.but, row=3)
tkbind(pdlg, "<Destroy>", function() tclvalue(done) <- 2)
tkfocus(pdlg)
#This allows me to insert a GIF image but the animation is lost. Also it would be convenient if the output can be obtained using 'tkgrid' instead of 'tkpack'
pdlg2 <- tktoplevel(background='white')
loading <- tclVar()
tcl('image', 'create', 'photo', loading,
file='file path to GIF file')
trial <- tklabel(pdlg2, image=loading)
tkpack(trial)
An example GIF file can be downloaded from here -http://www.dlfpramericalife.com/library/images/final_loading_big.gif
Ideally, the GIF image should be placed above the 'Stop' button but below the text. Many thanks for your help!
In Tcl/Tk, it's quite easy.
set img [image create photo -file nameofthefile.gif]
label .l -image $img
I don't know R, but taking your code as a guide, I imagine something like this, but please check it!
img <- tkimage.create('photo', file='nameofthefile.gif')
imglab <- tklabel(pdlg, image = img)
... then you grid/pack/place it wherever you want. Please note that this don't work with animated gifs and I think animation must be hand-handler, using a timer which updates periodically the image content, but I never did it, nor I know how to do. You may check the Tcl/Tk wiki for more help.

Resources