【问题标题】:Plots in Child Rows of an R/Shiny DT::DataTableR/Shiny DT::DataTable 的子行中的绘图
【发布时间】:2022-02-04 12:48:20
【问题描述】:

我一点也不精通 JS,所以请原谅我在下面这个简单的闪亮应用示例中的薄弱努力。我只是想在子行中呈现一个简单的 highcharts 图,只是为了确定这是否可以做到。

该示例在 DevTools 控制台中给出了这个错误: "未捕获的错误:Highcharts 错误 #13:www.highcharts.com/errors/13/"

如果有人可以就此示例提出建议或指出更有效的替代方案,将不胜感激(例如,能够使用 ggplot 代替仍然很棒)。

library(DT)
library(shiny)

ui <-shinyUI(fluidPage(
 tags$head(tags$script(src="https://code.highcharts.com/highcharts.js")),
 tags$body(
 HTML("<script type='text/javascript'>document.addEventListener('DOMContentLoaded', function () {
        const chart = Highcharts.chart('container', {
            chart: {
                type: 'bar'
            },
            title: {
                text: 'Fruit Consumption'
            },
            xAxis: {
                categories: ['Apples', 'Bananas', 'Oranges']
            },
            yAxis: {
                title: {
                    text: 'Fruit eaten'
                }
            },
            series: [{
                name: 'Jane',
                data: [1, 0, 4]
            }, {
                name: 'John',
                data: [5, 7, 3]
            }]
        });
    });
</script>")),
DTOutput("tab")))

server <- shinyServer(function(input, output, session) {

output$tab <- renderDT({datatable(
  cbind(' ' = '&oplus;', mtcars), escape = FALSE,
  options = list(
    columnDefs = list(
      list(visible = FALSE, targets = c(0, 2, 3)),
      list(orderable = FALSE, className = 'details-control', targets = 1)
    )
  ),
  callback = JS("
  table.column(1).nodes().to$().css({cursor: 'pointer'});

  table.on('click', 'td.details-control', function() {
    var td = $(this), row = table.row(td.closest('tr'));
    if (row.child.isShown()) {
      row.child.hide();
      td.html('&oplus;');
    } else {
      row.child('<div id=\"container\" style=\"width:100%;height:600px;\"></div>').show();
      td.html('&CircleMinus;');
    }
  });"
  ))
})


})

shiny::shinyApp(ui,server)

【问题讨论】:

    标签: javascript shiny highcharts parent-child


    【解决方案1】:

    Highcharts error #13 表示未找到渲染 div。

    在使用创建脚本之前,您需要为图表放置一个容器元素。例如:

    <div id="container"></div>
    
    <script type='text/javascript'>
        document.addEventListener('DOMContentLoaded', function() {
            const chart = Highcharts.chart('container', {
                ...
            });
        });
    
    </script>
    

    现场演示: http://jsfiddle.net/BlackLabel/o30aL8ev/

    【讨论】:

      【解决方案2】:

      Here's what the app looks like to better illustrate what I am trying to do

      直接渲染 highchart 没有问题,但我想弄清楚如何将该图表(或任何类型的图,如 ggplot、heatmaps 等)渲染为数据表中的子行。

      library(DT)
      library(shiny)
      
      ui <-shinyUI(fluidPage(
        tags$head(tags$script(src="https://code.highcharts.com/highcharts.js")),
        tags$body(
          HTML("<script type='text/javascript'>document.addEventListener('DOMContentLoaded', function () {
              const chart = Highcharts.chart('container', {
                  chart: {
                      type: 'bar'
                  },
                  title: {
                      text: 'Fruit Consumption'
                  },
                  xAxis: {
                      categories: ['Apples', 'Bananas', 'Oranges']
                  },
                  yAxis: {
                      title: {
                          text: 'Fruit eaten'
                      }
                  },
                  series: [{
                      name: 'Jane',
                      data: [1, 0, 4]
                  }, {
                      name: 'John',
                      data: [5, 7, 3]
                  }]
              });
          });
      </script>")),
        div(id="container"),
        DTOutput("tab")))
      
      server <- shinyServer(function(input, output, session) {
        
        
       
        output$tab <- renderDT({datatable(
          cbind(' ' = '&oplus;', mtcars), escape = FALSE,
          options = list(
            columnDefs = list(
              list(visible = FALSE, targets = c(0, 2, 3)),
              list(orderable = FALSE, className = 'details-control', targets = 1)
            )
          ),
          callback = JS("
        table.column(1).nodes().to$().css({cursor: 'pointer'});
      
        table.on('click', 'td.details-control', function() {
          var td = $(this), row = table.row(td.closest('tr'));
          if (row.child.isShown()) {
            row.child.hide();
            td.html('&oplus;');
          } else {
            row.child('<div id=#container style=\"width:100%;height:200px;\">I can put text here, but charts would be awesome</div>').show();
            td.html('&CircleMinus;');
          }
        });"
          ))
        })
        
        
      })
      
      shiny::shinyApp(ui,server)
      
      
      
      

      【讨论】:

      • 我还应该提到,理想情况下,这些子行图表将根据数据表中的实际数据构建(与我的图表数据不相关的示例不同)。
      【解决方案3】:

      对于任何感兴趣的人来说,reactable 看起来是将图表放入数据表子行的最直接的方法。请参阅下面的代码和结果:

      library(reactable)
      library(highcharter)
      
      reactable(iris[1:20, ], details =function(index) {
        VECTOR=iris[1:20,] %>% dplyr::filter(Species==as.vector(unique(iris[index,5]))) %>% select(Sepal.Length) %>% as.data.frame() %>% .[,1] 
        htmltools::div(style = "width: 1000",
                       highchart(type = "stock") %>% 
                         hc_add_series(VECTOR, type = "line"),
      # sparkline(VECTOR, type = "bar", chartRangeMin = 0, chartRangeMax = max(6),width = 1000,height = 300),
        h3("Yahoo!")
       
        )
      })
      

      What it looks like

      【讨论】:

        猜你喜欢
        • 2019-02-24
        • 2020-12-15
        • 2020-07-12
        • 2019-01-20
        • 2017-01-21
        • 1970-01-01
        • 2020-11-08
        • 2020-03-02
        相关资源
        最近更新 更多