<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
    ;

    //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);
    });
    */

    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>
