I have a two separate r2d3 chunks in an RMarkdown document, which I’m rendering to HTML.
Given the way r2d3 works, you can only have 1 script and 1 datasource that goes with each r2d3 call.
This chunk produces a map, with a dropdown menu:
```{r out.width='100%', fig.height=6, echo=FALSE, message=FALSE, warning=FALSE}
library(r2d3)
r2d3(data = dataset_1,
# this is the script for the first map.
script = "X:/dataset_1_script.js",
d3_version = "4",
options(r2d3.shadow = FALSE),
container="div",
elementId = "map_1")
```
This chunk produces another map with a dropdown menu (note the script and datasource is different):
```{r out.width='100%', fig.height=6, echo=FALSE, message=FALSE, warning=FALSE}
library(r2d3)
r2d3(data = dataset_2,
# this is the script for the second map.
script = "X:/dataset_2_script.js",
d3_version = "4",
options(r2d3.shadow = FALSE),
container="div",
elementId = "map_2")
```
Here is some of the basic content in dataset_1_script.js
. The script dynamically creates a dropdown element in the DOM. While this works in dataset_1_script.js
, it does NOT work in the second chunk with dataset_2_script.js
. In dataset_2_script.js
the dropdown doesn’t render in the DOM. The issue is due to the fact that both scripts call the addElement
function on document.body.onload
. And, given that document.body.onload
can only be called once, it makes sense that the dropdown element is successfully created in the first chunk (first script), but not in the second chunk (second script).
So my question is: is there a way to solve this issue in r2d3? I do think I need body.onload
to render the dropdown to the DOM.
document.body.onload = addElement_Tract;
function insertAfter_Tract(newNode, existingNode) {
existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);
}
function addElement_Tract() {
// create a sidebar_tract to hold legend and dropdown
const sidebar_tract = document.createElement("div");
sidebar_tract.className = "sidebar_tract";
sidebar_tract.id = "sidebar_tract";
//Create array of options to be added
var display_array_tract = ["2023", "2022","2021","2020","2019", "2018"];
var val_array_tract = [2023, 2022, 2021, 2020, 2019, 2018];
//Create and append select list
var selectList_tract = document.createElement("select");
selectList_tract.id = "mySelect_tract";
selectList_tract.className = "mySelect_tract";
//Create and append the options
for (var i = 0; i < display_array_tract.length; i++) {
var option_tract = document.createElement("option");
option_tract.value = Number(val_array_tract[i]);
console.log(option_tract.value);
option_tract.text = display_array_tract[i];
selectList_tract.appendChild(option_tract);
}
// add the newly created element and its content into the DOM
// Get a reference to the parent node
const parentDiv_tract = document.getElementById("map_choropleth_state_tract").parentNode;
const mapDiv_tract = document.getElementById("map_choropleth_state_tract");
insertAfter_Tract(sidebar_tract, mapDiv_tract)
sidebar_tract.appendChild(selectList_tract);
}
Thanks in advance!