使用htmlwidgets::scaffoldWidget来合并外部js库,以便将新包放入一个闪亮的应用程序中

using htmlwidgets::scaffoldWidget to incorporate external js libraries for a new package to go into a shiny app

本文关键字:一个 应用程序 新包放 合并 scaffoldWidget htmlwidgets 外部 js 使用      更新时间:2023-09-26

slick javascript库给我留下了深刻印象(http://kenwheeler.github.io/slick/)我想把它整合到我闪亮的应用程序/柔性版页面中。

我想在R中使用htmlwidgets包,该包包含光滑的js库,因此我已经开始尝试创建在线文档中建议的包(http://www.htmlwidgets.org/develop_intro.html),通过执行以下。。。

devtools::create("slick")              
setwd("slick")                          
htmlwidgets::scaffoldWidget("slick")

我从下载了js库https://github.com/kenwheeler/slick/archive/1.6.0.zip

并将其放入包的结构中,这样我就有了一个看起来有点像这样的文件结构。

R/
| slick.R
inst/
|-- htmlwidgets/
|   |-- slick.js
|   |-- slick.yaml
|   |-- lib/
|   |   |-- slick-1.6.0/
|   |   |   |-- slick/
|   |   |   |   |-- slick.min.js 
|   |   |   |   |-- slick.js
|   |   |   |   |-- slick.css
|   |   |   |   |-- slick-theme.css

我的slick.yaml文件如下。。。

dependencies:
  - name: slick
    version: 1.6.0
    src: htmlwidgets/lib/slick-1.6.0
    script:
        - slick/slick.min.js
        - slick/slick.js
    stylesheet: 
        - slick/slick.css
        - slick/slick-theme.css

但我真的很纠结于如何调整inst/htmlwidget/slick.js文件和R/slick.R文件,使其能够获取URL向量并在闪亮的应用程序中显示。原因是,它似乎与所提供的示例不匹配类似的输入数据概念。

为了再现并使用包中示例中提供的相同URL,我提供了一个占位符img URL的向量,我想将其用作内容。对于转盘中的每个图像。

image_vec <- paste0("http://placehold.it/350x300?text=",seq(1:9))

也许我需要用这样的东西?。。。

lapply(image_vec,function(y){div(img(src=y))})

和往常一样,如果能在这方面提供任何帮助,我们将不胜感激。

编辑

我的新slick.yaml文件如下所示。。。在@NicE的回复帖子之后。。。我是不是错过了什么?

dependencies:
  - name: jquery
    version: 3.1.0
    src: htmlwidgets/lib
    script:
      - jquery-3.1.0.min.js
  - name: slick
    version: 1.6.0
    src: htmlwidgets/lib/slick-1.6.0
    script:
        - slick/slick.min.js
        - slick/slick.js
    stylesheet: 
        - slick/slick.css
        - slick/slick-theme.css

现在我的文件结构如下:

R/
| slick.R
inst/
|-- htmlwidgets/
|   |-- slick.js
|   |-- slick.yaml
|   |-- lib/
|   |   |-- jquery-3.1.0.min.js
|   |   |-- slick-1.6.0/
|   |   |   |-- slick/
|   |   |   |   |-- slick.min.js 
|   |   |   |   |-- slick.js
|   |   |   |   |-- slick.css
|   |   |   |   |-- slick-theme.css

我的/inst/htmlwidgets/slick.js看起来像下面的

HTMLWidgets.widget({
  name: 'slick',
  type: 'output',
  factory: function(el, width, height) {
    // TODO: define shared variables for this instance
    // create new slick object witht the given id?
    var sl = new slick(el.id);

    return {
          renderValue: function(x) {
                    //add class to the div and center it
                    el.setAttribute("class",x.class);
                    el.style.margin = "auto";
                    //add images to the div
                    content='';    
                    for(var image in x.message)
                    {
                      content += '<div><img src="' + x.message[image] + '"/></div>';
                    }
                    el.innerHTML = content;
                    //initialize the slider.
                    $(document).ready(function(){
                      $("."+x.class).slick(x.options);      
                    });
      },
      resize: function(width, height) {
        // TODO: code to re-render the widget with a new size
      }
    };
  }
});

下面是一个尝试,使用htmlwidgets_0.6:

对于依赖项,yaml文件看起来是一样的,我只是在slick:之上添加了jQuery

dependencies:
  - name: jquery
    version: 3.1.0
    src: htmlwidgets/lib
    script:
      - jquery-3.1.0.min.js
  - name: slick ...

你可以在这里拿到它,然后把它放在lib文件夹中。

slick.R文件中,您需要更改slick函数的参数以添加选项,并更改x以将所有参数转发到JS代码:

slick <- function(message, class="slick_slider", options = list(), width = NULL, height = NULL) {
  # forward options using x
  x = list(
    message = message,
    class = class,
    options = options
  )
...

slick.js中,您主要需要更改renderValue以将图像/内容添加到div并显示转盘:

renderValue: function(x) {
          //add class to the div and center it
          el.setAttribute("class",x.class)
          el.style.margin = "auto";
          //add images to the div
          content='';    
          for(var image in x.message)
          {
            content += '<div><img src="' + x.message[image] + '"/></div>';
          }
          el.innerHTML = content;
          //initialize the slider.
          $(document).ready(function(){
            $("."+x.class).slick(x.options);      
          });
        }

一旦你使用devtools::install()安装了它,你就可以在shiny应用程序中使用它:

library(shiny)
library(htmlwidgets)
library(slick)
server <- function(input, output) {
  output$test_slick <- renderSlick({    
    slick(paste0("http://placehold.it/350x300?text=",1:9),
          options=list(dots=TRUE,autoplay=TRUE))
})
}
ui <- fluidPage(
  tags$style(HTML("body {background-color: #2682d5}")),
  slickOutput('test_slick',width="350px",height="300px")
)
shinyApp(ui = ui, server = server)
相关文章: