这是我的问题:我有一个地图SVG和一个条形图SVG。我想创建一个协调的选择。例如,用户突出显示图形中的条形图,并且地图上与该数据相对应的国家/地区也被突出显示,反之亦然。
现在,我可以突出显示地图上的任何国家,并且相应的相应栏也会突出显示。但是,对于酒吧不一样。当我突出显示一个条时,突出显示一个随机的国家,然后,如工具提示中所显示的,这些国家名称都是混乱的和错误的。
这是地图->条形图突出显示:
<select class="custom-select my-1 mr-sm-2" id="Style" [appAutoFocus]>
<option selected>Choose...</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
...
这是条形图->地图突出显示。这是我无法正常运行的功能。
...
map.selectAll("countries")
.data(b.features)
.enter()
.append("path")
.attr("d", path)
//.style("stroke", "black")
.on("mouseover", function(d) {
activeDistrict = d.properties.ADMIN,
chart.selectAll("rect")
.each(function(d) {
if(d){
if (d.Country == activeDistrict){
console.log("confirmed" + d.Country)
d3.select(this).style("stroke", "blue").style("stroke-width", "3");
}
}
})
这是我的整个JS:
var bars = chart.selectAll(".bars")
.data(data)
.enter()
.append("rect")
.on("mouseover", function(d) {
activeDistrict = d.Country,
//console.log(activeDistrict),
map.selectAll("path")
.data(b.features)
.each(function(d) {
if (d){
//console.log("activeDistrict = " + activeDistrict)
if (d.properties.ADMIN == activeDistrict){
d3.select(this).style("stroke", "blue").style("stroke-width", "3");
console.log(d.properties.ADMIN + "=" + activeDistrict)
}
}
});
答案 0 :(得分:2)
最初绘制国家/地区时,您使用:
map.selectAll("countries")
.data(b.features)
.enter()
.append("path")
由于页面上没有标签为countries
的元素,因此初始选择为空,并且.enter().append("path")
为数据数组中的每个项目创建了一个路径。
但是,当您将鼠标悬停在条形图上时,会按selectAll().data()
顺序重新分配数据,但操作方式有所不同:
map.selectAll("path")
.data(b.features)
...
您的地图中有不是国家/地区的路径:标线和轮廓。现在,我们选择了所有路径并为其分配了新数据。由于选择中的前两个项目是刻度线和轮廓线,因此它们现在具有数据数组中前两个项目的数据。在数据数组中,所有国家/地区都将拥有一个国家的绑定数据,该国家/地区与它们相距两个。这就是为什么将鼠标悬停在条形图上时会突出显示错误数据的原因,以及随后导致国家工具提示错误的原因。
目前尚不清楚为什么更新数据(我看不到它在变化),您可以这样附加国家/地区:
var countries = map.selectAll("countries")
.data(b.features)
.enter()
.append("path")
... continue as before
或
map.selectAll("countries")
.data(b.features)
.enter()
.append("path")
.attr("class","country")
... continue as before
然后在条形图的鼠标悬停功能中使用:
countries.each(....
或
map.selectAll(".country").each(...
如果需要,无论哪种方式,您都可以使用.data()
更新数据。
我会注意到each
方法不是必需的,但在某些情况下可能更可取,因为可以使用它的外观:
var bars = chart.selectAll(".bars")
.data(data)
.enter()
.append("rect")
.on("mouseover", function(d) {
activeDistrict = d.Country,
map.selectAll(".country")
.data(b.features)
.style("stroke", function(d) {
if (d.properties.ADMIN == activeDistrict) return "blue"; else return color(d.properties[currentFood])
})
.style("stroke-width", function(d) {
if (d.properties.ADMIN == activeDistrict) return "3" else return 0;
});
})
...
答案 1 :(得分:-1)
您可以尝试使以下内容在创建内容和选择内容方面更加一致。
地图:
path
在栏中添加一个类以突出显示,而不是设置样式
map.selectAll(".countries")
.data(b.features)
.enter()
.append("path")
.attr("class", "countries")
.attr("d", path)
//.style("stroke", "black")
.on("mouseover", function(d) {
activeDistrict = d.properties.ADMIN,
chart.selectAll(".bars")
.classed("highlight", function(d) {
return d && d.Country === activeDistrict;
});
tooltip.transition() //(this.parentNode.appendChild(this))
.duration(200)
.style("opacity", .9)
.style("stroke-opacity", 1.0);
tooltip.html(d.properties.ADMIN + "<br/>" + d.properties[currentFood] + "(kg/CO2/Person/Year)")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
activeDistrict = d.properties.ADMIN,
chart.selectAll(".bars")
.classed("highlight", false);
tooltip.transition()
.duration(500)
.style("opacity", 0)
.style("stroke-opacity", 0);
})
.style("fill", function(d) { return color(d.properties[currentFood]) });
};
条形图
bars
和country
之间添加空格将一个类添加到地图路径中以突出显示,而不是设置样式
var bars = chart.selectAll(".bars")
.data(data)
.enter()
.append("rect")
.on("mouseover", function(d) {
activeDistrict = d.Country;
//console.log(activeDistrict),
map.selectAll(".countries")
.classed("highlight", function(d) {
return d && d.properties.ADMIN === activeDistrict;
});
tooltip.transition() //(this.parentNode.appendChild(this))
.duration(200)
.style("opacity", .9)
.style("stroke-opacity", 1.0);
tooltip.html(d.Country + "<br/>" + d[currentFood] + "(kg/CO2/Person/Year)")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
map.selectAll(".countries")
.classed("highlight", false);
tooltip.transition()
.duration(500)
.style("opacity", 0)
.style("stroke-opacity", 0);
})
.sort(function(a, b){
return a[currentFood]-b[currentFood]
})
.transition() //add animation
.delay(function(d, i){
return i * 5
})
.duration(1)
.attr("class", function(d){
return "bars " + d.Country;
})
.attr("width", chartWidth / data.length - 1)
.attr("x", function(d, i){
return i * (chartWidth / data.length);
})
.attr("height", function(d){
return yScale(parseFloat(d[currentFood]));
})
.attr("y", function(d){
return chartHeight - yScale(parseFloat(d[currentFood]));
})
.style("fill", function(d){ return color(d[currentFood]); });