如何选择特定的d3节点组元素

时间:2017-11-20 05:05:40

标签: javascript d3.js

我有一个带有多个节点的D3 v4力模拟。每个节点都有一个组。当我将鼠标悬停在该组中的一个元素(一个不可见的圆圈)上时,我想要一个其他元素(该特定节点上的红色圆圈,我只给出了#34;后面的圆圈")来做某事。目前这就是我所拥有的,但它对所有节点都有效,而不仅仅是我悬停在其上的元素。

this.node = this.d3Graph.selectAll(null)
.data(this.props.nodes)
.enter()
.append("g")
.attr("class", "nodes");

this.node.append("circle")
.attr("id", "backCircle")
.attr("r", 60)
.attr("fill", "red")


this.node.append("svg:image")
        .attr("xlink:href", function(d) { return d.img })
        .attr("height", 60)
        .attr("width", 60)
        .attr("x", -30)
        .attr("y", -30)


          this.node.append("circle")
            .attr("r", 60)
            .attr("fill", "transparent")
            .on( 'mouseenter', function(d) {
              d.r = 65;
              this.node.select("#backCircle")
              .transition()
              .attr("r", 80);

            }.bind(this))

2 个答案:

答案 0 :(得分:2)

除此之外,还有两个重要提示:

  1. 请勿在SVG中使用"transparent"
  2. ID 唯一。因此,请改用类(或通过标记名称选择)
  3. 回到你的问题:

    有几种方法可以根据兄弟圈元素选择圆形元素。第一个是使用this.parentNode向上再次向下移动DOM。第二个,如果您确切知道兄弟姐妹的顺序,则使用previousSibling

    在以下演示中,每组有3个元素:圆形,文本和矩形。将鼠标悬停在矩形上将选择圆圈。

    首先是this.parentNode的选项。在你的情况下:

    d3.select(this.parentNode).select(".backCircle")
    

    将鼠标悬停在方块上:

    
    
    var svg = d3.select("svg");
    var data = [50, 150, 250];
    var g = svg.selectAll(null)
      .data(data)
      .enter()
      .append("g")
      .attr("transform", function(d) {
        return "translate(" + d + ",75)"
      });
    
    g.append("circle")
      .attr("class", "backCircle")
      .attr("r", 40)
      .attr("fill", "teal")
    
    g.append("text")
      .attr("font-size", 20)
      .attr("text-anchor", "middle")
      .text("FOO");
    
    g.append("rect")
      .attr("x", 20)
      .attr("y", 20)
      .attr("width", 20)
      .attr("height", 20)
      .style("fill", "firebrick")
      .on("mouseenter", function() {
        d3.select(this.parentNode).select(".backCircle")
          .transition()
          .attr("r", 50)
      }).on("mouseleave", function() {
        d3.select(this.parentNode).select(".backCircle")
          .transition()
          .attr("r", 40)
      })
    
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <svg></svg>
    &#13;
    &#13;
    &#13;

    然后,选项previousSibling(此处,您甚至不需要设置课程)。在你的情况下:

    d3.select(this.previousSibling.previousSibling)
    

    将鼠标悬停在方块上:

    &#13;
    &#13;
    var svg = d3.select("svg");
    var data = [50, 150, 250];
    var g = svg.selectAll(null)
      .data(data)
      .enter()
      .append("g")
      .attr("transform", function(d) {
        return "translate(" + d + ",75)"
      });
    
    g.append("circle")
      .attr("r", 40)
      .attr("fill", "teal")
    
    g.append("text")
      .attr("font-size", 20)
      .attr("text-anchor", "middle")
      .text("FOO");
    
    g.append("rect")
      .attr("x", 20)
      .attr("y", 20)
      .attr("width", 20)
      .attr("height", 20)
      .style("fill", "firebrick")
      .on("mouseenter", function() {
        d3.select(this.previousSibling.previousSibling)
          .transition()
          .attr("r", 50)
      }).on("mouseleave", function() {
        d3.select(this.previousSibling.previousSibling)
          .transition()
          .attr("r", 40)
      })
    &#13;
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <svg></svg>
    &#13;
    &#13;
    &#13;

    PS:请记住,由于我没有使用对象,因此我的代码段中不需要bind(this)

答案 1 :(得分:1)

我认为您需要从其处理程序中选择触发mouseenter事件的节点。

      this.node.append("circle")
        .attr("r", 60)
        .attr("fill", "transparent")
        .on( 'mouseenter', function(d) {
          var mouseenterNode = d3.select(this) 
          mouseenterNode.attr("r", 65);
          mouseenterNode.select("#backCircle")
          .transition()
            .attr("r", 80);
        }.bind(this))