简体   繁体   English

querySelectorAll是在多个图表中选择元素的好方法吗?

[英]Is querySelectorAll a good way to select elements in multiple charts?

I would like to highlight elements from the same dimension (Country in this example) in multiple charts. 我想在多个图表中突出显示来自同一维度(此示例中为国家/地区)的元素。 Assigning a class to each country at the point of generation of rect or circle and then using querySeletorAll to find all matching elements seems to work, but I wonder if there is a better way. 在生成rectcircle为每个国家/地区分配一个类,然后使用querySeletorAll查找所有匹配的元素似乎可行,但是我想知道是否有更好的方法。 This feels a little hack-y. 感觉有点。

Please see this block for a working demo. 请查看此以获取有效的演示。

Both the bar chart and the scatter have classes assigned to their elements ( rect and circle ) in the same way: 条形图和散点图都具有以相同方式分配给它们的元素( rectcircle )的类:

var enter = svgContainer.selectAll('rect')
  .data(data)
  .enter().append('rect')
  .attr('class', function(d) { return "mycharts_bars_" + d.Country; })

And then the highlight on hover does this: 然后悬停时的突出显示是:

  .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');}
    })

As you can see in the source code , d3.selectAll already uses document.querySelectorAll internally: 如您在源代码中所看到的, 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);
}

So, you can safely use selectAll , which makes your code more idiomatic for D3 programmers. 因此,您可以安全地使用selectAll ,这对于D3程序员来说使您的代码更加惯用。

However, there are some issues in your code: 但是,您的代码中存在一些问题:

First, you don't need that var hover_value = this.__data__.Country; 首先,您不需要var hover_value = this.__data__.Country; . You already have the datum as the first argument! 您已经将基准作为第一个参数! Therefore, it can be just d.Country . 因此,它可以只是d.Country

Secondly, you don't need to deal with classes if you don't want, just select the element. 其次,如果不需要,则不需要处理类,只需选择元素。 You can use classes if you want, that's not a big problem, but you definitely don't need that for...of loop. 您可以根据需要使用类,这不是什么大问题,但是for...of循环,您绝对不需要。 As a rule of thumb, do not use loops in a D3 code (there are specific situations where they are needed, but not this one). 根据经验,请勿在D3代码中使用循环(在某些特定情况下需要使用循环,但不需要这种情况)。

All that being said, the function can be simply this: 综上所述,该函数可以简单地是这样的:

d3.selectAll("circle, rect").attr("fill", function(e) {
    return e.Country === d.Country ? "pink" : "grey"
});

Or, since only the rectangle hovered over will change colour: 或者,因为仅将鼠标悬停在矩形上会更改颜色:

d3.select(this).attr("fill", "pink");
d3.selectAll("circle").attr("fill", function(e) {
    return e.Country === d.Country ? "pink" : "grey"
});

As a side note, this will change all selected elements in the page. 附带说明,这将更改页面中所有选定的元素。 I'm doing this only because, in your example, you have very few elements. 我这样做只是因为在您的示例中,您只有很少的元素。 If in your real chart you have hundreds of elements a better solution is first filtering them and after that applying the changes (both on mouseover and mouseout ), which gives you better performance. 如果您的真实图表中有数百个元素,那么更好的解决方案是先过滤它们,然后再应用更改( mouseovermouseout ),这样可以提供更好的性能。

Here is your code with that change: https://blockbuilder.org/GerardoFurtado/e54f2f0cc711b51be4b400627cac6f51 这是您所做的更改的代码: https : //blockbuilder.org/GerardoFurtado/e54f2f0cc711b51be4b400627cac6f51

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM