0
votes

I am a beginner in d3 and still have to learn a lot. I would like to code an an animated pie chart with hyper-linked slices. My current solution is not very elegant and clean. I have bound the data to the "slice" group - at every update of the data the "slice" groups get refreshed by D3.

But I must remove the href element "by hand", and under the href element are the path element from the pie ... so I delete path elements in a hard manner.

How do I implement my Update-Function that I can have such an animation at the end: http://bl.ocks.org/mbostock/1346410 (Best practice?)

function initPieChart() {
    var radius = Math.min(width, height) / 2;

    pie = d3.layout.pie()
        .sort(null)
        .value(function (d) { return d.Value; });

    color = d3.scale.category20();

    arc = d3.svg.arc()
        .startAngle(function (d) { return d.startAngle; })
        .endAngle(function (d) { return d.endAngle; })
        .innerRadius(0)
        .outerRadius(radius);

    svg_pie = d3.select("#pieChart").append("svg:svg")
        .attr("width", width)
        .attr("height", height);

    svg_rect = d3.select("#rects").append("svg:svg")
        .attr("width", width)
        .attr("height", height);

    pie_holder = svg_pie.append("svg:g")
        .attr("class", "pie_holder")
        .attr("transform", "translate(" + (width / 2) + "," + (height / 2) + ")");

}

function updatePieChart() {

    var slice_group = pie_holder.selectAll("g.slice").data(newPieData);
    slice_group.enter().append("svg:g");
    slice_group.attr("class", "slice");
    slice_group.exit().remove();

    slice_group.selectAll("a").remove();
    var slice_link = slice_group.append("svg:a")
        .attr("xlink:href", "http://stackoverflow.com");
    var slice_path = slice_link.append("svg:path")
        .attr("stroke", "white")
        .attr("stroke-width", 0.5)
        .attr("fill", function (d, i) { return color(i); })
        .attr("d", arc);

}


....
    <g class="pie_holder" transform="translate(480,250)">
      <g class="slice">
        <a xlink:href="http://stackoverflow.com">
          <path stroke="white" stroke-width="0.5" fill="#1f77b4" d="M1.5307579422779716e-14,-250A250,250 0 1,1 -20.289681381857783,249.1752973900557L0,0Z"></path>
          <title>Kst.1 119</title>
        </a>
      </g>
....
1
You could use nested selections to bind data to the paths directly. Apart from that, your code doesn't look bad to me. The source for the example you've linked to is available and tells you how to animate the transitions. - Lars Kotthoff

1 Answers

0
votes

You could and should avoid coding hyperlinks in the way you mentioned.

Better way would be to create click handler, similar to this: (code is from another project, I attach it for demonstration purposes, and you can adjust it of course easily)

  var node = vis.selectAll("g.node")
      .data(nodes, function(d) { return d.id || (d.id = ++i); })
      .style("cursor", "pointer")
      .on("click", function() {
          window.open("http://www.stackoverflow.com", '_blank').focus();
      });