• R语言
  • 求复现问题,同一段代码输出为ioslides_presentation和html_document时展示效果差别很大

问题是这样的:
echarts4r包里有个函数叫e_arrange可以把不同的图放一起展示,比如e_arrange(e1, e2, e3, e4, cols = 2, rows = 2)就是指我画了e1/e2/e3/e4四个图并指定这四个图排成两行两列一起展示出来,但是输出为output: ioslides_presentation时就变成所有图都排成一列了,我换成输出普通的output: html_document却是正常的。
代码如下:

---
title: echarts 图形排列
output:
  ioslides_presentation: default
  html_document: default
---

## 两行两列

```{r, echo=FALSE}
library(echarts4r)

df <- data.frame(
  x = seq(50),
  y = rnorm(50, 10, 3),
  z = rnorm(50, 11, 2),
  w = rnorm(50, 9, 2)
)

e1 <- df |>
  e_charts(x,
           height = 200,
           width = 200,
           elementId = "图1") |>
  e_line(z) |>
  e_area(w)

funnel <-
  data.frame(stage = c("View", "Click", "Purchase"),
             value = c(80, 30, 20))
e2 <- funnel |>
  e_charts(height = 200,
           width = 200,
           elementId = "图2") |>
  e_funnel(value, stage)

liquid <- data.frame(val = c(0.6, 0.5, 0.4))
e3 <- liquid |>
  e_charts(height = 200,
           width = 200,
           elementId = "图3") |>
  e_liquid(val)

e4 <- df |>
  e_charts(x, height = 200, width = 200) |>
  e_polar() |>
  e_angle_axis(x) |> # angle = x
  e_radius_axis() |>
  e_bar(y, coord_system = "polar") |>
  e_scatter(z, coord_system = "polar") |>
  e_connect(c("图1", "图2", "图3"))

e_arrange(e1, e2, e3, e4, cols = 2, rows = 2)
```

环境信息如下:

> sessionInfo()
R version 4.1.1 (2021-08-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19043)

Matrix products: default

locale:
[1] LC_COLLATE=Chinese (Simplified)_China.936  LC_CTYPE=Chinese (Simplified)_China.936   
[3] LC_MONETARY=Chinese (Simplified)_China.936 LC_NUMERIC=C                              
[5] LC_TIME=Chinese (Simplified)_China.936    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] dplyr_1.0.7          echarts4r.maps_0.0.2 data.table_1.14.2    echarts4r_0.4.2     

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.7        knitr_1.36        magrittr_2.0.1    tidyselect_1.1.1  xtable_1.8-4      R6_2.5.1          rlang_0.4.11     
 [8] fastmap_1.1.0     fansi_0.5.0       tools_4.1.1       xfun_0.26         utf8_1.2.2        htmltools_0.5.2   ellipsis_0.3.2   
[15] yaml_2.2.1        digest_0.6.28     countrycode_1.3.0 tibble_3.1.5      lifecycle_1.0.1   crayon_1.4.2      shiny_1.7.1      
[22] purrr_0.3.4       later_1.3.0       htmlwidgets_1.5.4 vctrs_0.3.8       promises_1.2.0.1  evaluate_0.14     mime_0.12        
[29] glue_1.4.2        rmarkdown_2.11    compiler_4.1.1    pillar_1.6.4      generics_0.1.1    jsonlite_1.7.2    httpuv_1.6.3     
[36] pkgconfig_2.0.3  

    没有仔细调查,大概说一个推测:
    e_arrange不是 Echart 原装提供的接口,而是为了方便大家使用而独立写的一个函数,只对普通 html 渲染做了验证,甚至在 shiny 中也是没有办法正常使用的,因此可能存在不少问题,和 ioslides_presentation 产生冲突也可能是其中一个 bug。

    这个问题比较难修,所以如果不介意的话可以直接拆开写看看能不能达成目的:

    e_arrange(e1, e2)
    e_arrange(e3, e4)

    yuanfan 没有仔细调查,不过凭直觉大概能猜出来问题所在。一句 CSS 解决问题:

    ```{css, echo=FALSE}
    .col-xs-6 {
      display: inline-block;
      /* width: 49%; */
    }
    ```

    我没有时间解释,留给其他客官解释吧。宽度我注释掉了,如果需要调整宽度,可以把注释符 /* */ 去掉。

    把益辉给的那段css放到ioslides的主题css文件中以后,能正常显示成两行两列了。
    虽然网上能查到col-xs-6display: inline-block的含义,不过背后的逻辑依然不明所以。
    蹲个答案,看哪天有英雄好汉路过的话顺道说说。

      yuanfan 算了,估计没人来解开这个谜了,还是我自己来吧。刚回了个别的帖子,趁手热把这个也回了。

      这个 e_arrange() 貌似假设用户会使用 Bootstrap 框架,把每一幅图包在 <div class="col-xs-6"></div> 里。这个假设在 html_document 和 Shiny 中基本上都可以成立,因为它们默认都用 Bootstrap。遇上不用 Bootstrap 的应用,它就不灵了,比如 ioslides_presentation 就不用。CSS 类 col-xs-6 是 Bootstrap 里的一个类名,大约表示 6 栏宽。Boostrap 一共将页面定义为 12 栏,那么 6 栏就是一半的宽度,也就是一行上放两个对象,即两列。

      若不用 Bootstrap,那么 col-xs-6 就没有任何特殊意义了,只是个平凡的类名。默认情况下,<div class="col-xs-6"> 会是全宽的,因为 <div> 是占全宽的元素(CSS 属性默认 display: block;)。将它的属性改成 inline-block,也就是让它变成行内(依旧是块状)元素,那么它就不会像杜鹃鸟一样将左右的元素全部排挤到下一行了(除非是当前行挤不下了);这就像行内文字一样,只有触及页边、摆不下的时候才会换行。这个 inline-block 属性我自己也经常用,比如前几天的菜谱样式翻新时,我就将它用在了目录里的 <li> 子项上,使得一行能放多道菜名(<li> 默认也是全宽元素,一行放一项)。这是导航菜单样式的常用伎俩。

      你的每一幅子图的宽度恰好让它们能在 ioslides_presentation 里一行放两幅,所以我的宽度定义可以注释掉。若你要一行放三幅图,那么宽度应该大约小于等于 33%;以此类推。

        5 个月 后

        yihui 这个 e_arrange() 貌似假设用户会使用 Bootstrap 框架,把每一幅图包在 <div class="col-xs-6"></div> 里。

        今天发现这句话不严谨。这个类名 col-xs-6 中的数字取决于 e_arrange() 中指定的列数。楼主的例子是 2 列,而全宽是 12 栏,所以每一列占 6 栏,也就得到了这个数字 6。如果是 e_arrange(cols = 4),那么类名将会是 col-xs-3(3 = 12 / 4)。