rCharts nvd3中的setTemplate具有多个图的奇怪行为

时间:2015-08-10 18:49:40

标签: javascript r shiny nvd3.js rcharts

我有一个使用rCharts的nvd3库的闪亮应用程序。我在下面提供了一个完全可重现的例子:

library(shiny)
library(reshape2)
library(ggplot2)
testing <- function() {
  shinyApp(
    options = list(launch.browser = TRUE),
    ui = fluidPage(
      titlePanel("test"),
      sidebarLayout(
        sidebarPanel(
          ),
        mainPanel(
          rCharts::showOutput("plot1", "nvd3"),
          rCharts::showOutput("plot2", "nvd3")
          )
        )
    ),
    server = function(input, output) {
      output$plot1 <- rCharts::renderChart2({       
        ecm <- reshape2::melt(economics[,c('date', 'uempmed', 'psavert')], id = 'date')
        g <- nPlot(value ~ date, group = 'variable', data = ecm, type = 'lineWithFocusChart')

        #let's add this to make date handling easier
        g$xAxis( tickFormat="#!function(d) {return d3.time.format('%b %Y')(new Date( d * 86400000 ));}!#" )


        #grab template from
        #https://github.com/ramnathv/rCharts/blob/master/inst/libraries/nvd3/layouts/chart.html
        #modify to add callback on graph render
        after_script <- 
          "
                                function drawVerticalLines( opts ){

        if (!(d3.select('#' + opts.id  + ' .nvd3 .nv-focus .nv-linesWrap').select('.vertical-lines')[0][0])) {
        d3.select('#' + opts.id  + ' .nvd3 .nv-focus .nv-linesWrap').append('g')
        .attr('class', 'vertical-lines')
        d3.select('#' + opts.id).insert('h3','svg')
        .text('Test');
        }

        vertLines = d3.select('#' + opts.id  + ' .nvd3 .nv-focus .nv-linesWrap').select('.vertical-lines').selectAll('.vertical-line')
        .data(
        [ 
_
        ] )

        var vertG = vertLines.enter()
        .append('g')
        .attr('class', 'vertical-line')

        vertG.append('svg:line')
        vertG.append('text')

        vertLines.exit().remove()

        vertLines.selectAll('line')
        .attr('x1', function(d){
        return chart.xAxis.scale()(d.date/60/60/24/1000)
        })
        .attr('x2', function(d){ return chart.xAxis.scale()(d.date/60/60/24/1000) })
        .attr('y1', chart.yAxis.scale().range()[0] )
        .attr('y2', chart.yAxis.scale().range()[1] )
        .style('stroke', 'red')

        vertLines.selectAll('text')
        .text( function(d) { return d.label })
        .attr('dy', '1em')
        //x placement ; change dy above for minor adjustments but mainly
        //    change the d.date/60/60/24/1000 
        //y placement ; change 2 to where you want vertical placement
        //rotate -90 but feel free to change to what you would like
        .attr('transform', function(d){
        return  'translate(' +
        chart.xAxis.scale()(d.date/60/60/24/1000) + 
        ',' + 
        chart.yAxis.scale()(2) +
        ') rotate(-90)'
        })
        //also you can style however you would like
        //here is an example changing the font size
        .style('font-size','80%')

      }
        "

        temp <- "{ 'date' : new Date('1997-12-25'), 'label' : '83613223.8687485' },{ 'date' : new Date('1975-12-26'), 'label' : '83866338.1127959' },{ 'date' : new Date('1960-12-29'), 'label' : '85663720.9007578' },{ 'date' : new Date('1964-12-30'), 'label' : '84730972.6070318' },{ 'date' : new Date('1963-12-31'), 'label' : '82158524.7138574' }"
        replacement <- sub("_", temp, after_script)
        g$setTemplate(script = sprintf("
                                        <script type='text/javascript'>
                                        $(document).ready(function(){
                                        draw{{chartId}}(  );
                                        });
                                        function draw{{chartId}}(  ){  
                                        var opts = {{{ opts }}};
                                        var 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() {
                                        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 }}}

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

                                        chart.dispatch.brush.on('brushstart',function(){ drawVerticalLines( opts ) });
                                        chart.dispatch.brush.on(
                                        'brushend',
                                        function(){ window.setTimeout(
                                        function() {drawVerticalLines( opts )},
                                        250
                                        )}
                                        );

                                        nv.utils.windowResize(chart.update);
                                        return chart;
                                        },%s);
                                        };

                                        %s
                                        </script>
                                        "
                                ,
                                #here is where you can type your vertical line/label function
                                "function() { drawVerticalLines( opts ) }"
                                ,
                                #add the afterScript here if using with shiny
                                replacement
    ))


    g
        })

  output$plot2 <- rCharts::renderChart2({       
    ecm <- reshape2::melt(economics[,c('date', 'uempmed', 'psavert')], id = 'date')
    g <- nPlot(value ~ date, group = 'variable', data = ecm, type = 'lineWithFocusChart')

    #let's add this to make date handling easier
    g$xAxis( tickFormat="#!function(d) {return d3.time.format('%b %Y')(new Date( d * 86400000 ));}!#" )


    #grab template from
    #https://github.com/ramnathv/rCharts/blob/master/inst/libraries/nvd3/layouts/chart.html
    #modify to add callback on graph render
    after_script <- 
      "
    function drawVerticalLines( opts ){

    if (!(d3.select('#' + opts.id  + ' .nvd3 .nv-focus .nv-linesWrap').select('.vertical-lines')[0][0])) {
    d3.select('#' + opts.id  + ' .nvd3 .nv-focus .nv-linesWrap').append('g')
    .attr('class', 'vertical-lines')
    d3.select('#' + opts.id).insert('h3','svg')
    .text('Test');
    }

    vertLines = d3.select('#' + opts.id  + ' .nvd3 .nv-focus .nv-linesWrap').select('.vertical-lines').selectAll('.vertical-line')
    .data(
    [ 
    _
    ] )

    var vertG = vertLines.enter()
    .append('g')
    .attr('class', 'vertical-line')

    vertG.append('svg:line')
    vertG.append('text')

    vertLines.exit().remove()

    vertLines.selectAll('line')
    .attr('x1', function(d){
    return chart.xAxis.scale()(d.date/60/60/24/1000)
    })
    .attr('x2', function(d){ return chart.xAxis.scale()(d.date/60/60/24/1000) })
    .attr('y1', chart.yAxis.scale().range()[0] )
    .attr('y2', chart.yAxis.scale().range()[1] )
    .style('stroke', 'red')

    vertLines.selectAll('text')
    .text( function(d) { return d.label })
    .attr('dy', '1em')
    //x placement ; change dy above for minor adjustments but mainly
    //    change the d.date/60/60/24/1000 
    //y placement ; change 2 to where you want vertical placement
    //rotate -90 but feel free to change to what you would like
    .attr('transform', function(d){
    return  'translate(' +
    chart.xAxis.scale()(d.date/60/60/24/1000) + 
    ',' + 
    chart.yAxis.scale()(2) +
    ') rotate(-90)'
    })
    //also you can style however you would like
    //here is an example changing the font size
    .style('font-size','80%')

    }
    "

    temp <- "{ 'date' : new Date('1997-12-25'), 'label' : '83613223.8687485' },{ 'date' : new Date('1975-12-26'), 'label' : '83866338.1127959' },{ 'date' : new Date('1960-12-29'), 'label' : '85663720.9007578' },{ 'date' : new Date('1964-12-30'), 'label' : '84730972.6070318' },{ 'date' : new Date('1963-12-31'), 'label' : '82158524.7138574' }"
    replacement <- sub("Test", "Not a Test", sub("_", temp, after_script))
    g$setTemplate(script = sprintf("
                                   <script type='text/javascript'>
                                   $(document).ready(function(){
                                   draw{{chartId}}(  );
                                   });
                                   function draw{{chartId}}(  ){  
                                   var opts = {{{ opts }}};
                                   var 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() {
                                   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 }}}

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

                                   chart.dispatch.brush.on('brushstart',function(){ drawVerticalLines( opts ) });
                                   chart.dispatch.brush.on(
                                   'brushend',
                                   function(){ window.setTimeout(
                                   function() {drawVerticalLines( opts )},
                                   250
                                   )}
                                   );

                                   nv.utils.windowResize(chart.update);
                                   return chart;
                                   },%s);
                                   };

                                   %s
                                   </script>
                                   "
                                   ,
                                   #here is where you can type your vertical line/label function
                                   "function() { drawVerticalLines( opts ) }"
                                   ,
                                   #add the afterScript here if using with shiny
                                   replacement
    ))


    g
  })
    })
}

测试()

这几乎与来自及时报道的示例相同:http://rcharts.io/viewer/?80d85f78a5a975fa29d7#.VcidCp1Viko

但是,我在

添加了更多javascript
d3.select('#' + opts.id).insert('h3','svg')
    .text('Test');

部分,它允许我创建一个标题。然而,我的第一个情节使用标题&#34;测试&#34;,而第二个情节使用标题&#34;不是测试&#34;,但是当我绘制两个时,只有标题&#34;不是测试&#34;显示出来,它显示为两个情节的标题。此外,我还看到两个图都从一个模板(不仅仅是标题)中获取所有内容,因此,如果我为不同的图添加了不同的数据(在这种情况下为不同的日期和标签),则只显示其中一个图中指定的日期和标签会出现,它也会显示为其他情节的数据。这是非常奇怪的,因为我还打印出我正在使用的确切的javascript文本作为后记,并且它们在两个图中是不同的,但是当我在我的闪亮应用程序中实际渲染图时情况并非如此。有谁知道为什么会这样?如果需要更多细节,我很乐意提供!谢谢!

0 个答案:

没有答案