0

I would like to have both solid and dashed lines for different levels of a factor (grouping variable) in a plot created with nPlot. Any suggestions?

library(reshape2)
library(ggplot2)
library(rCharts)

ecm <- reshape2::melt(economics[,c('date', 'uempmed', 'psavert')], id = 'date')
p7 <- nPlot(value ~ date, group = 'variable', data = ecm, type = 'lineWithFocusChart')

Final result:

uempmed (solid line) and psavert (dashed line)

Another option could be to change the thickness of the lines instead.

user3874377
  • 255
  • 3
  • 10

3 Answers3

1

Unfortunately nvd3 has stagnated. This is a great example where a pull request that would allow the ability to specify thickness and dashed styling for lines sits unpulled.

Here is the difficult way to potentially solve your problem. We will need to modify the standard rCharts script template to add a callback function for the line styling. See here for a rCharts demo and a live code example.

  options(viewer=NULL)

  library(reshape2)
  library(ggplot2)
  library(rCharts)

  ecm <- reshape2::melt(economics[,c('date', 'uempmed', 'psavert')], id = 'date')
  p7 <- nPlot(value ~ date, group = 'variable', data = ecm, type = 'lineWithFocusChart')


  #grab template from
  #https://github.com/ramnathv/rCharts/blob/master/inst/libraries/nvd3/layouts/chart.html
  #modify to add callback on graph render

  p7$setTemplate(script = sprintf("
    <script type='text/javascript'>
      $(document).ready(function(){
        draw{{chartId}}()
      });
    function draw{{chartId}}(){  
      var opts = {{{ opts }}},
      data = {{{ data }}}

      if(!(opts.type==='pieChart' || opts.type==='sparklinePlus' || opts.type==='bulletChart')) {
        var data = d3.nest()
        .key(function(d){
          //return opts.group === undefined ? 'main' : d[opts.group]
          //instead of main would think a better default is opts.x
          return opts.group === undefined ? opts.y : d[opts.group];
        })
        .entries(data);
      }

      if (opts.disabled != undefined){
        data.map(function(d, i){
          d.disabled = opts.disabled[i]
        })
      }

      nv.addGraph(function() {
        var chart = nv.models[opts.type]()
        .width(opts.width)
        .height(opts.height)

        if (opts.type != 'bulletChart'){
          chart
          .x(function(d) { return d[opts.x] })
          .y(function(d) { return d[opts.y] })
        }


  {{{ chart }}}

  {{{ xAxis }}}

  {{{ x2Axis }}}

  {{{ yAxis }}}

  //on legend click, line might be deleted
  //when redrawn we need to make dashed again
  chart.legend.dispatch.on('legendClick', dashedAfterLegend )

  function dashedAfterLegend(){
    //to make dashed we need to make sure it is drawn first
    //not a js expert so might not be best way to handle
    window.setTimeout(function dashedDelay(){
      makeDashed(opts)
    }  , 400)
  }

  d3.select('#' + opts.id)
  .append('svg')
  .datum(data)
  .transition().duration(500)
  .call(chart);

  nv.utils.windowResize(chart.update);
  return chart;
      },%s);
    };
  %s
  </script>
  "
  ,
  #here is where you can type your line styling function
  "function(){ makeDashed( opts ) } "

  # here is the part that was in afterScript but moved to work with shiny
  #see this article for help on dashed d3 lines
  #http://www.d3noob.org/2013/01/making-dashed-line-in-d3js.html
  ,"
  function makeDashed( opts ){
    // select all the lines with d3 both main plot and focus
    // see this article for help on dashed d3 lines
    // http://www.d3noob.org/2013/01/making-dashed-line-in-d3js.html
    d3.select('#' + opts.id).selectAll('.nv-linesWrap .nv-group')
      .filter(function(g){return g.key== 'psavert'})
      .selectAll('.nv-line')
        .style('stroke-dasharray', ('3, 3'))
  }
  "

  ))
  p7

I understand that this is a lot of Javascript to ask of a R user, so please let me know if any of this does not make sense.

timelyportfolio
  • 6,479
  • 30
  • 33
  • This is amazing, and it works perfectly! Any idea of how to solve this [other issue with the same dataset?](http://stackoverflow.com/questions/24944151/add-vertical-line-to-line-chart-in-rchart-nvd3-nplot) – user3874377 Jul 25 '14 at 17:29
  • the other one is much tougher. I have the lines and labels drawn, but now I am trying to make sure they update when zoomed in or out. – timelyportfolio Jul 25 '14 at 18:58
  • Any idea why this new version updated to make dashed on legend click does not work in shiny? The previous version was working fine. – user3874377 Jul 29 '14 at 17:10
  • guessing the event handling; shiny overrides some of the event stuff and becomes very difficult to debug. I'll have a look but unfortunately might be a couple of days. Do you see any errors in the console ? – timelyportfolio Jul 29 '14 at 17:49
  • same as the vertical line / label http://stackoverflow.com/questions/24944151/add-vertical-line-to-line-chart-in-rchart-nvd3-nplot/24964707#24964707 . see https://github.com/ramnathv/rCharts/issues/414. I changed the code in the answer above and the gist to avoid use of afterScript. – timelyportfolio Jul 30 '14 at 14:19
  • good to hear; glad you are using it; would love any additional feedback – timelyportfolio Jul 31 '14 at 03:08
0
var dasheddesign=['10,20','5,5' ,'30,30','20,10,5,5,5,10'];         
d3.select('#chart1 svg')
    .datum(data)
    .call(chart)
    .call(function(){
d3.select('#chart1')
  .selectAll('.nv-line').each(function( d,i ){
   d3.select(this).attr("stroke-dasharray",dasheddesign[i]); 
  });

});

No delay required

Vikas Kumar
  • 519
  • 5
  • 16
0

This works fine, but thy to Hide and then Unhide series from legend. dash style is gone :(

Rafal
  • 209
  • 2
  • 3