equanimity
equanimity

Reputation: 2533

Changing the appearance of circles on mouseover and mouseout (with transitions)

I have a line plot with some circle markers.

enter image description here

I'd like to add some mouseover and mouseout effects to the circles.

Here is my code:

let linePlot = svg.selectAll('.line')
    .data(data);

// Draws the line
linePlot
    .enter()
    .append('path')
    .merge(linePlot)
    .datum(data)
    .transition()
    .duration(800)
    .attr('class', 'line')
    .attr('d', d3.line()
        .x(function (d) { return xScale(d.YEAR); })
        .y(function (d) { return yScale(d[metricType]); })
        .curve(d3.curveMonotoneX)
    );

linePlot
    .exit()
    .remove();

// Draws the circles
let circles = svg.selectAll('circle')
    .data(data);

circles
    .enter()
    .append('circle')
    .merge(circles)
    .data(data)
    .transition()
    .duration(800)
    .attr('fill', '#5e855d')
    .attr('stroke', '#49614a')
    .attr('cx', function(d) { return xScale(d.YEAR)})
    .attr('cy', function(d) { return yScale(d[metricType])})
    .attr('r', 6)
;

circles
    .on('mouseover', function() {
        d3.select(this)
            .transition()
            .duration(2000)
            .attr('fill', 'red')
    })
    .on('mouseout', function() {
        d3.select(this)
            .transition()
            .duration(2000)
            .attr('fill', 'blue')
    })

circles
    .exit()
    .remove();

The mouseout and mouseover effects are not working.

Any assistance would be greatly appreciated.

Thanks!

Upvotes: 1

Views: 25

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102174

When you do this...

circles
    .enter()
    .append('circle')
    .merge(circles)
    .data(data)
    .transition()
    .duration(800)
    .attr('fill', etc...

...you're basically setting circles as a transition selection, and transitions don't have mouseover as a typename. The only typenames allowed for a transition are:

  • start
  • end
  • interrupt
  • cancel

The idiomatic solution is breaking that chain:

circles.enter()
    .append('circle')
    .merge(circles)
    .data(data);

circles.transition()
    .duration(800)
    .attr('fill', etc...

Now circles is a proper D3 selection, so you can do circles.on('mouseover', etc....

Finally, consider revising that data method after merging, it makes little sense to me.

Upvotes: 1

Related Questions