Change line type in rCharts NVD3 (nPlot)

别等时光非礼了梦想. 提交于 2019-12-13 06:53:27

问题


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.


回答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.




回答2:


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




回答3:


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



来源:https://stackoverflow.com/questions/24942366/change-line-type-in-rcharts-nvd3-nplot

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!