Динамическая окраска клеточного фона в rhandsontable - PullRequest
0 голосов
/ 19 декабря 2018

Мой вопрос немного сложнее, чем вопрос здесь .Давайте предположим, что я хочу разработать следующую игру как приложение Shiny.

У меня есть фрейм данных 3 x 3, содержащий числа от 1 до 9 в случайном порядке.

set.seed(123)
df_correct <- as.data.frame(matrix(sample(9), nrow = 3, ncol = 3))
df_correct

  V1 V2 V3
1  3  6  2
2  7  5  8
3  9  1  4

Когдаприложение Shiny загружается, пользователю предоставляется пустая кнопка 3 x 3 rhandsontable, а также кнопка «Отправить».Цель игры состоит в том, чтобы успешно найти число, «спрятанное за каждой ячейкой».

То, чего я пытаюсь добиться, - это динамическое цветовое кодирование ячеек на основе введенных пользователем данных при нажатии кнопки «Отправить» (красный = неправильно, зеленый = правильно, светло-серый = пусто).Несмотря на то, что я не знаю, как кодировать в Javascript, в этом руководстве по пакету rhandsontable приведены примеры кода, которые относительно легко понять и настроить.Я продолжаю в 3 этапа:

  1. Идентификация пустых ячеек

  2. Идентификация ячеек с правильными пользовательскими вводами

  3. Определение ячеек с неправильными пользовательскими вводами

Каждый из этих шагов приводит к R объекту, содержащему индексы (то есть номер строки и столбца).Я не знаю, как передать эту информацию в функцию hot_cols() (точнее, в аргумент renderer, который принимает код Javascript).Ваша помощь очень ценится.

library(shiny)
library(rhandsontable)
library(magrittr)

ui <- fluidPage(

   titlePanel("Simple game"),

   rHandsontableOutput("table"),

   actionButton("button", "Submit")

)

server <- function(input, output) {

    tables <- reactiveValues(
        df_correct = {
            set.seed(123)
            as.data.frame(matrix(sample(9), nrow = 3, ncol = 3))
        },
        df_user = rhandsontable(
            data = as.data.frame(matrix(NA_integer_, nrow = 3, ncol = 3)
        ))
    )

    output$table <- renderRHandsontable({
        tables$df_user
    })

    observeEvent(input$button, {

        df <- hot_to_r(input$table)

        index_empty <- which(is.na(df), arr.ind = TRUE)
        index_correct <- which(df == tables$df_correct, arr.ind = TRUE)
        index_wrong <- which(df != tables$df_correct, arr.ind = TRUE)

        tables$df_user <- 
            df %>%
            rhandsontable() %>%
            hot_cols(renderer = "")
    })
}

shinyApp(ui = ui, server = server)

1 Ответ

0 голосов
/ 29 января 2019

Может быть, я срезаю углы, но это может помочь.Предположим, игрок введет 1 во все ячейки, поэтому он угадает по крайней мере одну ячейку.Вы хотите покрасить эту ячейку в зеленый.Это то, что вы делаете.Передайте два параметра в rhandsontable function rows_correct и cols_correct index (-1, потому что у javascript есть индекс, начинающийся с 0).

Затем в рендере вы переходите ячейка за ячейкой и окрашивает фон в зеленый, если ячейка соответствует правильному индексу ячейки.

Надеюсь, это поможет

enter image description here

library(shiny)
library(rhandsontable)
library(magrittr)

ui <- fluidPage(

    titlePanel("Simple game"),

    rHandsontableOutput("table"),

    actionButton("button", "Submit")

)

server <- function(input, output) {

    tables <- reactiveValues(
        df_correct = {
            set.seed(123)
            as.data.frame(matrix(sample(9), nrow = 3, ncol = 3))
        },
        df_user = rhandsontable(
            data = as.data.frame(matrix(NA_integer_, nrow = 3, ncol = 3)
            ))
    )

    output$table <- renderRHandsontable({
        tables$df_user
    })

    observeEvent(input$button, {

        df <- hot_to_r(input$table)

        index_empty <- which(is.na(df), arr.ind = TRUE)
        index_correct <- which(df == tables$df_correct, arr.ind = TRUE)
        index_wrong <- which(df != tables$df_correct, arr.ind = TRUE)

        tables$df_user <- 
            df %>%
            rhandsontable(rows_correct = index_correct[1] - 1, cols_correct = index_correct[2] - 1) %>%
            hot_cols(renderer = "
                function (instance, td, row, col, prop, value, cellProperties) {
                    Handsontable.renderers.TextRenderer.apply(this, arguments);
                    if (instance.params) {
                        col_to_highlight = instance.params.cols_correct
                        col_to_highlight = col_to_highlight instanceof Array ? col_to_highlight : [col_to_highlight]

                        row_to_highlight = instance.params.rows_correct
                        row_to_highlight = row_to_highlight instanceof Array ? row_to_highlight : [row_to_highlight]

                        for (i = 0; i < col_to_highlight.length; i++) { 
                            if (col_to_highlight[i] == col && row_to_highlight[i] == row) {
                                td.style.background = 'green';
                            }
                        }
                    }
                }")
    })
}

shinyApp(ui = ui, server = server)
...