0

I use this code:

d3.selectAll('rect')
.on('mousemove',function(){d3.select(this).attr("fill", "red");})
.on('mouseleave',function(){d3.select(this).attr("fill", "black");})
.on('click', function(){alert(this.tagName);})
;
d3.selectAll('text')
.on('mousemove',function(){d3.select(this.parentNode).select('rect').on('click').apply(this);})
;
.chart rect {
  fill: steelblue;
}

.chart text {
  fill: white;
  font: 10px sans-serif;
  text-anchor: end;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.4/d3.min.js"></script>
<svg class="chart" width="420" height="120">
  <g transform="translate(0,0)">
    <rect width="40" height="19"></rect>
    <text x="37" y="9.5" dy=".35em">4</text>
  </g>
  <g transform="translate(0,20)">
    <rect width="80" height="19"></rect>
    <text x="77" y="9.5" dy=".35em">8</text>
  </g>
  <g transform="translate(0,40)">
    <rect width="150" height="19"></rect>
    <text x="147" y="9.5" dy=".35em">15</text>
  </g>
  <g transform="translate(0,60)">
    <rect width="160" height="19"></rect>
    <text x="157" y="9.5" dy=".35em">16</text>
  </g>
  <g transform="translate(0,80)">
    <rect width="230" height="19"></rect>
    <text x="227" y="9.5" dy=".35em">23</text>
  </g>
  <g transform="translate(0,100)">
    <rect width="420" height="19"></rect>
    <text x="417" y="9.5" dy=".35em">42</text>
  </g>
</svg>

I expect that when hovering over text element will be triggered event for sibling rect elements and showing message "rect". But the message "text" showed, although code select('rect') must be set "this" referenced to rect element. Why reference to text element is passed to handler?

Interloper
  • 790
  • 7
  • 20
  • It's because of the way you're calling the click handler. You probably want https://stackoverflow.com/questions/9063383/how-to-invoke-click-event-programmaticaly-in-d3 – Lars Kotthoff Aug 24 '15 at 16:46
  • Code "d3.select(this.parentNode).select('rect').on('click')()" also is not works as I want. – Interloper Aug 24 '15 at 18:54

1 Answers1

2

The this you're passing to .apply() refers to the text element that the event was fired for, not for the rect element you've selected afterwards (selecting an element doesn't change this). You need to call the click handler in the new context:

d3.selectAll('text')
  .on('mousemove',function(){
    d3.select(this.parentNode).select('rect').each(function() {
      d3.select(this).on("click").apply(this);
    });
  });

Complete demo here.

Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204