将数据拖放到闪亮的应用程序中
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/
【讨论】:
以上是关于将数据拖放到闪亮的应用程序中的主要内容,如果未能解决你的问题,请参考以下文章