squishy
squishy

Reputation: 374

D3 enable mouseover AFTER transition

How can I add a d3-tip / mouseover event AFTER a transition on a histogram / bar chart?

I create a bar chart / plot:

canvas.call(tip);

var sampleBars = canvas.selectAll(".sampleBar")
  .data(data)
.enter().insert("rect", ".axis")
    .attr("class", "sampleBar")
    .attr("x", function(d) { return x(d.x) + 1; })
    .attr("y", function(d) { return y(d.y); })
    .attr("width", x(data[0].dx + data[0].x) - x(data[0].x) - 1)
    .attr("height", 0)
    .transition()
    .duration(2500)
    .delay(500)
    .attr("height", function(d) { return height - y(d.y); });

I want to add:

sampleBars
        .on('mouseover', tip.show)
        .on('mouseout', tip.hide);

And this is the tip:

    var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) { 
    return "<span style='color:white'>" + d3.round((d.y * 100)) 
    + "%" + "</span>" + " infected"; })

So that the mouseover event occurs after the transition is complete. But I get the error:

Uncaught TypeError: undefined is not a function

The error is for the line:

.on('mouseover', tip.show)

I think there is a simple flaw in my logic. I seem to be confused about how these events or attributes interact with each other.

Again: I want to 'activate' the mouseover tip AFTER the transition is complete so that after the transition does its thing the tip will appear if the user puts their mouse over each bar. I have no problem creating the mouseover event and having it work on user mouseover to display the data I want, but I am having no luck with making this work with a transition of those bars.

Upvotes: 2

Views: 2076

Answers (1)

Steve P
Steve P

Reputation: 19377

Instead of adding/removing events, one approach is to simply set/unset the pointer-events attribute so that the events don't fire when you want them suppressed.

var myselection = d3.select('body')
  .append('svg').attr({height: 200, width: 200})
  .append('circle')
  .attr( {cx: 100, cy: 100, r: 0})
  .attr('pointer-events', 'none')
  .on('mouseover', function() { console.log('mouseover'); })
  .on('mouseout', function() { console.log('mouseout'); })

myselection
  .transition().duration(4000).attr('r', 100)
  .transition().attr('pointer-events', 'auto')
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

If you have the console window open you'll notice that mouse over/out logs nothing until the circle stops growing.

Upvotes: 5

Related Questions