更改rCharts NVD3中的线型(nPlot)

时间:2014-07-24 19:28:13

标签: r rcharts nvd3.js

我想在使用nPlot创建的图中为不同级别的因子(分组变量)提供实线和虚线。有什么建议吗?

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')

最终结果:

uempmed (solid line) and psavert (dashed line)

另一种选择可能是改变线条的粗细。

3 个答案:

答案 0 :(得分:1)

不幸的是nvd3停滞不前。这是一个很好的例子,其中pull request允许指定线条的粗细和虚线样式的功能无效。

这是解决问题的难点。我们需要修改标准rCharts脚本模板,为线条样式添加回调函数。请点击此处查看rCharts demolive 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

我知道这是R用户要求的很多Javascript,所以请告诉我这是否有任何意义。

答案 1 :(得分: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]); 
  });

});

无需延迟

答案 2 :(得分:0)

这很好,但是你可以隐藏,然后从传奇中取消隐藏系列。破折号风格消失了:(