1

I am trying to build a shiny app that displays a complex force network graph that I have coded in d3JS. This goes beyond what I can do the R package networkD3, which I have tried. I instead want to bring in my highly customized .js file that handles the display and this is where I am lost.

To keep things simple let's consider the simplest of force network graphs, adapted from here: http://bl.ocks.org/sathomas/11550728 If someone can show me how to bring in the file SimpleFN.js (see below) with an example ui.R and server.R I could then extend the approach to my more complicated example. I know how to bring in the style.css file. Also not shown is the required reference to the d3.min.js library (http://d3js.org/d3.v3.min.js) which I also know how to reference.

I know what you are saying: "This is not a reactive graph! Why are you bothering?" I will get there, trust me. :)

Any assistance with this most basic of examples would be greatly appreciated!

Cheers!

Tim

NOTE: Cross-post to Shiny Google Group where there was no response to date.

File style.css:

.node {
    fill: #ccc;
    stroke: #fff;
    stroke-width: 2px;
}

.link {
    stroke: #777;
    stroke-width: 2px;
}

File SimpleFN.js :

var width = 640,
    height = 480;

var nodes = [
    { x:   width/3, y: height/2 },
    { x: 2*width/3, y: height/2 }
];

var links = [
    { source: 0, target: 1 }
];

var svg = d3.select('body').append('svg')
    .attr('width', width)
    .attr('height', height);

var force = d3.layout.force()
    .size([width, height])
    .nodes(nodes)
    .links(links);

force.linkDistance(width/2);

var link = svg.selectAll('.link')
    .data(links)
    .enter().append('line')
    .attr('class', 'link');

var node = svg.selectAll('.node')
    .data(nodes)
    .enter().append('circle')
    .attr('class', 'node');
force.on('end', function() {
    node.attr('r', width/25)
        .attr('cx', function(d) { return d.x; })
        .attr('cy', function(d) { return d.y; });
    link.attr('x1', function(d) { return d.source.x; })
        .attr('y1', function(d) { return d.source.y; })
        .attr('x2', function(d) { return d.target.x; })
        .attr('y2', function(d) { return d.target.y; });
});
force.start();
Tim
  • 929
  • 12
  • 30
  • The [networkD3 package](https://christophergandrud.github.io/networkD3/) for R might be of interest. – cengel Jul 05 '16 at 22:09
  • Thanks. In the meantime I discovered networkD3 and visNetwork packages. This are both good, though I find myself still going out to use d3js directly when I have to do a lot of customization (it just seems easier). – Tim Jul 06 '16 at 17:59

1 Answers1

2

If you have the d3.min.js, style.css and SimpleFN.js files in the same directory as your ui.R and server.R files you could do:

ui.R

library(shiny)

shinyUI(fluidPage(tags$head(includeScript("d3.min.js")),
                  includeCSS('style.css'),
    mainPanel(uiOutput("chart"))
    ))

server.R

library(shiny)

shinyServer(function(input, output) {
  output$chart <- renderUI({
    includeScript('SimpleFN.js')
  }) 
})

It takes a few seconds to load on my machine. You can also directly include the SimpleFN.js script in your ui.R if you don't need that part to be reactive.

NicE
  • 21,165
  • 3
  • 51
  • 68
  • Perfect. Good information about including directly within ui.R if reactivity not needed. In my case I will build this out to be reactive so will keep the separate ui.R and server.R components. Thanks much!! – Tim Mar 27 '15 at 17:12