我有散点图和表格。散点图中的每个圆在表中都有一个对应的行。当我将类应用于圆圈以用于CSS时,我还希望将相同的类分配给相应的表行。它们具有相同的数据值,但附加到单独的元素。
这是我的圈子类事件:
my_circles.each(function(d,i) {
if (my_bool===true) {
d3.select(this).classed('selected',true);
//d3.selectAll('tr').filter(d===???)
}
});
我试图使用过滤器只选择匹配d值的表行,但它没有完全解决,我不知道如何完成该行。这让我思考,也许有更好的方法,如帖子标题,为所有绑定到相同数据的元素分配类。
如果除了我的任何想法之外还有其他解决方案,那也没关系。
答案 0 :(得分:1)
如果绑定到.classed()
的数据与所选圈子的数据匹配,则最简单的解决方案可能是tr
方法检查tr
选项。
my_circles.each(function(d,i) {
if (my_bool===true) {
d3.select(this).classed("selected",true);
d3.selectAll('tr')
.classed("selected", trData => d === trData); // Set class if data matches
}
});
然而,这有点笨拙并且可能非常耗时,因为每次调用此代码时它都会遍历所有tr
。如果这是在一个外部循环中处理多个选定的圆圈 - 如comment中所述 - 事情会变得更糟。
对于简洁的方法,我更喜欢使用D3的local variables(v4的新手)来存储圆和表行之间的引用。这只需要一次性设置,这取决于你的其余代码,但可能会有以下几点:
// One-time setup
var tableRows = d3.local();
my_circles.each(function(d) {
var row = d3.selectAll("tr").filter(trData => d === trData);
tableRows.set(this, row); // Store row reference for this circle
});
这将创建一个新的局部变量tableRows
,用于存储每个圆的相应表行的引用。之后,您可以检索对行的引用,而无需进一步迭代。
my_circles.each(function(d,i) {
if (my_bool===true) {
d3.select(this).classed('selected',true);
tableRows.get(this).classed("selected", true); // Use local variable to get row
}
});
如果你还没有使用D3,当然还有其他方法来实现同样的目的。就个人而言,我更希望使用WeakMap
来存储引用。因为WeakMap
的API还具有类似于d3.local
的get和set方法,所以您需要做的就是更改创建本地引用存储的行,同时保持上述代码的其余部分:
// var tableRows = d3.local();
var tableRows = new WeakMap(); // use a WeakMap to hold the references
答案 1 :(得分:0)
您可以将dataIndex用于此目的。这是相同的代码段。
var data = ["A", "B", "C"];
var color = d3.scale.category10();
var container = d3.select("body")
.append("svg")
.attr("height", 500)
.attr("width", 500);
var my_circles = container.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("name", function(d, i) {
return "circle" + i
})
.attr("r", 10)
.attr("cx", function(d, i) {
return (i + 1) * 50
})
.attr("cy", function(d, i) {
return (i + 1) * 50
})
.style("fill", function(d, i) {
return color(i)
});
container.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("name", function(d, i) {
return "rect" + i
})
.attr("width", 15)
.attr("height", 15)
.attr("x", function(d, i) {
return i * 50 + 200
})
.attr("y", function(d, i) {
return (i + 1) * 50
})
.style("fill", function(d, i) {
return color(i)
});
my_circles.each(function(d, i) {
d3.select(this).classed("selected" + i, true);
container.selectAll("[name=rect" + i + "]").classed("selected" + i, true);
});

svg {
border: 1px solid black;
background: black;
}

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