d3.select(this) works on mouseover, but not on function called in mouseover

前端 未结 3 1873
感情败类
感情败类 2021-02-05 23:29

I am new to javascript and currently struggling with selecting the this object while trying to do a d3 selection. I\'ve made the following example, with a funct

3条回答
  •  太阳男子
    2021-02-06 00:08

    Although Andrew's answer might be the best fit if you take the question literally, I would like to add my two cents to it. Your real problem does not seem to be to get a hold of this, but to repeatedly get access to that element to apply you manipulations. Since fiddling around with this can be a pain in JavaScript it might be worth taking a slightly different approach by directly passing the selection instead. This will also improve performance as there is no need to re-select this over and over again.

    First, let us slightly refactor your changeFont() function to accept a selection object.

    function changeFont(selection) {
      selection
        .attr('font-size', '2em');
    }
    

    Note, how this makes the function more generally applicable as it does not make any assumptions about the selection passed into it. It could be your d3.select(this), a selection containing multiple elements or any other D3 selection object. Additionally, you do not need to preserve the previous this scope.

    There are basically two ways of calling this function.

    1. The obvious one will directly pass the selection as an argument when calling the function:

      const d3This = d3.select(this);
      changeFont(d3This);
      
    2. Fortunately, there is a more elegant way of doing it by resorting to D3's own selection.call() which even allows for method chaining if you need to do multiple calls on the same selection.

      function changeFont(selection) { selection.attr("font-size", "2em"); }
      function changeFill(selection) { selection.attr("fill", "limegreen"); }
      function changeOpacity(selection) { selection.attr("opacity", "0.1"); }
      
      // ...
      .on("mouseover", function() {
        // Call the functions for this element.
        d3.select(this)
          .call(changeFont)
          .call(changeFill)
          .call(changeOpacity);
      
        // Instead, you could also apply the same pattern to all texts.
        d3.selectAll("text")
          .call(changeFont)
          .call(changeFill)
          .call(changeOpacity);
      
      }
      

提交回复
热议问题