如何在 flexdashboard 中结合行列布局?

Posted

技术标签:

【中文标题】如何在 flexdashboard 中结合行列布局?【英文标题】:How to combine row and column layout in flexdashboard? 【发布时间】:2016-07-26 21:02:56 【问题描述】:

对于一个新项目,我想尝试新的 flexdasboard 包。我正在考虑以某种方式组合列和行方向的布局。

我想到的布局是这样的:

如果我更改此代码:

---
title: "Focal Chart (Left)"
output: flexdashboard::flex_dashboard
---

Column data-width=600
-------------------------------------

### Chart 1

```r
```

Column data-width=400
-------------------------------------

### Chart 2

```r
```   

### Chart 3

```r
```

进入这个:

---
title: "Focal Chart (Left)"
output: flexdashboard::flex_dashboard
---

Column data-width=600
-------------------------------------

### Chart 1

```r
```

Column data-width=400
-------------------------------------

Row data-width=400
-------------------------------------

### Chart 2

```r
```   

### Chart 3

```r
```   

Row data-width=400
-------------------------------------

### Chart 4

```r
```

(当然)这不起作用,但我还没有找到正确的方法。有人有想法吗?

【问题讨论】:

【参考方案1】:

这似乎无法使用基本的行和列来实现,但可以通过使用侧边栏来保存左侧面板的内容来实现。与其他面板相比,这将更改左侧面板的格式,但是可以通过编辑 css 来调整其外观。请注意,您可以使用 data-width 选项更改侧栏的宽度,例如.sidebar data-width=300

---
title: "Focal Chart"
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
---

Column .sidebar data-width=500
-------------------------------------
### Chart 1
```r
```

Row data-height=350
-------------------------------------
### Chart 2
```r
```

### Chart 3
```r
```   

Row data-height=650
-------------------------------------
### Chart 4
```r
```

这给了...

然后可以根据自己的喜好编辑侧边栏的外观。例如:

    将侧面板的背景颜色更改为白色(如果您希望它与其他面板匹配), 将顶部边缘与其他面板对齐,然后 添加左侧和底部边框以匹配其他面板:

将 .section.sidebar 的 css 样式表编辑为

.section.sidebar 
  top: 61px;
  border-bottom: 10px solid #ececec;
  border-left: 10px solid #ececec;
  background-color: rgba(255, 255, 255, 1);

要更改填充,请使用 flexdashboard markdown 中的 data-padding 选项:

Column .sidebar data-width=500 data-padding=10

现在,它看起来像这样:

【讨论】:

有什么方法可以保留侧边栏布局控件并拥有您提供的布局? @TylerRinker 的意思是您想将闪亮的控件放在看起来像面板的侧边栏中,或者您想在此布局中添加第二个侧边栏(看起来更像侧边栏)? 来自文档“将 .sidebar 属性添加到列中,这表明它应该与左侧齐平布置...无论在哪里定义侧边栏,它们总是出现在左侧在文档流中。”,这就解释了为什么添加多个侧边栏总是会导致它们相互重叠。 作为参考,我想记录下边栏中的 data-width=500 对我不起作用,但 style='max-width: 500px;' 对我起作用。【参考方案2】:

您真正需要的是fillColfillRow 函数。看看这个:http://shiny.rstudio.com/articles/gadget-ui.html#fillrowfillcol

【讨论】:

可以在 Flexdashboard 中使用 fillColfillRow 吗? 是的,您可以在 Flexdashboard 中使用它。 @sanyi14ka 你能举个例子吗? 我可以确认可以使用fillCol/fillRow。我在评论中的字符数有限,所以我无法适应可重现的代码,但这是我尝试过的一个稻草人:`fillRow(fillCol(renderPlotly(...plot在这里... )), fillCol(renderPlotly(... plot 在这里...), renderGauge(... gauge 在这里...)))`【参考方案3】:

我使用 fillCol 在 RStudio 的 Shiny+flex 站点中找到的内容组成了这个 flexdashboard 示例:

---
title: "Fill Layout"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
runtime: shiny
---

# Info .sidebar data-width=350

When you mix multiple Shiny inputs and/or outputs within a flexdashboard panel it’s good practice to have them fill the bounds of their container in the same way that other flexdashboard components like plots and htmlwidgets do. This is possible using the Shiny `fillRow` and `fillCol` layout functions.

For those familiar with Shiny here are further details on how this example works:

1. The container is laid out using the `fillCol` function, which establishes a single column layout with flexible row heights.

