将数据拖放到闪亮的应用程序中

Posted

技术标签:

【中文标题】将数据拖放到闪亮的应用程序中【英文标题】:Drag and drop data into shiny app 【发布时间】:2016-07-06 15:26:43 【问题描述】:

如何?我可以拖放到一个区域并使用 javascript 读取它,但我不确定如何让闪亮注册它,以便我可以在服务器上处理它。这是一个示例设置 - 它有点长 b/c 我认为没有内置的 javascript 函数来处理拖放操作。

当前运行并拖入数据集“dat.csv”时应如下所示。目标是将已拖放的数据注册到input中的变量中,以便对其进行处理在 R。

ui.R

library(shiny)

ui <- shinyUI(
  fluidPage(
    tags$head(tags$link(rel="stylesheet", href="css/styles.css", type="text/css"),
      tags$script(src="getdata.js")),
    h3(id="data-title", "Drop Datasets"),
    div(class="col-xs-12", id="drop-area", ondragover="dragOver(event)", 
      ondrop="dropData(event)"),
    tableOutput('table'),  # doesn't do anything now

    ## debug
    div(class="col-xs-12",
      tags$hr(style="border:1px solid grey;width:150%"),
      tags$button(id="showData", "Show", class="btn btn-info", 
        onclick="printData('dat.csv')")),
    div(id="data-output")  # print the data
  )
)

服务器.R

## Make a sample dataset
# write.csv(data.frame(a=1:10, b=letters[1:10]), "dat.csv", row.names=FALSE)
server <- function(input, output, session) 
  output$table <- renderTable(input$data)  # this variable doesn't exist

www/getdata.js

var datasets = ;
var dragOver = function(e)  e.preventDefault(); ;
var dropData = function(e) 
    e.preventDefault();
    handleDrop(e.dataTransfer.files);
;
var handleDrop = function(files) 
    for (var i = 0, f; f = files[i]; i++) 
    var reader = new FileReader();

    reader.onload = (function(file) 
        return function(e) 
        datasets[file.name.toLowerCase()] = e.target.result;
        var div = document.createElement("div");
        var src = "https://cdn0.iconfinder.com/data/icons/office/512/e42-512.png";
        div.id = "datasets";
        div.innerhtml = [
            "<img class='thumb' src='", src, "' title='", encodeURI(file.name),
            "'/>", "<br>", file.name, "<br>"].join('');
        document.getElementById("drop-area").appendChild(div);
        ;
    )(f);
    reader.readAsText(f);
    
;
// debug
var printData = function(data) 
    var div = document.createElement("div");
    div.innerHTML = datasets[data];
    document.getElementById("data-output").appendChild(div);
;

www/css/styles.css

#data-title 
    text-align:center;


#drop-area 
    background-color:#BCED91;
    border:2px solid #46523C;
    border-radius:25px;
    height:90px;
    overflow:auto;
    padding:12px;


#drop-area #datasets 
    display:inline-block;
    font-size:small;
    margin-right:8px;
    text-align:center;
    vertical-align:top;


.thumb 
    height:45px;

【问题讨论】:

【参考方案1】:

只需要在js文件中加入下面一行

datasets[file.name.toLowerCase()] = e.target.result;
# Add this line
Shiny.onInputChange("mydata", datasets);

然后您可以在服务器代码中使用input$mydata。请注意,它是一个列表,因此您需要遍历它(如果您打算删除多个文件,这也是必要的)。

完整代码(同样显示多个csv文件,注意如果你drop多个同名文件,只会显示一个):

getdata.js(如上加一行)

styles.css(不变)

ui.R

library(shiny)

ui <- shinyUI(
  fluidPage(
    tags$head(tags$link(rel="stylesheet", href="css/styles.css", type="text/css"),
              tags$script(src="getdata.js")),
    sidebarLayout(
      sidebarPanel(
        h3(id="data-title", "Drop Datasets"),
        div(class="col-xs-12", id="drop-area", ondragover="dragOver(event)", 
            ondrop="dropData(event)")
      ),
      mainPanel(
        uiOutput('tables')
      )
    )

  )
)

服务器.R

server <- function(input, output, session) 
  observeEvent(input$mydata, 
    len = length(input$mydata)
    output$tables <- renderUI(
      table_list <- lapply(1:len, function(i) 
        tableName <- names(input$mydata)[[i]]
        tableOutput(tableName)
      )
      do.call(tagList, table_list)
    )
    for (name in names(input$mydata)) 
      output[[name]] <- renderTable(read.csv(text=input$mydata[[name]]))
    
  )

【讨论】:

我花了大约一个小时试图让它工作,然后我意识到这是因为我有shiny.onInputChange( ),小写s 除了文本文件之外是否可以这样做?我已经用 .xlsx 试过了,但不幸的是它不起作用。谢谢 @AlexNevsky 您需要修改原始问题中的 www/getdata.js 文件以读取 xlsx 文件。这里有一个代码sn-p github.com/SheetJS/js-xlsx(靠近页面中间,“HTML5 drag-and-drop using readAsBinaryString”)【参考方案2】:

截至 2017 年 8 月,此功能现在由 fileInput 直接从 shiny 提供!多么美妙。

这是宣布该功能的博文https://blog.rstudio.com/2017/08/15/shiny-1-0-4/

【讨论】:

以上是关于将数据拖放到闪亮的应用程序中的主要内容,如果未能解决你的问题,请参考以下文章

Kendo Grid:将单元格中的单元格数据拖放到另一个网格中

为啥我不能将文件拖放到 Qt 示例拖放示例中?

将承诺的文件拖放到 Dock 中的应用程序图标上

ActionScript 3 AIR将文件拖放到应用程序中

拖放到桌面/资源管理器

Mac 应用程序 - 将文件拖放到菜单栏应用程序中