D3 .on change 适用于不在图表上的文本

D3 .on change works on text not on chart

我试图在下拉列表中的值发生变化时显示和更新相同的变化数据。您会看到文本数据按预期更改,但条形图未正确更新。它似乎在覆盖自己。您可以在此处找到 运行 示例代码:http://jsfiddle.net/khnumtemu/43oaczq8/15/

// Create a distinct list of FSMs
  var uniqueValues = d3.map([])
  dataset.forEach(function(d){ uniqueValues.set(d.FsmId, d); });

  var newJsonStr = []
  uniqueValues.forEach(function(d){ newJsonStr.push(uniqueValues.get(d)); });

  // Create and Fill Dropdown
  d3.select("body").append("select")
    .classed('colorSelect',true)
    .selectAll("option")
    .data(newJsonStr)
    .enter()
    .append("option")
    .attr("value",function(d){ return d.FsmId;})
    .text(function(d){ return d.FieldSalesManagerName + " (" + d.FsmId + ")";})
    .sort(function(a, b) {return d3.descending(a.FieldSalesManagerName, b.FieldSalesManagerName);});


// Inital Data OnLoad
  var intsel = d3.select(".colorSelect").node().value;
  d3.select("body").selectAll("p")
    .data(dataset)
    .enter()
    .append("p")
    .text(function(d){
          if(d.FsmId == intsel){
            return d.SalesRepName;
          }
    })

  var w = 800;
  var h = 500;
  var x = d3.scale.linear().domain([0,d3.max(dataset)]).range([0,w]);
  var y = d3.scale.linear().domain([0,dataset.length]).range([0,h]);
  var svg = d3.select("body").append("svg")
                .attr({
                  "id":"chart",
                  "width":w,
                  "height":h
                  })

  svg.selectAll(".bar")
    .data(dataset)
    .enter()
    .append("rect")
    .filter(function(d,i){if(d.FsmId == intsel){
            return d.AchievementCount;
          }})
    .attr({
      "class":"bar",
      "x":0,
      "y": function(d,i){
         return y(i);
      },
      "width": function(d,i){
        return d.AchievementCount;
      },
      "height": function(d,i){ return y(1) -1; }
    })


  // Data Updated on Selected Change
  d3.select("select")
    .on("change", function(d){

      var sel = d3.select(".colorSelect").node().value;
      d3.select("body").selectAll("p")
        .data(dataset)
        .text(function(d){
          if(d.FsmId == sel){
            return d.SalesRepName;
          }
        })



        svg.selectAll(".bar")
        .data(dataset)
        .enter()
        .append("rect")
        .filter(function(d,i){if(d.FsmId == sel){
                return d.AchievementCount;
              }})
        .attr({
          "class":"bar",
          "x":0,
          "y": function(d,i){
             return y(i);
          },
          "width": function(d,i){
            return d.AchievementCount;
          },
          "height": function(d,i){ return y(1) -1; }
        })

    });

更新 d3 可视化遵循进入、更新和退出工作流程(开始阅读 here and here)。

您只处理输入案例。因此,在每个 .on 上,您都在 rect 之后的 rect 之后附加 rect。您永远不会退出(删除 rect)或更新(更新现有的 rect)。解决这个问题的正确方法是处理那些老人。

当然,对于像您这样小的数据集,简单的解决方法(您不会看到性能下降)就是删除并重新添加所有矩形。

svg.selectAll(".bar").remove();

例子here.