<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<style>
#slice_interaction_chart_placeholder {
    text-align: center;
    color:#fff;
    position: relative;
    height: 100%;
    width: 100%;
}
.dependencyWheel {
    font: 10px sans-serif;
}
form .btn-primary {
    margin-top: 25px;
}
.labeltext {
    color: #fff;
}
#circle circle {
    fill: none;
    pointer-events: all;
}
path.chord {
    stroke: #000;
    stroke-width: .10px;
    transition: opacity 0.3s;
}
#circle:hover path.fade {
    opacity: 0;
}
a {
    text-decoration: none;
    border-bottom: 1px dotted #666;
    color: #999;
}
.more a {
    color: #666;
}
.by a {
    color: #fff;
}
a:hover {
    color: #45b8e2;
}
a:not(:hover) {
    text-decoration: none;
}
text {
    fill: black;
}
svg {
    font-size: 12px;
    font-weight: bold;
    color: #999;
    font-family:'Arial', sans-serif;
    min-height: 100%;
    min-width: 100%;
}
button:disabled {
    color:red;
    background-color: lightyellow;
}
.sliceinteractions_column {
  display: table-cell;
  padding: 10px;
}
#interactions_function {
  width: 125px;
}

</style>

<div class="row">
    <div class="sliceinteractions_column">
    <select id="interactions_function">
        <option value="networks">networks</option>
        <option value="users">users</option>
        <option value="owner sites">sites</option>
        <option value="sliver_sites">sliver_sites</option>
        <option value="sliver_nodes">sliver_nodes</option>
    </select>
    </div>
    <div class="sliceinteractions_column">
    <h3 id="sliceEngagementTitle">Slice Interactions</h3>
    </div>
</div>

<div id="slice_interaction_chart_placeholder"></div>

<script>

// Chord Diagram for showing Collaboration between users found in an anchor query
// Collaboration View
//

var width = 600,
    height = 600,
    outerRadius = Math.min(width, height) / 2 - 100,
    innerRadius = outerRadius - 18;

//create number formatting functions
var formatPercent = d3.format("%");
var numberWithCommas = d3.format("0,f");

//define the default chord layout parameters
//within a function that returns a new layout object;
//that way, you can create multiple chord layouts
//that are the same except for the data.
function getDefaultLayout() {
    return d3.layout.chord()
    .sortSubgroups(d3.descending)
    .sortChords(d3.ascending);
}
var last_layout; //store layout between updates
var g;
var arc;
var path;

function init_visualization() {
    arc = d3.svg.arc()
        .innerRadius(innerRadius)
        .outerRadius(outerRadius);

    path = d3.svg.chord()
        .radius(innerRadius);


    /*** Initialize the visualization ***/
    g = d3.select("#slice_interaction_chart_placeholder").append("svg")
            .attr("width", width)
            .attr("height", height)
        .append("g")
            .attr("id", "circle")
            .attr("transform",
                  "translate(" + width / 2 + "," + height / 2 + ")");
    //the entire graphic will be drawn within this <g> element,
    //so all coordinates will be relative to the center of the circle

    g.append("circle")
        .attr("r", outerRadius);
}

$( document ).ready(function() {
    init_visualization();
    $('#interactions_function').change(function() {
         updateInteractions();
     });
    updateInteractions();
});

function updateInteractions() {
 $( "#sliceEngagementTitle" ).html("<h3>Loading...</h3>");
 $.ajax({
    url : "/admin/sliceinteractions/" + $("#interactions_function :selected").text() + "/",
    dataType : 'json',
    type : 'GET',
    success: function(newData)
    {
        $( "#sliceEngagementTitle" ).html("<h3>" + newData["title"] + "</h3>");
        updateChords(newData["groups"], newData["matrix"], newData["objectName"])
    }
   });
}


