使用D3.js动态创建时如何使HTML复选框运行功能

时间:2019-02-04 22:30:49

标签: javascript html d3.js leaflet

[版本]我想我找到了问题。这是因为我的CSV已转换为JSON。在我的D3中,我使用的是myJSON = JSON.parse(JSON.stringify(data));制作我的JSON。问题是我的经纬度是字符串。当我将原始JSON放入JavaScript时,所有与D3对应的复选框都可以使用。当我使用转换后的版本时,它不起作用。所以现在我的问题是,如何在我的D3中将CSV文件转换为对象而不是字符串,并放置在全局JSON变量中?因此,我需要在转换过程中将字符串数字转换为实数(从CSV到JSON)。

我发现了一个很棒的概念!这是我使用的示例https://jsfiddle.net/xf4fwwme/44/的jsFiddle的链接。

但是,为了自定义一个最适合我的概念,我使用D3.js动态创建复选框,并从CSV文件然后从JSON.parse(JSON.stringify(data))加载数据。将数据存储到全局json对象/变量中,因此我可以使用CSV文件更轻松地更新复选框和数据。我设法创建了复选框,但似乎可以像上面的jsfiddle示例一样运行该功能。当我将复选框HTML硬编码到位时,它工作得很好,但是当使用D3.js动态添加时,我什么都没用。似乎没什么问题,但是我无法运行它。以下是我正在使用的D3复选框表单脚本。其他一切都类似于上面的jsfiddle示例。任何帮助解决此问题的帮助将不胜感激。预先谢谢你。

当我像下面这样对HTML进行硬编码时,效果非常好;像jsfiddle示例一样:

<div class="checkboxWrapper">

<div id="form">

<input type="checkbox" id="cbAdults" checked>Adults

<input type="checkbox" id="cbYouth" checked>Youth

<input type="checkbox" id="cbSeniors" checked>Seniors

<input type="checkbox" id="cbMen" checked>Men

<input type="checkbox" id="cbWomen" checked>Women
<br>

<button id="btnForm">Filter</button>

</div>
</div>

这种方式行不通。复选框和数据是使用D3.js动态加载的。

var myJSON;

d3.csv("data/checkboxData.csv", function(error, data) {
  if (error) {
    alert("Data didn't load, Refresh your browser");
  } else {
    myJSON = JSON.parse(JSON.stringify(data)); //convert CSV data to JSON and load in Global variable

    var selectBox = d3.select("#form")
      .selectAll("input")
      .data(data)
      .enter()
      .append("label")
      .append("input")
      .attr("checked", true)
      .attr("type", "checkbox")
      .attr("id", function(d, i) {
        return d.cbID;
      })
      .attr("onClick", filter()) ////can't get this to run the function
    .on('change', filter()) /////and I can't get this to run the function
    .attr("for", function(d, i) {
      return i;
    });

    d3.selectAll("#form label")
      .data(data)
      .attr("class", "checkbox")
      .append("text").text(function(d) {
        return " " + d.checkBoxValue
      })
  }
});

let myMarkers = L.featureGroup().addTo(map);
btnForm.onclick = () => filter();

filter();


function filter() {
  myMarkers.clearLayers();

  let myJSONcopy = JSON.parse(JSON.stringify(myJSON));

  let categories = [];

  if (cbAdults.checked) {
    categories.push('adults');
  }
  if (cbYouth.checked) {
    categories.push('youth');
  }
  if (cbSeniors.checked) {
    categories.push('seniors')
  }
  if (cbMen.checked) {
    categories.push('men');
  }
  if (cbWomen.checked) {
    categories.push('women');
  }

  for (let i = 0; i < myJSONcopy.length; i++) {
    for (let j = 0; j < categories.length; j++) {
      for (let k = 0; k < myJSONcopy[i].demographic.length; k++)
        if (categories[j] == myJSONcopy[i].demographic[k] &&
          !myJSONcopy[i].added) {

          L.circleMarker([myJSONcopy[i].lat, myJSONcopy[i].lon], {
            color: myJSONcopy[i].color,
            fillColor: myJSONcopy[i].color,
            fillOpacity: 1,
            radius: 10.0
          }).addTo(myMarkers);

          myJSONcopy[i].added = true;

          ///Fit to bounds
          map.fitBounds(myMarkers.getBounds(), {
            padding: [150, 150],
            animate: true,
            duration: 2
          });
          break;
        }
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div class="checkboxWrapper">
  <div id="form"></div>
  <br>
  <button id="btnForm">Filter</button>
</div>

0 个答案:

没有答案