在D3.js中过滤和匹配json数据悬停

时间:2017-10-25 21:13:11

标签: javascript json d3.js

我正在尝试创建一个交互式图例,根据谁拥有它们,突出显示D3.js地图上的匹配村庄。但是,突出显示不起作用。如果我改变我的JSON文件以显示该村庄由一个人所拥有,那么大多数村庄都由多人拥有。我怎样才能解决这个问题?我需要用JSON做些什么吗?

交互式图例代码如下:

//Decrease opacity of non selected circles when hovering in the legend  
function selectLegend(opacity) {
  return function(d, i) {
    var chosen = color.domain()[i];
    d3.selectAll(".villages")
      .filter(function(d) { return d.landholder != chosen; })
      .transition()
      .style("opacity", opacity);
  };
};//function selectLegend

json如下所示:

[
  {
    "longitude": 55.4,
    "latitude": 55.4,
    "name": "village1",
    "landholder": ["Landholder1", "Landholder2", "Landholder3"]
  }
]

1 个答案:

答案 0 :(得分:1)

假设chosen只包含一个土地所有者的名字:

如果d.landholder是一个数组,那么使用d.landholder == chosen将无效。您将需要查看您的值是否在数组中,而不是值是否等于数组。

尝试以下行:

 .filter(function(d) { return d.landholder.indexOf(chosen) > -1; })

array.indexOf(value)将返回给定数组中a值的索引。否定值表示该值不存在。因此,对于您的代码,如果d.landholder.indexOf(chosen)返回零或更大的数字,您可以查看所选值是否在landholder数组中。

为此,json中的所有landholder值都应该是数组,即使它们只有一个值:

"landholder": ["Landholder1"],

以下示例是使用属于一个或多个组(a,b,c,d)的数据元素的简单实现:



var data = [
 { groups: ["a","b","c"] },
 { groups: ["b"] },
 { groups: ["a","c","d"] },
 { groups: ["a","d"] },
 { groups: ["a","b"] }
]


var text = d3.select("body")
  .append("div")
  .selectAll("p")
  .data(["a","b","c","d"])
  .enter()
  .append("p")
  .html(function(d) { return "Group: " + d })
  .on("mouseover",function(chosen) {
    // reset all circles:
    d3.selectAll("circle").attr("fill","steelblue");  
    // select all circles and filter if groups array has chosen value:
    d3.selectAll("circle").filter(function(d) { 
        return d.groups.indexOf(chosen) > -1 
      })
      .attr("fill", "red")
  
  })

var svg = d3.select("body")
  .append("svg")
  .attr("width",500)
  .attr("height",200);
  
var circles = svg.selectAll("circle")
  .data(data)
  .enter()
  .append("circle")
  .attr("cx",function(d,i) { return i * 100 + 50 })
  .attr("cy", 100)
  .attr("r",20)
  .attr("fill","steelblue");

p {
  margin: 5px;
  padding: 10px;
  cursor: pointer;
  display: inline-block;
  background: #ccc;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
&#13;
&#13;
&#13;