为存储的 rpivottable 配置名称创建一个单选按钮列表

Make a radiobutton list for the stored rpivottable configuration name

以下是一个 link 代码,可以让您节省一些配置,只要您不清除 cookie,就可以随时加载。
我想知道是否可以制作一个单选按钮,显示所有存储名称的列表。

link:

这是我得到的:

  • 使用自定义名称保存
  • 按名称检索
  • 通过单选按钮检索
  • 通过按钮删除

您可能想要调整单选按钮容器的大小或位置。这取决于你如何使用它。现在,随着您添加更多内容,容器将继续增长(达到一定程度)。

这仍然使用文件或网页名称,因此如果您有多个电子表格,您将能够保存并分开配置。

YAML、选项、CSS、库和示例数据。

---
title: "testing rpivotTable cookie-ishness"
author: "me"
date: '2022-05-12'
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```

<style>
body {    /*push content away from far right and left edges*/
  margin-right: 2%;
  margin-left: 2%;
}
.main-container {
  max-width: unset;
}
.btn {    /*Added other buttons*/
  vertical-align: middle;
  -moz-box-shadow: 0px 10px 14px -7px #000000;
    -webkit-box-shadow: 0px 10px 14px -7px #000000;
    box-shadow: 0px 10px 14px -7px #000000;
    -moz-border-radius: 4px;
    -webkit-border-radius: 4px;
    border-radius: 4px;
    border: .5px solid black;
    display: inline-block;
    font-size: 1.15em;            /*Changed from 1.3em*/
    padding: .3em 0px;
    width: 20em;                 /*Changed from 18em*/
    text-decoration: none; /*no underline!!*/
    cursor: pointer;
}
.btn:active { /*simulate movement; added other buttons*/
  position: relative;
  top: 1px;
}
</style>

```{r data,include=F}
# devtools::install_github("fraupflaume/rpivotTable")
library(rpivotTable)
library(tidyverse)
data(mtcars)

```

按钮(不是单选按钮)和 rpivotTable

## Make it Interesting...or not

Do you want to save or restore the previously saved pivot tables' configuration?

<a id='saveNamed' class='btn' style="background-color:#003b70;color:white;">Save Configuration by Name</a>
<a id='restoNamed' class='btn' style="background-color:#b21e29;color:white;">Restore Configuration with Custom Name</a>
<a id='remoSaved' class='btn' style="background-color:black;color:white;">Remove Saved Configuration</a>


```{r showMe, echo=FALSE, fig.show="hold"}
rpivotTable(mtcars, rows="am", cols = c("cyl"), width = "90%", 
            height = "40%", subtotals = TRUE,
            rendererOptions = list(
              c3 = list(legend = list(show = FALSE), 
                        data = list(labels = TRUE),
                        options = list(responsive = TRUE,
                                       maintainAspectRatio = FALSE),
                        size = list(width = "600",
                                    height = "500")),
              d3 = list(size = list(width = "500", height = "500")) 
            ))
```

剩下的代码是Javascript。这将创建事件、保存、检索和删除配置,并创建单选按钮。

```{r listenOrElse,results="asis",engine="js"}

