<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="instance_sites">instance_sites</option>
        <option value="instance_nodes">instance_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>
