我想在多个图表中突出显示来自同一维度(此示例中为国家/地区)的元素。在生成rect
或circle
时为每个国家/地区分配一个类,然后使用querySeletorAll
查找所有匹配的元素似乎可行,但是我想知道是否有更好的方法。感觉有点。
请参阅此block以获得有效的演示。
条形图和散点图都以相同的方式为它们的元素(rect
和circle
)分配了类:
var enter = svgContainer.selectAll('rect')
.data(data)
.enter().append('rect')
.attr('class', function(d) { return "mycharts_bars_" + d.Country; })
然后将鼠标悬停在突出显示位置上
.on("mouseover", function(d) {
var hover_value = this.__data__.Country;
var hover_elems = document.querySelectorAll(`[class*="${hover_value}"]`);
for (let item of hover_elems) {
item.setAttribute('fill', 'hotpink');}
})
答案 0 :(得分:2)
正如您在source code中看到的那样,d3.selectAll
已在内部使用document.querySelectorAll
:
export default function(selector) {
return typeof selector === "string"
? new Selection([document.querySelectorAll(selector)], [document.documentElement])
: new Selection([selector == null ? [] : selector], root);
}
因此,您可以安全地使用selectAll
,这对于D3程序员来说,使代码更加惯用。
但是,您的代码中存在一些问题:
首先,您不需要var hover_value = this.__data__.Country;
。您已经将基准作为第一个参数!因此,它可以只是d.Country
。
第二,如果不需要,则不需要处理类,只需选择元素。您可以根据需要使用类,这不是什么大问题,但是您绝对不需要for...of
循环。根据经验,请勿在D3代码中使用循环(在某些特定情况下需要使用循环,但不需要这种循环)。
话虽如此,功能可以很简单:
d3.selectAll("circle, rect").attr("fill", function(e) {
return e.Country === d.Country ? "pink" : "grey"
});
或者,因为只有悬停在上方的矩形才会改变颜色:
d3.select(this).attr("fill", "pink");
d3.selectAll("circle").attr("fill", function(e) {
return e.Country === d.Country ? "pink" : "grey"
});
请注意,这将更改页面中所有选定的元素。我这样做只是因为在您的示例中,您只有很少的元素。如果您的真实图表中有数百个元素,那么更好的解决方案是首先过滤它们,然后应用更改(在mouseover
和mouseout
上进行更改),这可以为您提供更好的性能。
这是您所做的更改的代码:https://blockbuilder.org/GerardoFurtado/e54f2f0cc711b51be4b400627cac6f51