Javascript variables...back into R

2,179 views
Skip to first unread message

Ryan Mears

unread,
Feb 12, 2013, 4:35:09 PM2/12/13
to shiny-...@googlegroups.com
Hello,
I am having trouble moving data from a javascript variable back to R after user interaction (i.e.,to obtain pixel coordinates from html canvas).
I've worked through the input tutorial on custom input bindings and made variations on the increment button script.
 
I'm certain that my inability to get data from a javascript variable is because I don't adequately understand the concept of javascript closures. 
Could someone please help? I'd like to know how to move data (string or some number format) from a javascript variable to a variable in R.
Much thanks in advance.
-Ryan

Joe Cheng

unread,
Feb 13, 2013, 2:23:06 AM2/13/13
to shiny-...@googlegroups.com
Ryan, if you can share the code you have so far it would make it a lot easier to help--is that a possibility?


-Ryan

--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Ryan Mears

unread,
Feb 13, 2013, 12:11:06 PM2/13/13
to shiny-...@googlegroups.com
Joe,
Here is the javascript file

and ui and server R.

The working example is on glimmer:

I have two questions now.
1) If you click on the canvas in the "Select" tab the centered-coordinates for each "component" are displayed at the top of the canvas, how can I get clicked coordinates into R so that I can add the coordinate to the data.frame listed under the "Table" tab.
2) Is there a way to send the mousedown canvas coordinates directly to R? (This isn't important for this project.) For future projects I'd like to send a javascript variable or array directly to R without the html intermediary. 
Many, many thanks!
-Ryan
Message has been deleted

Ramnath Vaidyanathan

unread,
Feb 13, 2013, 5:28:52 PM2/13/13
to shiny-...@googlegroups.com
Here is an ugly hack to achieve it.


I am attaching my code along with this. I will update this thread with a short explanation later tonight, but the code is pretty self explanatory.
app7.zip

Ryan Mears

unread,
Feb 13, 2013, 9:29:30 PM2/13/13
to shiny-...@googlegroups.com
Ramnath,
That is so clever to use the existing input binding. It is a hack, but it's more brilliantly simple, than ugly. 
I'd still like to hear more explanation/examples from Joe Cheng (or a RStudio maintainer) of how to formally manage input/output bindings (i.e., for javascript beginners like myself).
-Ryan
Message has been deleted

Joe Cheng

unread,
Feb 14, 2013, 3:00:28 PM2/14/13
to shiny-...@googlegroups.com
That's very clever, Ramnath.

I think we should add an <input type="hidden"> binding to Shiny. So you could just set the hidden value, rather than a visible field and then hiding it.

I hesitate to share this with you, but there is another way, that is not documented and may not be supported in the future as it breaks some collaboration features we were hoping to get to one day. You can call Shiny.onInputChange(name, value) and that will act as if that control exists and was changed. However it can't be used while the page is loading; the Shiny client code must have fully initialized first.


On Wed, Feb 13, 2013 at 6:43 PM, Ramnath Vaidyanathan <ramnath...@gmail.com> wrote:
Here is a cleaner solution. I have basically replaced your maptitle element with a hidden textInput with the same id. This way we can directly let javascript manipulate the text input for which Shiny already has a binding defined. Note that you need to unbind all before letting javascript update a Shiny input variable and then bind them back again. This is required for reactivity to work. Here is a gist with ui.R, server.R and mycanvas_ic.js.


Cheers

Alex Brown

unread,
Feb 15, 2013, 5:38:21 PM2/15/13
to shiny-...@googlegroups.com
I have a GIST that gives javascript an INPUT that can be read from R.


Also includes an output.

-Alex

Laszlo Szakacs

unread,
Feb 15, 2013, 6:53:46 PM2/15/13
to shiny-...@googlegroups.com
+1 for "hidden" binding

Ryan Mears

unread,
Feb 16, 2013, 10:34:59 AM2/16/13
to shiny-...@googlegroups.com
Alex,
Once I understand how this i/o binding works I'll send an update.
The direct javascript input is most appealing with the shortest possible lag without hanging up the UI (especially for locations with server-client communication lags).
The potential to interface to d3.js is very cool.
Thanks!
-Ryan

Ryan Mears

unread,
Feb 26, 2013, 1:15:35 PM2/26/13
to shiny-...@googlegroups.com
Javascript scoping is not at all intuitive to me, and the event loop in the gist (see below, canvasImg.js) is difficult to combine with other javascript event listener loops that I'm trying to implement.

Currently, I'm attempting to create a custom input binding for shiny that produces the same behavior as the following javascript behavior:

I'd like to extend selectInputBinding from shiny.js to produce a new image reference and to redraw canvas whenever a new selection from the drop down menu occurs.
The problem with canvasImg.js is that the event loop is continuous, not conditional like the reactive functions in shiny.

It might be possible to use an approach similar to the extension of textInputBinding in shiny.js:

var textareaInputBinding = {};
  $.extend(textareaInputBinding, textInputBinding, {
    find: function(scope) {
      return $(scope).find('textarea');
    }
  });
  inputBindings.register(textareaInputBinding, 'shiny.textareaInput');
I think that I need to understand the following terms/concepts so that I can create a custom shiny input:
1) scope (The dropdown selector, canvas, & new image need to be included for the namespace/closure.)
2) return (I anticipate that return would be the mechanism to instruct canvas to draw the new image node)
3) callback (I think a callback is needed to update multiple canvases with multiple different images from a single dropdown selection. From what I understand, callbacks are heart of communication between multiple javascript processes.)

