简体   繁体   中英

Only one SVG component rendered when calling a method twice

I use a function to set up event handlers for a click and as it gets fired, the rendition goes as supposed to (fold in on the outer control and fold out on the inner one). Then, clicking it again, the process is retracted. However, the next time I perform the operation, only the outer component changes its size while the inner one does not get affected.

function pieClickOuter(target) {
  var pie = d3.layout.pie()
    .startAngle(0).endAngle(2 * Math.PI)
    .value(function (d) { return d.val; });
  var out = d3.svg.arc().innerRadius(90).outerRadius(99);
  var org = d3.svg.arc().innerRadius(1).outerRadius(1);
  var sub = d3.svg.arc().innerRadius(10).outerRadius(80));

  d3.selectAll("#chart .sector path")
    .transition().duration(1500).attr("d", out);

  var grx = _.chart.selectAll(".subSector")
    .data(pie(getData())).enter().append("g")
    .attr("class", "subSector")
    .on("click", pieClickInner);

  grx.append("path")
    .attr("d", org).style("fill", function (d) { return colors(d.value); });
  grx.selectAll("#chart .subSector path")
    .transition().duration(1000).attr("d", sub);
}

function pieClickInner() {
  d3.selectAll("#chart .sector path")
    .transition().duration(1500)
    .attr("d", d3.svg.arc().innerRadius(80).outerRadius(99));

  outerPieEvents(d3.selectAll("#chart .sector"));

  d3.selectAll("#chart .subSector path")
    .transition().duration(1000)
    .attr("d", d3.svg.arc().innerRadius(1).outerRadius(1));
}

I cannot for my life see why. According to the console output, all the steps are executed, so it seems that the events are re-set up correctly. Still, the inner component seems to disobey.

See this fiddle

I believe that you want something like this .

I changed only 1 name:

var grx = _.chart.selectAll(".subSector")

to

var grx = _.chart.selectAll(".foo")//or any other name

so, we don't select what already exists.

The problem with this approach is that your SVG will have more and more groups each click. But you can avoid this removing them in your pieClickInner() :

d3.selectAll("#chart .subSector path")
    .transition().duration(1000)
    .attr("d", d3.svg.arc().innerRadius(1).outerRadius(1)).remove();
d3.selectAll("#chart .subSector text").attr("opacity", 0).remove();
d3.selectAll("g.subSector").transition().duration(1000).remove();

I, personally, don't like remove() , i'd simply rebind the data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM