title: D3.js Tree pass node.name on click to R Shiny
body: <p>I would like first to address my intentions</p>
  
  <p>1) Create a predefined D3.js collapsible Tree in Shiny</p>
  
  <p>2) On click of a node the name of this specific node is passed from D3.js to R for further operations. </p>
  
  <p>Well, at this moment I have a predefined D3.js collapsible tree in Shiny. I provide the code for js, server.R and ui.R below. Now at this point, I just have a interactive graphic, but I would like to go one step further. </p>
  
  <p>As soon as I click on a node, I would like to get the name of the node as a variable.</p>
  
  <p>I did my research (mainly here: <a href="https://github.com/metrumresearchgroup/SearchTree" rel="nofollow noreferrer">https://github.com/metrumresearchgroup/SearchTree</a>), so I know, that I have to use d3OutputBinding to create a new variable. Further I found out, that </p>
  
  <pre><code> .on('click', function(node) {
            alert(node.name);
  </code></pre>
  
  <p>would at least pop up a message with the nodes name. So I assume, I have to use something like </p>
  
  <pre><code>var d3OutputBinding = new Shiny.OutputBinding();
  $.extend(d3OutputBinding, {
      find: function(scope) {
          return $(scope).find('.div_tree2');
      },
      renderValue: function(el) {
          var svg = d3.select(el).select("svg");
  ...
  function update(source) {
  ...
  nodeEnter = node.enter().append("g")
  .on('click', function(node) {var nodes1 = node.name; });
  ...
  Shiny.onInputChange(".nodesData", JSON.decycle(nodes1));
  ...
  } // end of renderValue
  }); // end of .extend
  </code></pre>
  
  <p>And plug it into server.R via reactive function (input$.nodesData).</p>
  
  <p>Unfortunately, I am too dumb to achieve this. So I am kindly asking you for any advice.</p>
  
  <p>As already stated, I would provide my codes. Here goes my d3script_tree.js</p>
  
  <pre><code>    Shiny.addCustomMessageHandler("jsondata_tree",
    function(message){
  var treeData = [
    {
      "name": "Parent",
      "parent": "null",
      "children": [
        {
          "name": "A",
          "parent": "Parent"
        },
        {
          "name": "B",
          "parent": "Parent"
          }
      ]
    }
  ];
  
  
  // ************** Generate the tree diagram  *****************
  var margin = {top: 20, right: 120, bottom: 20, left: 120},
      width = 960 - margin.right - margin.left,
      height = 250 - margin.top - margin.bottom;
  
  var i = 0,
      duration = 750,
      root;
  
  var tree = d3.layout.tree()
      .size([height, width]);
  
  var diagonal = d3.svg.diagonal()
      .projection(function(d) { return [d.y, d.x]; });
  
  var svg = d3.select("#div_tree2").append("svg")
      .attr("width", width + margin.right + margin.left)
      .attr("height", height + margin.top + margin.bottom)
    .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  
  root = treeData[0];
  root.x0 = height / 2;
  root.y0 = 0;
  
  update(root);
  
  d3.select(self.frameElement).style("height", "500px");
  
  
  function update(source) {
  
    // Compute the new tree layout.
    var nodes = tree.nodes(root).reverse(),
        links = tree.links(nodes);
  
    // Normalize for fixed-depth.
    nodes.forEach(function(d) { d.y = d.depth * 180; });
  
    // Update the nodes…
  /*   var node = svg.selectAll("g.node")
      .data(nodes, function(d) { return d.id || (d.id = ++i); })
   */ 
      var node = svg.selectAll("g.node")
        .data(nodes, function(d) { return d.id || (d.id = ++i); })
  
    // Enter any new nodes at the parent's previous position.
    var nodeEnter = node.enter().append("g")
        .attr("class", "node")
        .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
        //.on("click", click);
        .on('click', function(node) {
        alert(node.name);
    });
  
    nodeEnter.append("circle")
        .attr("r", 1e-6)
        .style("fill", function (d) { return '#05415A'; })
        //.style("fill", function(d) { return d._children ? "#C00000" : "#fff"; });
  
    nodeEnter.append("link")
      .style("stroke-width", "3px");    
  
    nodeEnter.append("text")
        .attr("x", function(d) { return d.children || d._children ? -13 : 13; })
        .attr("dy", ".35em")
        .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
        .text(function(d) { return d.name; })
        .style("fill-opacity", 1e-6);
  
    // Transition nodes to their new position.
    var nodeUpdate = node.transition()
        .duration(duration)
        .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
  
    nodeUpdate.select("circle")
        .attr("r", 10)
        .style("fill", function (d) { return '#05415A'; })
       // .style("fill", function(d) { return d._children ? "#C00000" : "#fff"; });
  
    nodeUpdate.select("text")
        .style("fill-opacity", 1);
  
    nodeUpdate.select("link")
      .style("stroke-width", "3px");
  
    // Transition exiting nodes to the parent's new position.
    var nodeExit = node.exit().transition()
        .duration(duration)
        .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
        .remove();
  
    nodeExit.select("circle")
        .attr("r", 1e-6);
  
  
    nodeExit.select("text")
        .style("fill-opacity", 1e-6);
  
    // Update the links…
    var link = svg.selectAll("path.link")
        .data(links, function(d) { return d.target.id; });
  
    // Enter any new links at the parent's previous position.
    link.enter().insert("path", "g")
        .attr("class", "link")
        .attr("d", function(d) {
          var o = {x: source.x0, y: source.y0};
          return diagonal({source: o, target: o});
        });
  
    // Transition links to their new position.
    link.transition()
        .duration(duration)
        .attr("d", diagonal);
  
    // Transition exiting nodes to the parent's new position.
    link.exit().transition()
        .duration(duration)
        .attr("d", function(d) {
          var o = {x: source.x, y: source.y};
          return diagonal({source: o, target: o});
        })
        .remove();
  
    // Stash the old positions for transition.
    nodes.forEach(function(d) {
      d.x0 = d.x;
      d.y0 = d.y;
    });
  }
  
  // Toggle children on click.
  function click(d) {
    if (d.children) {
      d._children = d.children;
      d.children = null;
    } else {
      d.children = d._children;
      d._children = null;
    }
    update(d);
  }
    });
  </code></pre>
  
  <p>Next I have ui.R referencing to it. The CSS styles aren't of any importance, so it could be ignored.</p>
  
  <pre><code>library(shinydashboard)
  library(shinyjs)
  
  
  sidebar &lt;- dashboardSidebar(
    sidebarMenu(
      menuItem("Toy example", tabName = "toy", icon = icon("cog"))
    )
  )
  
  body &lt;- dashboardBody(
    tags$head(
      tags$link(rel = "stylesheet", type = "text/css", href = "custom.css")
    ),
    tabItems(
      tabItem(tabName = "toy",
              tags$div(class="d3-div",
                       #to style to d3 output pull in css
                       tags$head(tags$link(rel = "stylesheet", type = "text/css", href = "style.css")),
                       #load D3JS library
                       tags$script(src="d3.min.js"),
                       #tags$script(src="https://d3js.org/d3.v3.min.js"),
                       #load javascript
                       tags$script(src="d3script_tree.js"),
                       #create div referring to div in the d3script
                       tags$div(id="div_tree2"))
              )
    )
  )
  
  # Put them together into a dashboardPage
  dashboardPage(
    dashboardHeader(title = "Toy Example"),
    sidebar,
    body
  )
  </code></pre>
  
  <p>And finally, there is server.R to trigger this Java script.</p>
  
  <pre><code>library(shiny)
  library(shinyjs)
  
  shinyServer(function(input, output, session) {
    options(shiny.maxRequestSize=30*1024^2, shiny.usecairo=T)
  
    var_json_tree &lt;- toJSON(1, pretty = T)
    #push data into d3script
    session$sendCustomMessage(type="jsondata_tree",var_json_tree)  
  })
  </code></pre>