Vishnu Suresh
Vishnu Suresh

Reputation: 187

D3 Mouseover and Mouseout

I have created a pie chart using typescript and D3. I would like to highlight the respective sections of the Pie Chart during the mouseover event.my current code is only changing the color of the text,instead of the whole arc. Can someone suggest a solution.

Here's my TypeScript code:

 interface Data {
            
            quantity: number;
            category: string;
        }
        let testData: Data[] = [
            {
                quantity: 25,
                category: 'a'
            },
            {
                quantity: 50,
                category: 'b'
            },
            {
                quantity: 100,
                category: 'c'
            },
            {
                quantity: 200,
                category: 'd'
            },
            {
                quantity: 300,
                category: 'e'
            }];
            drawChart(testData);
function drawChart(data: Data[]) {

    let width = 400,
        height = 400,
        radius = Math.min(width, height) / 2,
        colourValues = d3.scale.category20c();
    
    let arc = d3.svg.arc<d3.layout.pie.Arc<Data>>()
        .innerRadius(0)
        .outerRadius(radius-20);
    let arcHover=d3.svg.arc<d3.layout.pie.Arc<Data>>()
                    .innerRadius(0)
                    .outerRadius(radius+10);
    
    let pie = d3.layout.pie<Data>().value((d: Data):number => d.quantity);

    
    let fill = (d: d3.layout.pie.Arc<Data>): string => colourValues(d.data.category);
    let tf  = (d: d3.layout.pie.Arc<Data>): string => `translate(${arc.centroid(d)})`;
    let text = (d: d3.layout.pie.Arc<Data>): string => d.data.category;
    
    let svg = d3.select('.pie-chart').append('svg')
        .attr('width', width)
        .attr('height', height)
        .append('g')
        .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
    
    let g = svg.selectAll('.arc')
        .data(pie(data))
        .enter().append('g').attr('class', 'arc')
        .data(pie(data))
        .on("mouseover",function(d)
        {
        d3.select(this).attr('fill','blue').attr('d',arcHover)}) 
        .on("mouseout",function(d)
    {
        d3.select(this).attr('fill','black').attr('d',arc)
    });  
    g.append('path').attr('d', arc).attr('fill', fill)           
    g.append('text').attr('transform', tf).text(text);
  
}

Here's my HTML :

 <head>    
</head>
    <body>
        <div class="pie-chart"></div>
        <script src="https://d3js.org/d3.v3.min.js"></script>
        <script src="piechart1.js"></script>
    </body>

Upvotes: 3

Views: 4363

Answers (1)

Mikhail Shabrikov
Mikhail Shabrikov

Reputation: 8509

You should attach your event-handler functions on path element, not on the g:

g.append('path')
  .on("mouseover", function(d) {
    d3.select(this).attr('fill', 'blue').attr('d', arcHover)
  })
  .on("mouseout", function(d) {
    d3.select(this).attr('fill', 'black').attr('d', arc)
  });

Another way - attach event-handlers on g element and change color for text and path separately:

let g = svg.selectAll('.arc')
  .data(pie(data))
  .enter().append('g').attr('class', 'arc')
  .data(pie(data))
  .on("mouseover", function(d) {
    d3.select(this).select('path').attr('fill', 'blue').attr('d', arcHover);
    d3.select(this).select('text').attr('fill', 'blue')
  })
  .on("mouseout", function(d) {
    d3.select(this).select('path').attr('fill', 'black').attr('d', arc);
    d3.select(this).select('text').attr('fill', 'black')
  });

Here - https://jsfiddle.net/tafxrkdL/1/ - an example with pure JavaScript (not TypeScript).

Upvotes: 6

Related Questions