/* Create OR update a chord layout from a data matrix */
function updateChords( users, matrix, objectName ) {

    /* Compute chord layout. */
    layout = getDefaultLayout(); //create a new layout object
    layout.matrix(matrix);
 
    /* Create/update "group" elements */
    var groupG = g.selectAll("g.group")
        .data(layout.groups(), function (d) {
            return d.index; 
            //use a key function in case the 
            //groups are sorted differently between updates
        });
    
    groupG.exit()
        .transition()
            .duration(1500)
            .attr("opacity", 0)
            .remove(); //remove after transitions are complete

    var newGroups = groupG.enter().append("g")
        .attr("class", "group");
    //the enter selection is stored in a variable so we can
    //enter the <path>, <text>, and <title> elements as well

    
    //Create the title tooltip for the new groups
    newGroups.append("title");
    
    //Update the (tooltip) title text based on the data
    groupG.select("title")
        .text(function(d, i) {
            return "Slice (" + users[i].name +
                ") "
                ;
        });

    //create the arc paths and set the constant attributes
    //(those based on the group index, not on the value)
    newGroups.append("path")
        .attr("id", function (d) {
            return "group" + d.index;
            //using d.index and not i to maintain consistency
            //even if groups are sorted
        })
        .style("fill", function (d) {
            return users[d.index].color;
        });
    
    //update the paths to match the layout
    groupG.select("path") 
        .transition()
            .duration(1500)
            .attr("opacity", 0.5) //optional, just to observe the transition
        .attrTween("d", arcTween( last_layout ))
       //     .transition().duration(100).attr("opacity", 1) //reset opacity
        ;
    
    //create the group labels
    newGroups.append("svg:text")
        .attr("xlink:href", function (d) {
            return "#group" + d.index;
        })
        .attr("dy", ".35em")
        .attr("color", "#fff")
        .text(function (d) {
            return users[d.index].name;
        });

    //position group labels to match layout
    groupG.select("text")
        .transition()
            .duration(1500)
            .attr("transform", function(d) {
                d.angle = (d.startAngle + d.endAngle) / 2;
                //store the midpoint angle in the data object
                
                return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")" +
                    " translate(" + (innerRadius + 26) + ")" + 
                    (d.angle > Math.PI ? " rotate(180)" : " rotate(0)"); 
                //include the rotate zero so that transforms can be interpolated
            })
            .attr("text-anchor", function (d) {
                return d.angle > Math.PI ? "end" : "begin";
            });
    
    
    /* Create/update the chord paths */
    var chordPaths = g.selectAll("path.chord")
        .data(layout.chords(), chordKey );
            //specify a key function to match chords
            //between updates
        
    
    //create the new chord paths
    var newChords = chordPaths.enter()
        .append("path")
        .attr("class", "chord");
    
    // Add title tooltip for each new chord.
    newChords.append("title");
    
    // Update all chord title texts
    chordPaths.select("title")
        .text(function(d) {
            if (users[d.target.index].name !== users[d.source.index].name) {
                return [numberWithCommas(d.source.value),
                        " " + objectName + " in common between \n",
                        users[d.source.index].name,
                        " and ",
                        users[d.target.index].name,
                        "\n"
                        ].join("");
                    //joining an array of many strings is faster than
                    //repeated calls to the '+' operator,
                    //and makes for neater code!
            }
            else { //source and target are the same
                return numberWithCommas(d.source.value)
                    + " " + objectName + " are only in Slice ("
                    + users[d.source.index].name + ")";
            }
        });

    //handle exiting paths:
    chordPaths.exit().transition()
        .duration(1500)
        .attr("opacity", 0)
        .remove();

    //update the path shape
    chordPaths.transition()
        .duration(1500)
        //.attr("opacity", 0.5) //optional, just to observe the transition
        .style("fill", function (d) {
            return users[d.source.index].color;
        })
        .attrTween("d", chordTween(last_layout))
        //.transition().duration(100).attr("opacity", 1) //reset opacity
    ;

    // XXX SMBAKER: The way the text was added with newGroups, it's only
    //   computed when a node is created. This is a problem if we redraw the
    //   graph with a different set of nodes, because the old labels will
    //   stick. So, I added this, which *seems* to cause the labels to be
    //   recomputed.
    groupG.selectAll("text")
        .text(function (d) {
            return users[d.index].name;
        });

    //add the mouseover/fade out behaviour to the groups
    //this is reset on every update, so it will use the latest
    //chordPaths selection
    groupG.on("mouseover", function(d) {
        chordPaths.classed("fade", function (p) {
            //returns true if *neither* the source or target of the chord
            //matches the group that has been moused-over
            return ((p.source.index != d.index) && (p.target.index != d.index));
        });
    });
    //the "unfade" is handled with CSS :hover class on g#circle
    //you could also do it using a mouseout event:
    /*
    g.on("mouseout", function() {
        if (this == g.node() )
            //only respond to mouseout of the entire circle
            //not mouseout events for sub-components
            chordPaths.classed("fade", false);
    });
    */

    // XXX smbaker: there's a bug where if you hilight a slice of the chord
    //   graph, and then update the data, the freshly drawn graph is missing
    //   some of the chords. Flipping the fade bit seems to fix that.
    chordPaths.classed("fade", true);
    chordPaths.classed("fade", false);

    last_layout = layout; //save for next update
    
//  }); //end of d3.json
}

