0

Problem:

I'm attempting to bring the inner circle elements to the forefront on mouseover, and then restore them on mouseout.

Fiddle:

https://jsfiddle.net/jo8xd3mo/1/

Code:

var dataset = {
  inside: [53245, 28479, 19697, 24037, 40245],
  outside: [40245, 25203, 65232, 53092, 12035]
};

var $container = $('.modular-chart'),
  width = $container.width(),
  height = $container.height(),
  cwidth = 80;

var color = d3.scale.category20c();

var pie = d3.layout.pie()
  .sort(null);

var arc = d3.svg.arc();

var svg = d3.select(".pie-chart").append("svg")
  .attr("width", "100%")
  .attr("height", "100%")
  .attr('viewBox', '0 0 ' + Math.min(width, height) + ' ' + Math.min(width, height))
  .attr('preserveAspectRatio', 'xMinYMin')
  .append("g")
  .attr("transform", "translate(" + Math.min(width, height) / 2 + "," + Math.min(width, height) / 2 + ")")

var gs = svg.selectAll("g").data(d3.values(dataset)).enter().append("g");

var path = gs.selectAll("path")
  .data(function(d) {
    return pie(d);
  })
  .enter().append("path")
  .attr("fill", function(d, i) {
    return color(i);
  })
  .attr("d", function(d, i, j) {
    return arc.innerRadius(cwidth + 280).outerRadius(cwidth * (j + 2.5))(d);
  })
  .on("mouseover", function(d, i, j) {
      d3.select(this)
        .transition()
        .duration(500)
        .style("fill", "white")
        .attr("d", d3.svg.arc().innerRadius(cwidth + 300).outerRadius(cwidth * (j + 2.5)))
  })
  .on("mouseout", function(d, i, j) {
    d3.select(this)
      .transition()
      .duration(500)
      .style("fill", color(i))
      .attr("d", d3.svg.arc().innerRadius(cwidth + 280).outerRadius(cwidth * (j + 2.5)))
  });

Analysis:

I understand that z-index does not exist for SVG elements and items are layered according to their order in the DOM. I've located various solutions that don't seem to work for my use-case. If anyone has any suggestions or insights, I'm all ears. I've been struggling with this for a few hours and could use another pair of eyes. Thank you!

Community
  • 1
  • 1
daveycroqet
  • 2,667
  • 7
  • 35
  • 61
  • 1
    How did the solutions not work for you? – Lars Kotthoff Apr 28 '16 at 21:09
  • The top two answers both rely on placing the entire inner ring on top (either by D3's sort or by grouping the elements, respectively). See here for example: https://jsfiddle.net/jo8xd3mo/3/ This is not the behavior I am seeking -- I only want the specific path (arc) being hovered over to be brought to the front and animated. – daveycroqet Apr 29 '16 at 07:04
  • what's stopping you from splitting the svg into several parts and each in a separate svg with different z-indices to work with? – paradite Apr 29 '16 at 08:06
  • @paradite If you are suggesting that I should be creating multiple pie charts and then stacking them on one another, that is not a solution I wish to pursue. The entire point of this exercise is to use a single SVG. – daveycroqet May 01 '16 at 00:40
  • @daveycroqet then it would be a challenge to implement such behavior as svg lacks intrinsic support for something like `z-index`, all layering in svg depends on the ordering the layers, so you have to dynamically cut and paste the layers into different positions. – paradite May 01 '16 at 01:06
  • @daveycroqet what i am suggesting is not entirely novel, it is a common practice to stack the layers in html. for convenience, you could have your basic static layer at bottom, and have another layer on top which only shows the content to be displayed on hover. in this way, you don't have to modify the bottom layer each time, instead, just change the top layer. – paradite May 01 '16 at 01:08

0 Answers0