Изменить второй вкладки при нажатии на flexdashboard - PullRequest
5 голосов
/ 27 апреля 2020

Я работаю над автономным проектом flexdashboard, и мне интересно, если это возможно, когда пользователь нажимает на новую вкладку в одном наборе вкладок, он также меняется на новую вкладку на втором вкладке.

Так, например, когда вы нажимаете «Диаграмму B1» ниже, я также хотел бы изменить вид на «Диаграмма B2» во втором столбце. А нажатие на «Диаграмма A2» изменится на «Диаграмма A1» и т. Д. c. et c.

enter image description here

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

```{r setup, include=FALSE}
library(flexdashboard)
```

Column {.tabset}
-----------------------------------------------------------------------

### Chart A1

### Chart B1

Column {.tabset}
-----------------------------------------------------------------------

### Chart A2

### Chart B2

Обратите внимание, это было впервые опубликовано в RStudio Community , но не получено ответы.

Ответы [ 2 ]

4 голосов
/ 04 мая 2020

Это может быть реализовано с помощью JavaScript. К счастью, Knitr поддерживает встроенный Javascript. Я в первую очередь программист на R, так что это не обязательно самая краткая реализация, но она дает правильный эффект.

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

    ```{r setup, include=FALSE}
    library(flexdashboard)
    ```

    Column {.tabset}
    -----------------------------------------------------------------------

    ### Chart A1
    Chart A1 is Great

    ### Chart B1
    Chart B1 is Great

    Column {.tabset}
    -----------------------------------------------------------------------

    ### Chart A2
    Chart A2 is Great

    ### Chart B2
    Chart B2 is Great

    ```{js}
    // Once the Document Has Fully Loaded
    document.addEventListener("DOMContentLoaded", function(){
      // Select The Tabs
      window.a1Tab = document.querySelector("#column > ul > li:nth-child(1)");
      window.b1Tab = document.querySelector("#column > ul > li:nth-child(2)");
      window.a2Tab = document.querySelector("#column-1 > ul > li:nth-child(1)");
      window.b2Tab = document.querySelector("#column-1 > ul > li:nth-child(2)");

      // Select the Panel Content
      window.a1Panel = document.getElementById('chart-a1');
      window.b1Panel = document.getElementById('chart-b1');
      window.a2Panel = document.getElementById('chart-a2');
      window.b2Panel = document.getElementById('chart-b2');

      // If We Click on B1, Open B2, Close A2
      b1Tab.addEventListener('click', function(){
        a2Tab.classList.remove('active');
        a2Tab.children[0].setAttribute('aria-expanded', true);
        a2Panel.classList.remove('active');

        b2Tab.classList.add('active');
        b2Tab.children[0].setAttribute('aria-expanded', true);
        b2Panel.classList.add('active');
      }, false);

      // If We Click on B2, Open B1, Close A1
      b2Tab.addEventListener('click', function(){
        a1Tab.classList.remove('active');
        a1Tab.children[0].setAttribute('aria-expanded', true);
        a1Panel.classList.remove('active');

        b1Tab.classList.add('active');
        b1Tab.children[0].setAttribute('aria-expanded', true);
        b1Panel.classList.add('active');
      }, false);

      // If We Click on A1, Open A2, Close B2
      a1Tab.addEventListener('click', function(){
        b2Tab.classList.remove('active');
        b2Tab.children[0].setAttribute('aria-expanded', true);
        b2Panel.classList.remove('active');

        a2Tab.classList.add('active');
        a2Tab.children[0].setAttribute('aria-expanded', true);
        a2Panel.classList.add('active');
      }, false);

      // If We Click on A2, Open A1, Close B1
      a2Tab.addEventListener('click', function(){
        b1Tab.classList.remove('active');
        b1Tab.children[0].setAttribute('aria-expanded', true);
        b1Panel.classList.remove('active');

        a1Tab.classList.add('active');
        a1Tab.children[0].setAttribute('aria-expanded', true);
        a1Panel.classList.add('active');
      }, false);
    });

    ```

Редактировать: Для неограниченного количества вкладок, при условии, что вы всегда будете иметь одинаковое количество вкладок в первом и втором столбце. Тот же отказ от ответственности, это не обязательно самая краткая реализация, но достигающая желаемого эффекта.


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

    ```{r setup, include=FALSE}
    library(flexdashboard)
    ```

    Column {.tabset}
    -----------------------------------------------------------------------

    ### Chart A1
    Chart A1 is Great

    ### Chart B1
    Chart B1 is Great

    ### Chart C1
    Chart C1 is Great

    ### Chart D1
    Chart D1 is Great

    Column {.tabset}
    -----------------------------------------------------------------------

    ### Chart A2
    Chart A2 is Great

    ### Chart B2
    Chart B2 is Great

    ### Chart C2
    Chart C2 is Great

    ### Chart D2
    Chart D2 is Great

    ```{js}
    // Once the Document Has Fully Loaded
    document.addEventListener("DOMContentLoaded", function(){
      // Select The Tabs
      window.col1Tabs = document.querySelector("#column > ul");
      window.col2Tabs = document.querySelector("#column-1 > ul");

      // Select the Panel Content
      window.col1Panels = document.querySelector("#column > div");
      window.col2Panels = document.querySelector("#column-1 > div");

      // Function to Make Tabs Active
      window.handleTab = function(tabIndex){
        for(i=0;i<col1Tabs.childElementCount;i++){
          col1Tabs.children[i].classList.remove('active');
          col2Tabs.children[i].classList.remove('active');
          col1Panels.children[i].classList.remove('active');
          col2Panels.children[i].classList.remove('active');
        }
        col1Tabs.children[tabIndex].classList.add('active');
        col2Tabs.children[tabIndex].classList.add('active');
        col1Panels.children[tabIndex].classList.add('active');
        col2Panels.children[tabIndex].classList.add('active');
      }

      // For All Tabs, Add Event Listener
      for(i=0;i<col1Tabs.childElementCount;i++){
        col1Tabs.children[i].setAttribute('onclick', 'handleTab(' + i + ');');
        col2Tabs.children[i].setAttribute('onclick', 'handleTab(' + i + ');');
      }

    });

    ```

Редактировать: Для тех, кто может найти этот вопрос позже, к * была добавлена ​​реализация JQuery с большей гибкостью Github Issue.

2 голосов
/ 06 мая 2020

Просто добавьте еще один ответ, используя JQuery и функцию boostrap tabset JS. Он более краткий, чем другой ответ, но работает одинаково с любым количеством вкладок (но с одинаковым числом) в формате двух столбцов.

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

```{r setup, include=FALSE}
library(flexdashboard)
```

```{js}
document.addEventListener("DOMContentLoaded", function(){
    $('a[data-toggle="tab"]').on('click', function(e){
      // find the tab index that is click
      child = e.target.parentNode;
      tabnum = Array.from(child.parentNode.children).indexOf(child);
      // find in which column we are
      column = $(e.target).closest("div[id]");
      // show the same tab in the other column
      columnid = column.attr("id");
      if (columnid == "column") {
        columnto = "column-1";
      } else {
        columnto = "column";
      }
      $("div[id="+columnto+"] li:eq("+tabnum+") a").tab('show');
    })
});
```

Column {.tabset}
-----------------------------------------------------------------------

### Chart A1

This is a text

### Chart B1

```{r}
plot(iris)
```


Column {.tabset}
-----------------------------------------------------------------------

### Chart A2

```{r}
plot(mtcars)
```

### Chart B2

This is another text

...