将类分配给相同绑定数据的所有元素

时间:2017-02-15 09:37:16

标签: javascript d3.js

我有散点图和表格。散点图中的每个圆在表中都有一个对应的行。当我将类应用于圆圈以用于CSS时,我还希望将相同的类分配给相应的表行。它们具有相同的数据值,但附加到单独的元素。

这是我的圈子类事件:

my_circles.each(function(d,i) {
    if (my_bool===true) {
        d3.select(this).classed('selected',true);
        //d3.selectAll('tr').filter(d===???) 
    }
});

我试图使用过滤器只选择匹配d值的表行,但它没有完全解决,我不知道如何完成该行。这让我思考,也许有更好的方法,如帖子标题,为所有绑定到相同数据的元素分配类。

如果除了我的任何想法之外还有其他解决方案,那也没关系。

2 个答案:

答案 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 v4

对于简洁的方法,我更喜欢使用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 v3

如果你还没有使用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;
&#13;
&#13;