// for ONE TABLE
setTimeout(function(){  // add to buttons
  radioStar();  // <= added in v3
  document.querySelector('a#saveNamed').addEventListener('click', savoring); 
  document.querySelector('a#restoNamed').addEventListener('click', giveItBack);
  document.querySelector('a#remoSaved').addEventListener('click', remIt);  // removing configs
  function savoring() {                              // function to save
    el = document.querySelector('.rpivotTable');
    msg = "Choose a name for the configuration that you are saving.";
    inName = prompt(msg, ['Enter a name with no spaces or special characters'])
    if(inName === null) {return;};                   // they changed their mind; nothing saved
    inName = inName.replace(/[^a-z0-9.]/gi, '');     // validate string
    path = window.location.pathname.split("/").pop().split(".").slice()[0]; //filename
    elId = el.getAttribute("id");
    stringy = $('#' + elId).data("pivotUIOptions");  // collect rows/col filters
    delete stringy['aggregators'];                   // remove not-parse-friendly keys
    delete stringy['renderers'];
    stringy2 = JSON.stringify(stringy);              // one key:value pair for storage
    window.localStorage.setItem(path + '_' + inName, stringy2);  // STORE it!
    radBuilder(inName);  // <= added in v3; mod v4; add radio btn for new saved name
  };
  function giveItBack() {                           // function to regurgitate
    //el = document.querySelector('.rpivotTable');
    msg = "Enter the name of the configuration you would like to retrieve.";
    confName = prompt(msg, ["Enter a name with no spaces or special characters"]);
    if(confName === null) {return;}; 
    confName = confName.replace(/[^a-z0-9.]/gi, '');    // validate string
    retriever(confName);
  }
  function retriever(confName) {  // <= added in v3
    console.log("I'm listening! I swear!");
    el = document.querySelector('.rpivotTable');
    ods = [...el.ownerDocument.scripts];             // make it an array
    path = window.location.pathname.split("/").pop().split(".").slice()[0]; //filename
    elId = el.getAttribute("id");
    where = ods.filter(function(ods){             // filter scripts for data
      return ods.dataset['for'] === elId;
    })[0].innerHTML; 
    where2 = JSON.parse(where).x.data;            // format data for pivotUI()
    where3 = HTMLWidgets.dataframeToD3(where2);   // ...still formatting
    if(window.localStorage.getItem(path + '_' + confName) === null) { // alert
      len = window.localStorage.length
      var str;
      for(i = 0; i < len; i++) {
        w = window.localStorage.key(i);
        w2 = w.split("_").pop();   // remove file/page name <= changed in v3
        str = str + w2 + '\n';     // make one long string of names
      }
      str2 = "WARNING: There is no saved pivot table configuration with the name " + confName + '.';
      str2 += " Here is a list of the configuration names that are currently stored for this page:\n";
      str2 += str;
      alert(str2);  // next step is a change in v3
      giveItBack(); // when unmatched name is chosen instead of re-prompting send them back
    }
    gimme = window.localStorage.getItem(path + '_' + confName); // get storage
    gimmeMore = JSON.parse(gimme);                            // prepare for recall
    if(where.includes('"subtotals":true')){       // is the option 'subtotal' used?
      gimmeMore.renderers = $.pivotUtilities.subtotal_renderers;
      gimmeMore.dataClass = $.pivotUtilities.SubtotalPivotData;
    }; 
    if(where.includes('"tsv":true')){             // is the option 'tsv' used?
      gimmeMore.renderers = $.extend(gimmeMore.renderers, $.pivotUtilities.export_renderers);
    };
    if(where.includes('sortAs')){
      // passed as a function, they will get lost in save & retrieve
      stringy = $('#' + elId).data("pivotUIOptions").sorters;
      gimmeMore.sorters = stringy;
    };
    $('#' + elId).pivotUI(where3, gimmeMore, true, "en"); // put it back!
  }
  function remIt(){
    el = document.querySelector('.rpivotTable');
    msg = "Identify the configuration for removal.";
    remName = prompt(msg, ['Enter a name with no spaces or special characters'])
    if(remName === null) {return;};                   // they changed their mind; nothing saved
    remName = remName.replace(/[^a-z0-9.]/gi, '');     // validate string
    path = window.location.pathname.split("/").pop().split(".").slice()[0]; //filename
    window.localStorage.removeItem(path + '_' + remName);
    rgetter = document.querySelector('#' + remName).parentNode;
    rgetter.remove();
  }
  function radioStar() { // create container *once*; size may have to be adjusted
    if(document.querySelector('#radIsland') == null) { // if an alert doesn't exist
        // one time = create island for radio buttons
      contLabel = document.createElement('div');
      contLabel.setAttribute(
        'style',
        'font-size: 1.2em; font-face: bold; color: #003b70; display: flex; flex-flow: wrap row;');
      contLabel.textContent = 'Choose from the available check points:';
      configCont = document.createElement('div');
      configCont.id = 'radIsland';
      configCont.setAttribute(
        'style',
        'border: 1px solid #003b70; min-width: 11em; width: auto; max-width: 55em; min-height: 10em; height: auto; border-radius: .5em; color: #003b70; display: flex; flex-flow: wrap row;'
      );
      pEl = document.querySelector('.rpivotTable').parentNode;
      pEl.prepend(configCont);        // but box above rpivottable
      pEl.prepend(contLabel);         // put the label on top
    }
    radCreation();
  }
  function radCreation(){
  // if island exists then move on
  // create radio buttons; when savoring runs, radio buttons need to be rebuilt/validated?
    var wk, rB, rLab, desc, newL, rCont, path, len;
    path = window.location.pathname.split("/").pop().split(".").slice()[0]; //filename
    len = window.localStorage.length
    for(i = 0; i < len; i++) {
      wk = window.localStorage.key(i);
      ind = wk.lastIndexOf('_');
      wkFile = wk.substr(0, ind);   // remove file/page name and table number
      chName = wk.split("_").pop();      // user chosen name
      if(wkFile === path) {              // only show radio if file names match
        radBuilder(chName);
      }
    }
  }
  function radBuilder(chName){
    console.log('building a button');
    rB = document.createElement('input');
    rB.type = 'radio';
    rB.name = 'rBtn';       // only one radio w/ same name can be selected at once
    rB.id = chName;         // id's have to be unique for rad groups
    rB.value = chName;
    rB.setAttribute(
        'style',
        'margin: 2px;');
    rB.addEventListener('click', function(){
      retriever(this.value)
    });
    rLab = document.createElement('label');
    rLab.htmlFor = chName;
    desc = document.createTextNode(chName);
    rLab.appendChild(desc);
    newL = document.createElement('br');
    fItem = document.createElement('div');
    fItem.setAttribute(
      'style',
      'width: 10em; height: 1.1em; margin: auto;');
    fItem.appendChild(rB);
    fItem.appendChild(rLab);
    fItem.appendChild(newL);
    rCont = document.getElementById('radIsland');
    rCont.appendChild(fItem);
  }
}, 500);


```

如果删除配置,单选按钮也会消失。

保存配置时将为该配置添加一个单选按钮

您可以添加任意数量的配置。

只需 select 一台新收音机即可更改为不同的配置。