从脚本创建的下拉框中重新加载数据,而无需删除元素并创建另一个元素

Reload data from a drop down box created by script without having to delete the element and create another one

我的 CSV 文件中的值不断变化,因此要更新选项,我可以做的最差模型是 remove the element by ID 并创建一个新模型,调用创建框的函数再次,但页面在删除元素和创建新元素之间不断上下移动。

我想帮助创建一种在此过程中不需要删除元素的方法。

注意:我使用D3.js解析CSV数据。

我的CSV模型数据:

label,value
,
Bayern x Dortmund,www.google.com
Barcelona x Real Madrid,www.yahoo.com
City x Arsenal,www.duckduckgo.com

我当前要自动重新加载的任务:

<script id="auto-update-csv">
    let interval_csv
    window.addEventListener('DOMContentLoaded', () => {
        interval_csv = setInterval(refreshcsv, 5000); // refresh every 5 secs
    })
    
    function refreshcsv() {
        document.getElementById('select-box-1').remove()
        d3.csv("Lista_de_Jogos.csv", function(error, data){caixasuspensa1(error, data)});
    }
</script>

我创建盒子的脚本:

<script src="http://d3js.org/d3.v3.js"></script>
<script id="script-da-caixa-de-selecao-suspensa-1">
    function caixasuspensa1(error, data) {
      var select = d3.select("#caixa-suspensa-1").append("select").attr("id","select-box-1").style("width","100%")
    
      select
        .on("change", function(d) {
          var value = d3.select(this).property("value");
          document.querySelector('#barra-de-texto-para-radar-1').value = value;
          document.getElementById('botao-do-radar-1').click();
        });
    
      select.selectAll("option")
        .data(data)
        .enter()
          .append("option")
          .attr("value", function (d) { return d.value; })
          .text(function (d) { return d.label; });
    }
    
    d3.csv("Lista_de_Jogos.csv", function(error, data){caixasuspensa1(error, data)});
</script>

您有数据相关项:选项和一个结构性和永久性(数据无关项):select。

我们可以一次添加我们的结构项目。然后在更新函数中,使用 enter/update/exit 循环,或者更简单地说,join 方法,以确保我们根据需要从 select.

更新、创建和删除选项

下面是一个使用 selection.join 的示例。 select 附加一次并在更新函数之外,更新函数仅 modifies/creates/removes 依赖于数据的元素:选项。

var select = d3.select("body")
  .append("select")
  .attr("id","select-box")
  .style("width","347px");
  
var data = [1,2,3,4]
  
function update(data) {
  
  select.selectAll("option")
    .data(data)
    .join("option")
    .text(d=>d)
    .attr("value",d=>d);
    
}

// load initial data:
update(data);


// generate new data and pass to update();
d3.select("body")
  .append("button")
  .text("update options")
  .on("click", function() {
    var min = Math.floor(Math.random() * 4);
    var length = Math.round(Math.random() * 3 + 3)
    data = d3.range(length).map(d=>d+min);
    console.log(data);
    update(data);
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>

虽然我在这里没有使用 d3.csv,但方法保持不变:当有新数据可用时,调用 update(data),其中数据是新数据数组。例如:

function refreshcsv() {
    d3.csv("Lista_de_Jogos.csv").then(update);
}

我用的是d3v7,join方法是d3v5后期引入的。看来您使用的是 v4,在这种情况下我们需要使用进入、退出和更新 selections:

var select = d3.select("body")
  .append("select")
  .attr("id","select-box")
  .style("width","347px");
  
var data = [1,2,3,4]
  
function update(data) {
  
  let update = select.selectAll("option")
    .data(data);
    
  update.exit().remove();
    
  update.enter().append("option").merge(update)
    .text(d=>d)
    .attr("value",d=>d);

}

// load initial data:
update(data);


// generate new data and pass to update();
d3.select("body")
  .append("button")
  .text("update options")
  .on("click", function() {
    var min = Math.floor(Math.random() * 4);
    var length = Math.round(Math.random() * 3 + 3)
    data = d3.range(length).map(d=>d+min);
    console.log(data);
    update(data);
  })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>

并将 refreshcsv 函数还原为 v4:

function refreshcsv() {
    d3.csv("Lista_de_Jogos.csv", function(error, data) { 
           /* check for error or processing */ 
           update(data); 
   })
}

当然,我们需要确保 select 元素在更新函数 运行[ 之前创建并 selected =17=]