d3.js - Can I use index.html and ui.r for my r shiny interface? -
in reference this on how build shiny app in html, i'm wondering if there way use approach in conjunction using traditional ui.r approach.
reason: this approach of using d3 r shiny seems require putting d3 code index.html file. want interactivity (selectinputs, daterangeinputs, multiple tabs, etc.). advice?
you can use tags add custom html ui.r
.
for more complicated outputs, can build custom shiny outputs while using app ui.r
, server.r
. this page has info on how code.
here's example using javascript code d3 example posted. app generates plot, added selectinput
can select data plots show how thing integrate. of javascript code mbostock. (can found here).
i added shiny binding parts , changed few lines adapt app, commented above changes can track them.
ui.r
library(shiny) shinyui( fluidpage(singleton(tags$head( #adds d3 library needed draw plot tags$script(src="http://d3js.org/d3.v3.min.js"), #the js script holding code make custom output tags$script(src="hierarchicaledgebundling.js"), #the stylesheet, paste between <style> tags example in graph_style.css file tags$link(rel = "stylesheet", type = "text/css", href = "graph_style.css") )), mainpanel( #this select input allows user choose json files in www directory selectinput("data_files", "json files:" , as.matrix(list.files(path="www",pattern="json"))), #this div hold final graph div(id="graph", class="hierarchicaledgebundling") ) ) )
server.r
shinyserver(function(input, output, session) { #output graph div output$graph <- reactive({ #get selected file input$data_files }) })
hierarchicaledgebundling.js
//shiny output binding var binding = new shiny.outputbinding(); binding.find = function(scope) { return $(scope).find(".hierarchicaledgebundling"); }; binding.rendervalue = function(el, data) { //empty div removes graph when change data $(el).empty() if(data!=null){ var diameter = 960, radius = diameter / 2, innerradius = radius - 120; var cluster = d3.layout.cluster() .size([360, innerradius]) .sort(null) .value(function(d) { return d.size; }); var bundle = d3.layout.bundle(); var line = d3.svg.line.radial() .interpolate("bundle") .tension(.85) .radius(function(d) { return d.y; }) .angle(function(d) { return d.x / 180 * math.pi; }); //select div has same id el id var svg = d3.select("#" + $(el).attr('id')).append("svg") .attr("width", diameter+300) .attr("height", diameter+300) .append("g") .attr("transform", "translate(" + radius + "," + radius + ")"); var link = svg.append("g").selectall(".link"), node = svg.append("g").selectall(".node"); //add data user input d3.json(data, function(error, classes) { var nodes = cluster.nodes(packagehierarchy(classes)), links = packageimports(nodes); link = link .data(bundle(links)) .enter().append("path") .each(function(d) { d.source = d[0], d.target = d[d.length - 1]; }) .attr("class", "link") .attr("d", line); node = node .data(nodes.filter(function(n) { return !n.children; })) .enter().append("text") .attr("class", "node") .attr("dy", ".31em") .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + (d.y + 8) + ",0)" + (d.x < 180 ? "" : "rotate(180)"); }) .style("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; }) .text(function(d) { return d.key; }) .on("mouseover", mouseovered) .on("mouseout", mouseouted); }); function mouseovered(d) { node .each(function(n) { n.target = n.source = false; }); link .classed("link--target", function(l) { if (l.target === d) return l.source.source = true; }) .classed("link--source", function(l) { if (l.source === d) return l.target.target = true; }) .filter(function(l) { return l.target === d || l.source === d; }) .each(function() { this.parentnode.appendchild(this); }); node .classed("node--target", function(n) { return n.target; }) .classed("node--source", function(n) { return n.source; }); } function mouseouted(d) { link .classed("link--target", false) .classed("link--source", false); node .classed("node--target", false) .classed("node--source", false); } d3.select(self.frameelement).style("height", diameter + "px"); // lazily construct package hierarchy class names. function packagehierarchy(classes) { var map = {}; function find(name, data) { var node = map[name], i; if (!node) { node = map[name] = data || {name: name, children: []}; if (name.length) { node.parent = find(name.substring(0, = name.lastindexof("."))); node.parent.children.push(node); node.key = name.substring(i + 1); } } return node; } classes.foreach(function(d) { find(d.name, d); }); return map[""]; } // return list of imports given array of nodes. function packageimports(nodes) { var map = {}, imports = []; // compute map name node. nodes.foreach(function(d) { map[d.name] = d; }); // each import, construct link source target node. nodes.foreach(function(d) { if (d.imports) d.imports.foreach(function(i) { imports.push({source: map[d.name], target: map[i]}); }); }); return imports; } } }; //register output binding shiny.outputbindings.register(binding, "hierarchicaledgebundling");
to make app work need create www
folder in same directory ui.r
, server.r
, put in hierarchicaledgebundling.js
file, css found here in graph_style.css
file, , json data file (for example data1.json or data2.json).
Comments
Post a Comment