R/Shiny中直接从R传递参数的JavaScript方法

huangapple go评论132阅读模式
英文:

R/Shiny Javascript passing arguments directly from R

问题

我有一个使用rhandsontable的Shiny App,我希望在修改值后更改单元格的颜色。
基本上,我需要对Kat在这里提供的解决方案进行一些修改:https://stackoverflow.com/questions/73337727/in-shiny-rhandsontable-afterchange-change-multiple-cell-backgrounds-at-once/73347195#73347195。

我想要的是,根据发生更改的行的不同,有不同的颜色。我在下面实现了一个示例,在前5行中颜色是蓝色,在其余行中是粉色。但我需要帮助的地方是,如何通过R动态地将参数传递给javascript中的数组?
(因为我每次都需要不同的行,并且我希望从R中获取所需的行索引,例如通过which,然后在R中有一个向量,应该自动传递给下面的javascript函数,而不是现在的if (elem['rowind'] in [0,1,2,4])

  1. library(shiny)
  2. library(rhandsontable)
  3. change_hook <- "function(el,x) {
  4. hot = this.hot;
  5. cellchngs = [];
  6. afterChange = function(changes, source) {
  7. $.each(changes, function (index, elem) {
  8. change = elem; /* gather the row, col, old, new values */
  9. if(change[2] !== change[3]) { /* if old isn't the same as new */
  10. cellchg = ({rowind: change[0], colind: change[1]});
  11. cellchngs.push(cellchg); /* add row and column indicies to array */
  12. }
  13. });
  14. $.each(cellchngs, function(ind, elem) {
  15. td = hot.getCell(elem['rowind'], elem['colind']); /* get the html element */
  16. if (elem['rowind'] in [0,1,2,4]){
  17. td.style.background = 'cyan'; /* set background color */
  18. }
  19. else {
  20. td.style.background = 'pink'; /* set background color */
  21. }
  22. });
  23. }
  24. hot.addHook('afterChange', afterChange); /* add event to table */
  25. }"
  26. ui <- div(actionButton(inputId = "reset_button",label = "Reset")
  27. ,rHandsontableOutput(outputId="mtcars"))
  28. server <- function(input, output, session) {
  29. reset <- reactiveVal(0)
  30. output$mtcars <- renderRHandsontable({
  31. r = reset()
  32. rht = rhandsontable(mtcars,reset=r,stretchH="all",height=300)
  33. reset(0)
  34. htmlwidgets::onRender(rht,change_hook)
  35. })
  36. observeEvent(input$reset_button,
  37. {
  38. reset(1)
  39. })
  40. }
  41. shinyApp(ui, server)
英文:

I have a Shiny App with rhandsontable where I want the cell colors to be changed after a value is modified
Basically I needed some modification of Kat's solution implemented here https://stackoverflow.com/questions/73337727/in-shiny-rhandsontable-afterchange-change-multiple-cell-backgrounds-at-once/73347195#73347195.

