在使用串扰过滤之前显示空 table

Show empty table before filtering with crosstalk

我想用串扰过滤 reactable。假设我有以下 Rmd 文件:

---
title: "blabla"
output:
   flexdashboard::flex_dashboard:
   orientation: rows
   social: menu
   source_code: embed
   theme: cerulean
---

```{r}
library(crosstalk)
library(tidyverse)
```

```{r Make dataset}
df1 <- structure(list(owner = structure(c(1L, 2L, 2L, 2L, 2L), .Label = c("John", "Mark"), 
class = "factor"), hp = c(250, 120, 250, 100, 110), car = structure(c(2L, 2L, 2L, 1L, 1L), .Label = c("benz", "bmw"), class = "factor"), id = structure(1:5, .Label = c("car1", "car2", "car3", "car4", "car5"), class = "factor")), .Names = c("owner", "hp", "car", "id"), row.names = c(NA, -5L), class = "data.frame")

df2 <- structure(list(car = structure(c(1L, 2L, 1L, 2L), .Label = c("benz", 
"bmw"), class = "factor"), owner = structure(c(1L, 1L, 2L, 2L
), .Label = c("John", "Mark"), class = "factor"), freq = c(0L, 
1L, 2L, 2L)), .Names = c("car", "owner", "freq"), row.names = c(NA, 
-4L), class = "data.frame")
```

#

##

### Filters

```{r}
library(crosstalk)
# Notice the 'group = ' argument - this does the trick!
shared_df1 <- SharedData$new(df1, ~owner, group = "Choose owner")
shared_df2 <- SharedData$new(df2, ~owner, group = "Choose owner")

filter_select("owner", "Car owner:", shared_df1, ~owner)
```


##

### Dataframe 1

```{r}
reactable::reactable(shared_df1)
```

### Dataframe 2

```{r}
reactable::reactable(shared_df2)
```

现在,在用户输入车主之前,table 会显示所有车主的行。我想实现 table 为空,只有输入车主时, table 才显示该车主的信息。这有可能实现吗?我正在寻找没有 Shiny 的解决方案。

以上例子推导自:.

我不知道如何用串扰来做,并试图搜索他们的文档,也许这不被支持。但是,我们可以使用一些 javascript 来完成。

function toggleDF(hasItem, selector) {
    if(!hasItem) {
        $(selector).hide();
    } else {
        $(selector).show();
    }
}
$(function(){
    // hide on start
    toggleDF(false, '#dataframe-1 .ReactTable .rt-tbody');
    toggleDF(false, '#dataframe-2 .ReactTable .rt-tbody');
    $('#owner').on("change", function(){
        var hasItem = $(this).find('.selectize-input').hasClass('has-items');
        // hide/show based on selection
        toggleDF(hasItem, '#dataframe-1 .ReactTable .rt-tbody');
        toggleDF(hasItem, '#dataframe-2 .ReactTable .rt-tbody');
    });
});
  1. 一个函数 toggleDF 显示和隐藏 table body。
  2. 根据您在 owner 下拉列表中是否有选择来触发函数的一些表达式。
  3. 表达式中,需要将reactable放在某个标题下,这样我们才能找到ID,例如### Dataframe 2的ID是dataframe-2,小写所有字母和破折号替换空格(Rmarkdown 如何将标题转换为 ID)。

完整代码

---
title: "blabla"
output:
   flexdashboard::flex_dashboard:
   orientation: rows
   social: menu
   source_code: embed
   theme: cerulean
---

```{r}
library(crosstalk)
library(tidyverse)
```

```{r Make dataset}
df1 <- structure(list(owner = structure(c(1L, 2L, 2L, 2L, 2L), .Label = c("John", "Mark"), 
class = "factor"), hp = c(250, 120, 250, 100, 110), car = structure(c(2L, 2L, 2L, 1L, 1L), .Label = c("benz", "bmw"), class = "factor"), id = structure(1:5, .Label = c("car1", "car2", "car3", "car4", "car5"), class = "factor")), .Names = c("owner", "hp", "car", "id"), row.names = c(NA, -5L), class = "data.frame")

df2 <- structure(list(car = structure(c(1L, 2L, 1L, 2L), .Label = c("benz", 
"bmw"), class = "factor"), owner = structure(c(1L, 1L, 2L, 2L
), .Label = c("John", "Mark"), class = "factor"), freq = c(0L, 
1L, 2L, 2L)), .Names = c("car", "owner", "freq"), row.names = c(NA, 
-4L), class = "data.frame")
```

#

##

### Filters

```{r}
library(crosstalk)
# Notice the 'group = ' argument - this does the trick!
shared_df1 <- SharedData$new(df1, ~owner, group = "Choose owner")
shared_df2 <- SharedData$new(df2, ~owner, group = "Choose owner")

filter_select("owner", "Car owner:", shared_df1, ~owner)
```


##

### Dataframe 1

```{r}
reactable::reactable(shared_df1)
```

### Dataframe 2

```{r}
reactable::reactable(shared_df2)
```

<script>
function toggleDF(hasItem, selector) {
    if(!hasItem) {
        $(selector).hide();
    } else {
        $(selector).show();
    }
}
$(function(){
    // hide on start
    toggleDF(false, '#dataframe-1 .ReactTable .rt-tbody');
    toggleDF(false, '#dataframe-2 .ReactTable .rt-tbody');
    $('#owner').on("change", function(){
        var hasItem = $(this).find('.selectize-input').hasClass('has-items');
        // hide/show based on selection
        toggleDF(hasItem, '#dataframe-1 .ReactTable .rt-tbody');
        toggleDF(hasItem, '#dataframe-2 .ReactTable .rt-tbody');
    });
});
</script>