rd3.jsrchartssankey-diagramriverplot

Making a Sankey diagram in R for printing


I am trying to make a Sankey diagram using R for a printed report. I have currently used 2 methods to do this but neither is achieving quite what I wanted.

The first uses the Riverplot function and produces this:enter image description here

My problems with this plot is that I can't work out how to control the whitespace around the plot (it appears to be fixed and does not adjust to different sized datasets) or the positioning of the annotated text. I want to repeat this plot for a number of similar but differently sized datasets but the text placing is very variable in its positioning. This is the code I am currently using to add the text annotations:

riverplot(a, srt = 0)
y_lim<-par("yaxp") #gets y axis limits to spicify text placements
#  text(1.5,y_lim[1], Name,font=2) #labels plot with Name (LA)
text(1,y_lim[1],"2004")
text(2,y_lim[1],"2010")

The second uses the rCharts and produces this:enter image description here

My problems with this are (a) I would like to fix the order of the categories on each side (as in the first image) and (b) I would like to annotate the diagram as in the first image. My questions are:

  1. How I can fine tune the formatting of the Riverplot figure (first image), or,
  2. How do I add annotations to the rCharts Sankey plot (I'm guessing this could be through the script section but I am new to rCharts, d3 and javascript), and,
  3. Is it possible to fix the order of the categories int the rCharts sankey plot.

Solution

  • After a lot of tinkering and pinching code from a bunch of places, I have managed to produce what I wanted (solving point 2 of my original question). enter image description here
    The code could be refined in a number of places and could probably be done more elegantly but I have included it below in case it helps anyone else.

    sankeyPlot$setTemplate(
      afterScript = "
    <script>
    
    var cscale = d3.scale.ordinal()
    .domain(['N','E', 'G' ,'I','T','N ','E ', 'G ' ,'I ','T '])
    .range(['#d3d3d3', '#32ca32', '#1f78b4', '#e31a1c','#ecd736','#d3d3d3',    '#32ca32', '#1f78b4', '#e31a1c','#ecd736'])
    
    
    
    d3.selectAll('#{{ chartId }} svg path.link')
    .style('stroke', function(d){
    return cscale(d.source.name);
    //returns grey links
    })
    
    d3.selectAll('#{{ chartId }} svg .node rect')
    .style('fill', function(d){
    return cscale(d.name)
    })
    .style('stroke', 'none')
    
    var text_box = d3.selectAll('#{{ chartId }}').append('svg')
        .attr('width', 500)
        .attr('height', 100)
    
    var TextData = [
        { 'cx': 0, 'cy': 20 ,'label': 'Type A', 'pos': 'left'},
        { 'cx': 250, 'cy': 20,'label': 'Label','pos': 'middle'},
        { 'cx': 500, 'cy': 20, 'label': 'Type B','pos': 'end'}];
    
    var text = text_box.selectAll('text')
                        .data(TextData)
                        .enter()
                        .append('text');
    
    //Add the text attributes
    var textLabels = text
                 .attr('x', function(d) { return d.cx; })
                 .attr('y', function(d) { return d.cy; })
                 .text( function (d) { return d.label ; })
                  .attr('text-anchor', function(d) { return d.pos ;})
                 .attr('font-family', 'sans-serif')
                 .attr('font-size', '14px')
                 .attr('fill', 'black');
    
    </script>
    ")