Thanks in advance!


Joe Cheng

unread,
Feb 26, 2013, 6:31:30 PM2/26/13
to shiny-...@googlegroups.com
I don't understand this sentence, can you elaborate?

The problem with canvasImg.js is that the event loop is continuous, not conditional like the reactive functions in shiny.

Ryan Mears

unread,
Feb 26, 2013, 7:43:39 PM2/26/13
to shiny-...@googlegroups.com
I probably shouldn't have included that. This was my guess why I was unable to combine two different event loops. 
The other event loop pertains to mouse move and mouse click locations on canvas. For example move the mouse over canvas and click with the following:




You received this message because you are subscribed to a topic in the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/shiny-discuss/ITFUwvYE-f8/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to shiny-discus...@googlegroups.com.

Ryan Mears

unread,
Feb 26, 2013, 8:02:45 PM2/26/13
to shiny-...@googlegroups.com
Here is the code for the canvas behavior:
The mouse click behavior on canvas should ultimately make a data frame addition (another version of this routine in R will append to icsheet.csv). 

Ryan Mears

unread,
Feb 28, 2013, 7:14:32 AM2/28/13
to shiny-...@googlegroups.com
Update: It appears that the closure of canvasing.js https://gist.github.com/doesmindmatter/5006486 is preventing the canvas context from being updated by other event listeners that are outside the closure https://gist.github.com/doesmindmatter/5043908

Ryan Mears

unread,
Feb 28, 2013, 11:12:15 AM2/28/13
to shiny-...@googlegroups.com
How can a string variable be made visible to scopes outside a javascript closure? 
Thanks in advance for any insight!!

 var str="b1-140";  
  var imgstr="";
$("select").change(function () {
  $("select option:selected").each(function () {
     var str = $(this).text();
      return str;   
  });
   var imgstr=str;
return imgstr;
}).change();

Joe Cheng

unread,
Feb 28, 2013, 9:50:25 PM2/28/13
to shiny-...@googlegroups.com
Declare "var str;" up by 'var imgstr=""'. Or better yet, simply change "var str = $(this).text();" to "imgstr = $(this).text();" and get rid of str altogether.


Ryan Mears

unread,
Feb 28, 2013, 10:49:43 PM2/28/13
to shiny-...@googlegroups.com
Great! 
Thank you, Joe!



--
You received this message because you are subscribed to a topic in the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/shiny-discuss/ITFUwvYE-f8/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to shiny-discus...@googlegroups.com.

Blake Arensdorf

unread,
Feb 13, 2014, 6:47:36 PM2/13/14
to shiny-...@googlegroups.com
Can someone give me a brief summary of how to do this? I'm currently in the process of moving the functionality backgrid.js over to Shiny. I pass in the data by converting to JSON and then displaying it, but since the user can make changes to the table, I need to figure out how to get the table back into R and do something with it and I can't figure it out.

I think this thread might have a solution but I'm not following these comments and with things being deleted, can someone provide a short explanation / snippet of how I'd go about doing this?

Thanks.

ZJ

unread,
Feb 13, 2014, 10:45:30 PM2/13/14
to shiny-...@googlegroups.com
Message has been deleted

Blake Arensdorf

unread,
Feb 14, 2014, 4:14:15 PM2/14/14
to shiny-...@googlegroups.com
I figured this would be better in a Gist.

Thanks, ZJ. I've actually been following those tutorials but can't seem to get the data back into R correctly. Hopefully you guys can take a look at this function and see where I'm going wrong, but I've basically tried to start by building it as simple as possible and then once I get it working I'll spend time wrapping it up and making it usable by others and understandable from a code perspective. 

So far I've gotten the backgrid table to display in my app by using this "GetBackgrid" function and putting it in 'global.r'. When I want to render the table, I simply call this function from server.R. However, when I reference the 'input$campaignGrid' which is the id I've given the object in the HTML, it returns null though the table is still populated. Here is what I've done (again this renders and looks perfect but doesn't return the value I want):

Reply all
Reply to author
Forward
0 new messages