首页 > 解决方案 > 在 flexdashboard 中单击时更改第二个标签集

问题描述

我正在开发一个自包含的 flexdashboard 项目,我想知道当用户单击一个选项卡集中的新选项卡时是否有可能,它也会更改为第二个选项卡集中的新选项卡。

因此,例如,当您单击下面的“图表 B1”时,我还想将第二列中的视图更改为“图表 B2”。点击“Chart A2”会变回“Chart A1”等等。

在此处输入图像描述

---
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 上,但没有收到任何回复。

标签: rr-markdownflexdashboard

解决方案


这可以用 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 + ');');
      }

    });

    ```

编辑:对于以后可能会发现此问题的任何人,Github 问题中添加了具有更大灵活性的 JQuery 实现。


推荐阅读