what I want, are different colors based on the row where the change has occurred. I have implemented an example below where in the first 5 rows the color is blue and pink in the rest, but where I would need help, how can I pass a paramter for the array in javascript dynamically via R?
(Because I need different rows everytime and I would like to get the desired row indices from R for example via ?which, then have a vector in R which should ideally automatically be passed to the javascript function below instead of the if (elem[&#39;rowind&#39;] in [0,1,2,4]) as it is now)

  1. library(shiny)
  2. library(rhandsontable)
  3. change_hook &lt;- &quot;function(el,x) {
  4. hot = this.hot;
  5. cellchngs = [];
  6. afterChange = function(changes, source) {
  7. $.each(changes, function (index, elem) {
  8. change = elem; /* gather the row, col, old, new values */
  9. if(change[2] !== change[3]) { /* if old isn&#39;t the same as new */
  10. cellchg = ({rowind: change[0], colind: change[1]});
  11. cellchngs.push(cellchg); /* add row and column indicies to array */
  12. }
  13. });
  14. $.each(cellchngs, function(ind, elem) {
  15. td = hot.getCell(elem[&#39;rowind&#39;], elem[&#39;colind&#39;]); /* get the html element */
  16. if (elem[&#39;rowind&#39;] in [0,1,2,4]){
  17. td.style.background = &#39;cyan&#39;; /* set background color */
  18. }
  19. else {
  20. td.style.background = &#39;pink&#39;; /* set background color */
  21. }
  22. });
  23. }
  24. hot.addHook(&#39;afterChange&#39;, afterChange); /* add event to table */
  25. }&quot;
  26. ui &lt;- div(actionButton(inputId = &quot;reset_button&quot;,label = &quot;Reset&quot;)
  27. ,rHandsontableOutput(outputId=&quot;mtcars&quot;))
  28. server &lt;- function(input, output, session) {
  29. reset &lt;- reactiveVal(0)
  30. output$mtcars &lt;- renderRHandsontable({
  31. r = reset()
  32. rht = rhandsontable(mtcars,reset=r,stretchH=&quot;all&quot;,height=300)
  33. reset(0)
  34. htmlwidgets::onRender(rht,change_hook)
  35. })
  36. observeEvent(input$reset_button,
  37. {
  38. reset(1)
  39. })
  40. }
  41. shinyApp(ui, server)

答案1

得分: 2

我会使用onRenderdata参数(参见?htmlwidgets::onRender)。它允许在JavaScript函数中使用第三个参数:即data参数,它是一个转换为JavaScript的R对象。

  1. change_hook <- "function(el, x, v) {
  2. hot = this.hot;
  3. cellchngs = [];
  4. afterChange = function(changes, source) {
  5. $.each(changes, function (index, elem) {
  6. change = elem; /* 收集行、列、旧值、新值 */
  7. if(change[2] !== change[3]) { /* 如果旧值与新值不同 */
  8. cellchg = ({rowind: change[0], colind: change[1]});
  9. cellchngs.push(cellchg); /* 将行和列索引添加到数组中 */
  10. }
  11. });
  12. $.each(cellchngs, function(ind, elem) {
  13. td = hot.getCell(elem['rowind'], elem['colind']); /* 获取HTML元素 */
  14. if(v.indexOf(elem['rowind']) > -1) {
  15. td.style.background = 'cyan'; /* 设置背景颜色 */
  16. } else {
  17. td.style.background = 'pink'; /* 设置背景颜色 */
  18. }
  19. });
  20. }
  21. hot.addHook('afterChange', afterChange); /* 将事件添加到表格中 */
  22. }"

然后执行:

  1. htmlwidgets::onRender(rht, change_hook, c(0, 1, 2, 4))
英文:

I would use the data argument of onRender (see ?htmlwidgets::onRender). It allows to use a third argument in the JavaScript function: namely this data argument, a R object, converted to JavaScript.

  1. change_hook &lt;- &quot;function(el, x, v) {
  2. hot = this.hot;
  3. cellchngs = [];
  4. afterChange = function(changes, source) {
  5. $.each(changes, function (index, elem) {
  6. change = elem; /* gather the row, col, old, new values */
  7. if(change[2] !== change[3]) { /* if old isn&#39;t the same as new */
  8. cellchg = ({rowind: change[0], colind: change[1]});
  9. cellchngs.push(cellchg); /* add row and column indicies to array */
  10. }
  11. });
  12. $.each(cellchngs, function(ind, elem) {
  13. td = hot.getCell(elem[&#39;rowind&#39;], elem[&#39;colind&#39;]); /* get the html element */
  14. if(v.indexOf(elem[&#39;rowind&#39;]) &gt; -1) {
  15. td.style.background = &#39;cyan&#39;; /* set background color */
  16. } else {
  17. td.style.background = &#39;pink&#39;; /* set background color */
  18. }
  19. });
  20. }
  21. hot.addHook(&#39;afterChange&#39;, afterChange); /* add event to table */
  22. }&quot;

and then:

  1. htmlwidgets::onRender(rht, change_hook, c(0, 1, 2, 4))

huangapple
  • 本文由 发表于 2023年7月31日 18:30:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76802740.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定