A simple scenario - markers chart on a Leaflet map. How to replace the chart with another?
If we do have a Shiny server we’ll write a Shiny app (or .Rmd) and be done with it.
But what if we don’t? How to enjoy a little chart selection without Shiny server’s heavy machinery?
Lets use a Markdown document with some extra JavaScript to do the job!

library(dplyr)
library(echarty)

data1 <- '
lon,lat,time,name,desc,area
-117.213417,32.822426,"2020-02-02","Clairmont","mex.jpg","SD"
-116.837258,33.041465,"2020-03-02","Ramona","👽","SD"
-117.146883,32.731749,"2020-04-02","Zoo","mex.jpg","SD"
-116.792351,32.821695,"2020-04-02","Alpine","👽","SD"
-116.567946,33.067508,"2020-06-02","Julian","👽","SD"
-118.838408,34.202133,"2020-04-02","1000oaks","kim","LA"
-118.435860,34.000473,"2020-06-02","StMonica","https://i.imgur.com/oUTzyvG.png","LA"
-118.045643,34.178955,"2020-06-02","Pasadena","https://i.imgur.com/zTw7b5h.jpg","LA"
-118.845374,34.039848,"2020-07-02","Malibu","https://image.flaticon.com/icons/png/64/129/129138.png","LA"
'
df <- read.csv(text=data1, header=TRUE)

plt <- function(df, name='name?') {
    p <- df %>% ec.init(load='leaflet')
    p$x$opts$tooltip <- list(ey='')
    p$x$opts$name <- name  # for one option of the dropdown
    p$x$opts$leaflet <- list(zoom=9, roam=TRUE, 
                             center=c(sum(range(df$lon))/2, sum(range(df$lat))/2))
    p$x$opts$series <- list(list(
      type='scatter', coordinateSystem='leaflet',
      #  markers as images: works, but not with imgur.com, 'circle' does not work
      # symbol = htmlwidgets::JS("function(params) {  //console.log(params);
      # if (params[4].endsWith('.jpg')) return ('image://'+params[4]);
      # if (params[4].endsWith('.png')) return ('image://'+params[4]);
      # return('circle');
      # }"), symbolSize=44, symbolKeepAspect=TRUE,
      symbol = 'pin', symbolSize=44, 
      itemStyle=list(color= if (name=='LA') 'red' else 'green'),
      encode=list(tooltip=list(2,3,5)) )  # Js count 0,1,2..
    )
    p
}
p1 <- plt(df %>% filter(area=='LA'), 'LA')
p2 <- plt(df %>% filter(area=='SD'), 'SD')
p1$x$o2 <- p2$x$opts        # save the second plot data
p1

And here is the JavaScript code


var chopt = {p1:null, p2:null, gpx:null};
function getData() {
  try {
    // find 1st htmlwidget, easy when there is only one ;-)
    const inlineJsonElement = document.querySelector(
      `script[type="application/json"][data-for^=htmlwidget-]`
    );
    const data = JSON.parse(inlineJsonElement.textContent);
    return data;
  } catch (err) {
    console.error(`Couldn't read JSON data from htmlwidget`, err);
  }
}
document.addEventListener("DOMContentLoaded", function() {
    const pp = getData();
    chopt.p1 = pp.x.opts;
    chopt.p2 = pp.x.o2;
    var pddl = document.querySelector('[id="pddl"]');
    var o = document.createElement("option");
    o.text = chopt.p1.name; pddl.options.add(o);
    o = document.createElement("option");
    o.text = chopt.p2.name; pddl.options.add(o);

    pddl.addEventListener('change', (event) => {
        var wt = document.querySelector("[id^=htmlwidget-]");  
        // get the ECharts object and replace options
        var p = get_e_charts(wt.id);
        switch(event.target.value) {
        case chopt.p1.name:  
            p.setOption(chopt.p1, true);
            break;
        case chopt.p2.name:
            p.setOption(chopt.p2, true);
            break;
        default:
            alert('selection not found');
        }
    });
});

TODO: add a file upload input for .GPX files
Users could view their own data. It all happens in the browser(client), so again no server needed.