Search code examples
d3.jschord-diagram

Transition chord diagram when one chord has zero value


I'm trying to make the chord diagram in a reusable way. My problem is when transitioning between 2 data-sets, such one data-set contains zero value (means that one chord will be removed). So here is the transition code that I have called to transition:

            changeDataFunction = function(data,selection) { // thisfunction will be called to determine the next drawing function to be called: render() function for the first time of drawing or transition function for the second one.
           if (!chord.matrix()) {
               chord.matrix(data);
               self.render();
           } else {
               var old = {   //save the old value of the diagram for interpolate
                   groups: chord.groups(),
                   chords: chord.chords()
               };
               console.log(old);
               chord.matrix(data);
               transition(old,selection); //call the transition function
           }
        };
function transition(old,selection){
            svg = d3.select(selection).selectAll("svg").data([chord]);
            svg.enter().append("svg")
                .classed("chorddiagram",true);

            arcGroup = svg.select(".arcpath-group").selectAll(".arcpath")
                .data(function(d){ return d.groups(); })
                .enter().append("path")
                .classed("arcpath",true)
                .style("fill",function(d){ return color(d.index);})
                .style("stroke",function(d) { return color (d.index);})
                .attr("d",arc_svg)
                .on("mouseover",fade(0.1))
                .on("mouseout",fade(1));
            arcGroup
                .transition().duration(1500)
                .attrTween("d",arcTween(arc_svg,old));
            arcGroup.exit().remove();

            chordGroup = svg.select(".chordpath-group").selectAll(".chordpath")
                .data(function(d){ return d.chords(); })
                .enter().append("path")
                .classed("chordpath",true)
                .attr("d",chord_svg)
                .style("fill", function(d){ return color(d.target.index);});
            chordGroup
                .transition().duration(1500)
                .style("fill",function(d){
                    return color(d.target.index);
                })
                .attrTween("d", chordTween(chord_svg, old));
            chordGroup.exit().remove();
        }

// Interpolate the arcs
        function arcTween(arc_svg, old) {
            return function(d,i) {
                if (d) {
                    var i = d3.interpolate(old.groups[i], d);
                };
                return function(t) {
                    return arc_svg(i(t));
                }
            }
        }

        // Interpolate the chords
        function chordTween(chord_svg, old) {
            return function(d,i) { //I think the problem from inside this block of code. The chord doesn't exist then the bug occurred. But I'm not good at interpolate so I don't know how to fix this.
                var i = d3.interpolate(old.chords[i], d);
                return function(t) {
                    return chord_svg(i(t));
                }
            }
        }

Thank you for your attention and helping!


Solution

  • So I have solved my own question above by using the arcTween and chordTween function of @AmeliaBR to replace my old one: https://stackoverflow.com/a/21923560/3128209 Thank you so much!