【问题标题】:using htmlwidgets::scaffoldWidget to incorporate external js libraries for a new package to go into a shiny app使用 htmlwidgets::scaffoldWidget 合并外部 js 库,以便将新包放入闪亮的应用程序
【发布时间】:2016-11-28 13:43:14
【问题描述】:

slick javascript 库 (http://kenwheeler.github.io/slick/) 给我留下了深刻的印象,并希望将其合并到我闪亮的应用程序/flexboard 页面中。

我想在 R 中使用 htmlwidgets 包并包含 slick js 库,因此首先尝试按照在线文档 (http://www.htmlwidgets.org/develop_intro.html) 中的建议创建一个包,方法是执行以下操作。 .

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

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

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

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,我提供了一个占位符 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

      }

    };
  }
});

【问题讨论】:

标签: javascript r shiny htmlwidgets


【解决方案1】:

这是一个尝试,使用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 ...

你可以得到它here并将它放在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)

【讨论】:

  • 运行ui部分时出现以下错误..Error in yaml.load(paste(readLines(input), collapse = "\n"), ...) : Scanner error: while scanning for the next token at line 11, column 5found character that cannot start any token at line 11, column 5
  • 如果您从 SO 复制粘贴 yaml,我认为新行或制表符错误,我必须手动替换它们才能正常工作。
  • 感谢您的建议....现在运行 shinyApp() 时,我现在只是蓝屏...但没有光滑的物体
  • 检查输出并查看错误得到以下slick.js:11 Uncaught ReferenceError: slick is not defined
  • 您不需要var sl = new slick(el.id); 行,现在库中有slick 对象。有空我会尝试把代码放到github上。
猜你喜欢
  • 2018-01-06
  • 2016-10-16
  • 2017-12-11
  • 2019-01-08
  • 2021-02-22
  • 2018-11-16
  • 2016-11-04
  • 2016-11-15
  • 2019-04-24
相关资源
最近更新 更多