2. Flexible height behavior is defined via `flex = c(NA, 1)`. The `NA` applies to the first component (the input panel) and says to not give it flexible height (i.e. allow it to occupy it’s natural height). The `1` applies to the second component (the plot) and says that it should have flexible height (i.e. occupy all remaining height in the container).

3. The call to `plotOutput` includes `height = "100%"` to ensure that the plot takes advantage of the height allocated to it by the `fillCol` flexible layout.

4. Finally, note that unlike the simpler layout examples above this examples uses an explicit  `plotOutput` / `renderPlot` pairing rather than just a standalone `renderPlot`. This is so that the plot can be included in a more sophisticated layout scheme (i.e. one more like traditional ui.R layout).

# Use fillCol

```r
fillCol(height = 600, flex = c(NA, 1), 
  inputPanel(
    selectInput("region", "Region:", choices = colnames(WorldPhones))
  ),
  plotOutput("phonePlot", height = "100%")
)

output$phonePlot <- renderPlot(
  barplot(WorldPhones[,input$region]*1000, 
          ylab = "Number of Telephones", xlab = "Year")
)
```

【讨论】:

【参考方案4】:

另一种方法是使用来自闪亮的绝对面板。与其尝试找到适合屏幕上所有片段的网格排列,不如使用带有折叠按钮的绝对面板来选择性地选择在给定时间出现的框。这允许用户选择他们想要呈现的图和信息。这个想法是从 superzip 应用程序https://shiny.rstudio.com/gallery/superzip-example.html 演变而来的,但在 flexdashboard 中运行良好。

在下面的示例中,可以在页面加载时显示或隐藏绘图。单击按钮使它们出现或消失。这在将传单与地块混合时非常有用,以避免用地块淹没地图(与以前一样,由于溺水问题,地块受到限制)。

---
  title: "Demo"
  output:
    flexdashboard::flex_dashboard:
      orientation: columns
      vertical_layout: fill
  ---


  ```r setup, include=FALSE
  library(flexdashboard)
  library(rmarkdown)
  library(plotly)
  library(shiny)

  ```

  Column data-width=400
  --------------------------------
  ### Planet Earth

  ```r

  library(leaflet)
  m = leaflet() %>% addTiles()
  m  # a map with the default OSM tile layer


  ```


  ```r
  #plot setup
  mtcars$am[which(mtcars$am == 0)] <- 'Automatic'
  mtcars$am[which(mtcars$am == 1)] <- 'Manual'
  mtcars$am <- as.factor(mtcars$am)

  p <- plot_ly(mtcars, x = ~wt, y = ~hp, z = ~qsec, color = ~am, colors = c('#BF382A', '#0C4B8E')) %>%
    add_markers() %>%
    layout(scene = list(xaxis = list(title = 'Weight'),
                       yaxis = list(title = 'Gross horsepower'),
                       zaxis = list(title = '1/4 mile time')))


  set.seed(100)
  d <- diamonds[sample(nrow(diamonds), 1000), ]


  ##########################
  absolutePanel(id = "controls", class = "panel panel-default", fixed = TRUE,
                draggable = TRUE, top = 70, left = "auto", right = 20, bottom = "auto",
                width = '30%', height = 'auto', 
                style = "overflow-y:scroll; max-height: 1000px; opacity: 0.9; style = z-index: 400",

              h4(strong("Plot Explorer")),

      HTML('<button data-toggle="collapse" data-target="#box1" class="btn-block btn-primary">dot plot</button>'),
      tags$div(id = 'box1', class="collapse in",

        plot_ly(d, x = ~carat, y = ~price, color = ~carat,
          size = ~carat, text = ~paste("Clarity: ", clarity)) %>% layout(height=200)

              ),

   HTML('<button data-toggle="collapse" data-target="#box2" class="btn-block btn-warning">histogram</button>'),
      tags$div(id = 'box2', class="collapse",

         plot_ly(x = rnorm(500), type = "histogram", name = "Histogram") %>% layout(height=200)
      ),


           HTML('<button data-toggle="collapse" data-target="#box3" class="btn-block btn-danger">spinny thing</button>'),
      tags$div(id = 'box3', class="collapse in",

          p %>% layout(height=200)
      )

   )

  ```

【讨论】:

以上是关于如何在 flexdashboard 中结合行列布局?的主要内容,如果未能解决你的问题,请参考以下文章

在 flexdashboard 中结合多个页面不同类型的 vertical_layout

flexdashboard 布局中的两个侧边栏

Flexdashboard 多属性页面

如何在 flexdashboard 中添加徽标?

Flexdashboard 不适用于 Shiny URL 状态

如何修复 flexdashboard 中的下载按钮侧边栏问题