R shinydashboard: указание аргумента ширины стиля div в процентах, чтобы соответствовать изменяемому графику JS - PullRequest
0 голосов
/ 05 января 2019

Задача : используя R и shinydashboard, внедрить пользовательский график, созданный Javascript, в тело панели управления. Укажите ширину графика в процентах , чтобы график занимал свой столбец (или поле) независимо от настроек экрана зрителя.

Настройка : R (3.5.2), shiny (1.2.0) и shinydashboard (0.7.1). Код панели инструментов (упрощенный воспроизводимый пример) выглядит следующим образом:

library(shiny)
library(shinydashboard)

ui <- fluidPage(

dashboardPage(
    dashboardHeader(),
    dashboardSidebar(
        sidebarMenu(
            menuItem("Main", tabName = "tab1", icon = icon("dashboard")
            )
        )
    ),
    dashboardBody(
        tabItems(
            tabItem("tab1",
                    column(width = 12, 
                           tags$div(id = "main", style = "width: 100%; height: 400px"),
                           tags$script(src = "http://cdnjs.cloudflare.com/ajax/libs/echarts/4.1.0/echarts.min.js"),
                           tags$script(src = "myscript.js")
                    )
            )
        )
    )
 )
)


server <- function(input, output) {

}

# Run the application 
shinyApp(ui = ui, server = server)

Соответствующий файл Javascript myscript.js, который должен быть помещен в подпапку www относительно самого файла приложения, выглядит следующим образом:

// JS Plot with Echarts 4

option = {
    xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },
    yAxis: {
        type: 'value'
    },
    series: [{
        data: [820, 932, 901, 934, 1290, 1330, 1320],
        type: 'line'
    }]
};

var myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);

Проблема : по какой-то причине спецификация 100% преобразуется в 100px в конечном результате, что приводит к следующему выводу:

screenshot_plot

Осматривая график, я вижу, что div#main действительно имеет ширину 100%, но затем он содержит другой, меньший div, который уже 100px широкий:

screenshot2

Мне может показаться, что виноваты либо tabItem, либо tabItems, потому что без их использования результат верен, и меньший посредник div правильно получает ширину от своего родителя:

screenshot3

Для полноты код рабочей версии (без tabItem(s)) такой:

library(shiny)
library(shinydashboard)

ui <- fluidPage(

    dashboardPage(
        dashboardHeader(),
        dashboardSidebar(),
        dashboardBody(
            column(width = 12, 
                   tags$div(id = "main", style = "width: 100%; height: 400px"),
                   tags$script(src = "http://cdnjs.cloudflare.com/ajax/libs/echarts/4.1.0/echarts.min.js"),
                   tags$script(src = "myscript.js")
            )
        )
    )
)

server <- function(input, output) {

}

# Run the application 
shinyApp(ui = ui, server = server)

Как видите, код практически идентичен, за исключением функций-нарушителей. Однако я не понимаю, как Shinydashboard может работать без этих функций, поскольку они структурируют все приложение. Есть ли какой-нибудь способ обойти это? Благодарю.

1 Ответ

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

Очень интересно, но да, это похоже на ошибку / функцию в tabItems.

Устанавливая ширину с помощью css, он просто растягивает график, так что он не работает. Я нашел те маленькие обходные пути, которые изменяют размер графика при изменении размера окна.

Вариант 1:
Для первоначального изменения размера окна я использую shinyjs, чтобы при запуске свернуть боковую панель, чтобы изменить размер графика. Это запустит приложение со свернутой боковой панелью.

Если вы хотите, чтобы боковая панель не была свернута при запуске, вам нужно добавить collapsed = TRUE в dashboardSidebar и изменить addClass на сервере на removeClass.

Вариант 2:
Если вы не хотите использовать shinyjs, вы можете добавить небольшой фрагмент JS, например:

jss <- HTML("
$(document).on('shiny:connected', function() {
  $('.sidebar-toggle').click();
});
")

с

tags$head(tags$script(jss))

в dashboardBody и collapsed = TRUE в dashboardSidebar.

app.R

ui <- fluidPage(

  dashboardPage(
    dashboardHeader(),
    dashboardSidebar(
      sidebarMenu(
        menuItem("Main", tabName = "tab1", icon = icon("dashboard")
        )
      )
    ),
    dashboardBody(
      useShinyjs(),
      tabItems(
        tabItem("tab1",
                column(width = 12,
                       tags$div(id = "main", style = "width: 100%; height: 400px"),
                       tags$script(src = "http://cdnjs.cloudflare.com/ajax/libs/echarts/4.1.0/echarts.min.js"),
                       tags$script(src = "myscript.js")
                )
        )
      )
    )
  )
)


server <- function(input, output) {
  addClass(selector = "body", class = "sidebar-collapse")
}

# Run the application
shinyApp(ui = ui, server = server)

myscript.js

option = {
    xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },
    yAxis: {
        type: 'value'
    },
    series: [{
        data: [820, 932, 901, 934, 1290, 1330, 1320],
        type: 'line'
    }]
};

var myChart = echarts.init(document.getElementById('main'), width='100%');
myChart.setOption(option);


$(window).on('resize', function(){
    if(myChart != null && myChart != undefined){
        myChart.resize();
    }
});
...