function arcTween(oldLayout) {
    //this function will be called once per update cycle
    
    //Create a key:value version of the old layout's groups array
    //so we can easily find the matching group 
    //even if the group index values don't match the array index
    //(because of sorting)
    var oldGroups = {};
    if (oldLayout) {
        oldLayout.groups().forEach( function(groupData) {
            oldGroups[ groupData.index ] = groupData;
        });
    }
    
    return function (d, i) {
        var tween;
        var old = oldGroups[d.index];
        if (old) { //there's a matching old group
            tween = d3.interpolate(old, d);
        }
        else {
            //create a zero-width arc object
            var emptyArc = {startAngle:d.startAngle,
                            endAngle:d.startAngle};
            tween = d3.interpolate(emptyArc, d);
        }
        
        return function (t) {
            return arc( tween(t) );
        };
    };
}

function chordKey(data) {
    return (data.source.index < data.target.index) ?
        data.source.index  + "-" + data.target.index:
        data.target.index  + "-" + data.source.index;
    
    //create a key that will represent the relationship
    //between these two groups *regardless*
    //of which group is called 'source' and which 'target'
}
function chordTween(oldLayout) {
    //this function will be called once per update cycle
    
    //Create a key:value version of the old layout's chords array
    //so we can easily find the matching chord 
    //(which may not have a matching index)
    
    var oldChords = {};
    
    if (oldLayout) {
        oldLayout.chords().forEach( function(chordData) {
            oldChords[ chordKey(chordData) ] = chordData;
        });
    }
    
    return function (d, i) {
        //this function will be called for each active chord
        
        var tween;
        var old = oldChords[ chordKey(d) ];
        if (old) {
            //old is not undefined, i.e.
            //there is a matching old chord value
            
            //check whether source and target have been switched:
            if (d.source.index != old.source.index ){
                //swap source and target to match the new data
                old = {
                    source: old.target,
                    target: old.source
                };
            }
            
            tween = d3.interpolate(old, d);
        }
        else {
            //create a zero-width chord object
/*          XXX SMBAKER: the code commented out below was causing an error,
                  so I replaced it with the following code from stacktrace
            if (oldLayout) {
                var oldGroups = oldLayout.groups().filter(function(group) {
                        return ( (group.index == d.source.index) ||
                                 (group.index == d.target.index) )
                    });
                old = {source:oldGroups[0],
                           target:oldGroups[1] || oldGroups[0] };
                    //the OR in target is in case source and target are equal
                    //in the data, in which case only one group will pass the
                    //filter function

                if (d.source.index != old.source.index ){
                    //swap source and target to match the new data
                    old = {
                        source: old.target,
                        target: old.source
                    };
                }
            }
            else old = d;

            var emptyChord = {
                source: { startAngle: old.source.startAngle,
                         endAngle: old.source.startAngle},
                target: { startAngle: old.target.startAngle,
                         endAngle: old.target.startAngle}
            };
            tween = d3.interpolate( emptyChord, d );*/

            //create a zero-width chord object
            var emptyChord = {
                source: { startAngle: d.source.startAngle,
                         endAngle: d.source.startAngle},
                target: { startAngle: d.target.startAngle,
                         endAngle: d.target.startAngle}
            };
            tween = d3.interpolate( emptyChord, d );
        }

        return function (t) {
            //this function calculates the intermediary shapes
            return path(tween(t));
        };
    };
}


/* Activate the buttons and link to data sets */
d3.select("#ReadersButton").on("click", function () {
    updateChords( "#readinfo" );
    //replace this with a file url as appropriate
    
    //enable other buttons, disable this one
    disableButton(this);
});

d3.select("#ContributorsButton").on("click", function() {
    updateChords( "#contributorinfo" );
    disableButton(this);
});

d3.select("#AllUsersButton").on("click", function() {
    updateChords( "#allinfo" );
    disableButton(this);
});
function disableButton(buttonNode) {
    d3.selectAll("button")
        .attr("disabled", function(d) {
            return this === buttonNode? "true": null;
        });
}

</script>
