xxxxxxxxxx
<html lang="en">
<head>
<meta charset="utf-8">
<style>
body{
font: 10px sans-serif;
}
.axis path,
.axis line{
fill:none;
stroke:#000;
shape-rendering: crispEdges;
}
.line {
fill: none;
stroke: black;
stroke-width: 3.5px;
}
.legend{
padding: 5px;
font: 10px sans-serif;
border: .5em solid black;
}
.team line{
stroke: black;
}
.chord path {
fill-opacity: .67;
stroke: #000;
stroke-width: .5px;
}
.ticks {
font-family: sans-serif;
}
</style>
<title>ACC Tournament, Cumulative Wins</title>
<body>
<script type="text/javascript" src="https://d3js.org/d3.v3.js"></script>
</head>
<script type="text/javascript">
var matrix = [
[0,8,10,14,11,10,12],
[9,0,11,12,9,11,5],
[4,8,0,6,10,10,5],
[7,4,3,0,3,6,7],
[3,6,5,3,0,4,9],
[3,3,2,6,4,0,5],
[1,3,2,3,1,1,0],
];
var max_scores = [];
var teams = ["North Carolina","Duke","NC State","Wake Forest","Maryland",
"Virginia","Clemson"];
var colors = ["#99BADD","#00009C","#CE1126","#CFB53B","#FF0000","#0D3268","#FF6300"];
var abbrDict={"Clem":"Clemson","Duke":"Duke","MD":"Maryland","UNC":"North Carolina", "NCS":"NC State", "UVA":"Virginia","WF":"Wake Forest"};
var dataset=0;
var w=932;
var h=490;
var padding = 30;
var color = d3.scale.ordinal() //custom color scale for teams
.range(colors)
.domain(teams);
d3.csv("basketball_data.csv",function(data){
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Year"; }));
data.forEach(function(d) {
d.Year = +d.Year;
d.Clem = +d.Clem;
d.Duke = +d.Duke;
d.MD = +d.MD;
d.UNC = +d.UNC;
d.NCS = +d.NCS;
d.UVA = +d.UVA;
d.WF = +d.WF;
});
var teams = color.domain().map(function(name) {
return {
name: name,
sort_value: 0,
values: data.map(function(d) {
return {date: d.Year, wins: d[name]};
})
};
});
//teams in order of most cumulative wins
teams.sort(function(a,b){
var last_b = b.values.length;
var last_a = a.values.length;
max_scores.push(abbrDict[b.name]);
max_scores.push(b.values[last_b-1].wins);
max_scores.push(abbrDict[a.name]);
max_scores.push(a.values[last_a-1].wins);
return parseFloat(b.values[last_b-1].wins)-parseFloat(a.values[last_a-1].wins);
});
console.log(max_scores);
console.log(teams);
visualize(teams);
});
var visualize = function(team_dict){
var svg = d3.select("body").append("svg")
.attr("width",w+padding*2)
.attr("height",h + padding*2)
.append("g")
.attr("transform", "translate(" + padding + "," + padding + ")");
var chord = d3.layout.chord()
.padding(.05)
.sortSubgroups(d3.descending)
.matrix(matrix);
var innerRadius = Math.min(w, h) * .41;
var outerRadius = innerRadius * 1.1;
var chord_fill = d3.scale.ordinal()
.domain(d3.range(10))
.range(colors);
//line chart code
var xScale = d3.scale.linear().range([padding/2,(w-padding/2)/3]);
var yScale = d3.scale.linear().range([h,padding]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickFormat(d3.format("04d"));
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
var line = d3.svg.line()
.x(function(d){
if(xScale(d.date)<0){ //quick fix to ensure Wake Forest wasn't extending into negatives
return padding;
}
else{
return padding+xScale(d.date);
}
})
.y(function(d){
return yScale(d.wins);
})
xScale.domain([1954,2001]);
yScale.domain([
d3.min(team_dict, function(c) { return d3.min(c.values, function(v) { return v.wins; }); }),
d3.max(team_dict, function(c) { return d3.max(c.values, function(v) { return v.wins; }); })
]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate("+padding+"," + h + ")")
.call(xAxis)
.append("text")
.attr("y",30)
.attr("x",w/4)
.style("font-size",16+"px")
.text("Year");
svg.append("g")
.attr("class", "y axis")
.attr("transform","translate("+padding/2+",0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", -40)
.attr("dy", ".71em")
//.style("text-anchor", "end")
.attr("x",-h/1.4)
.style("font-size",16+"px")
.text("Cumulative Number of Wins");
var team = svg.selectAll("g.team")
.data(team_dict)
.enter()
.append("g")
.attr("class", "team");
team.append("path")
.attr("class", "team line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.name); });
//border for legend
//not apart of the g group/legend class because Clemson's orange square disappears when I do that
svg.append("rect")
.attr("x",padding)
.attr("y",-15)
.attr("width",200)
.attr("height",100)
.attr("style","fill-opacity:0;stroke:black;stroke-width:1.5px");
var legend = svg.append("g")
.attr("class","legend")
.attr("width",200)
.attr("height",100);
//create elements inside of the legend
var gs = legend.selectAll("g.keybox")
.data(team_dict).enter().append("g")
.attr("class","keybox").attr("width",80).attr("height",15).attr("x",function(d,i){
if(i<4){return 65;}
else{return 150;}
})
.attr("y",function(d,i){
if(i<4){return i*20;}
else{return (i-4) * 20;}
})
.attr("id",function(d){
return ""+color(d.name);
});
gs.append("text")
.attr("class","keybox").attr("x",function(d,i){
if(i<4){return 80;}
else{return 163;}
})
//alternate boxes between two columns
.attr("y",function(d,i){
if(i<4){return i*20 +9;}
else{return (i-4)*20 +9;}
})
.attr("stroke-width",0)
.attr("stroke",function(d){
return color(d.name);
})
.text(function(d){
return abbrDict[d.name];
})
.on("mouseover", fade(.1))
.on("mouseout", fade(1));
gs.append("rect")
.attr("class","keybox")
.attr("x",function(d,i){
if(i<4){return 65;}
else{return 150;}
})
.attr("y",function(d,i){
if(i<4){return i*20;}
else{return (i-4) * 20;}
})
.attr("width",10)
.attr("height",10)
.style("fill",function(d){
return color(d.name);
})
.on("mouseover", fade(.1))
.on("mouseout", fade(1));
svg.selectAll("g.keybox").on("mouseover",function(){
var keepName = this.textContent;
var id = this.id;
var selectedLine_box;
var team_color;
var team_wins;
svg.selectAll("path.team.line").style("stroke", function(d){
if(abbrDict[d.name]!=keepName){
return "#C0C0C0";
}
else{
selectedLine_box = d3.select(this);
team_color=color(d.name);
var last = d.values.length;
team_wins = d.values[last-1].wins;
return color(d.name);
}
});
var pathNode = selectedLine_box.node();
var node = selectedLine_box.node();
//console.log(node);
var parent = node.parentNode;
var grandparent = node.parentNode.parentNode;
//console.log(parent);
//console.log(grandparent);
//console.log(parent.childNodes);
grandparent.removeChild(parent);
grandparent.appendChild(parent);
/*
var offset = (.75*w -(w/3))/3;
var center = offset+(w/3);
var center_label = svg.append("text")
.attr("id","center_label")
.attr("x",center)
.attr("y",h/2)
.style("text-anchor","middle")
.style("font-size",30+"px")
.style("font-family","sans-serif")
.text(keepName);
var score = svg.append("text")
.attr("id","score")
.attr("x",center)
.attr("y",h/2+40)
.style("text-anchor","middle")
.style("font-size",35+"px")
.text(""+team_wins);*/
});
svg.selectAll("g.keybox").on("mouseout",function(){
d3.select("#tooltip").remove();
d3.select("#center_label").remove();
d3.select("#score").remove();
svg.selectAll("path.team.line").style("stroke",function(d){
return color(d.name);
});
svg.selectAll("path.rim").style("opacity", 1);
});
svg.selectAll("g.team")
.on("mouseover",function(d){
var lineName;
var label_color;
var team_wins;
svg.selectAll("path.team.line").style("stroke","#C0C0C0"); //set all to gray
var selectedGroup = d3.select(this);
//console.log(this);
var selectedLine = selectedGroup.select("path.team.line");
selectedLine.style("stroke",function(d){ //let active keep color
lineName = abbrDict[d.name]; //full name to be at end of line
label_color=color(d.name);
var last = d.values.length;
team_wins = d.values[last-1].wins;
return color(d.name);
});
this.parentNode.appendChild(this); //brings team to front, must select the path's g parent to reorder it
var offset = (.75*w -(w/3))/3;
//console.log(offset);
var center = offset+(w/3);
var center_label = svg.append("text")
.attr("id","center_label")
.attr("x",center-padding)
.attr("y",h/2)
.style("text-anchor","middle")
.style("font-size",30+"px")
.style("font-family","sans-serif")
.text(lineName);
var score = svg.append("text")
.attr("id","score")
.attr("x",center-padding)
.attr("y",h/2+40)
.style("text-anchor","middle")
.style("font-size",35+"px")
.text(""+team_wins);
})
.on("mouseout",function(){
d3.select("#tooltip").remove();
d3.select("#center_label").remove();
d3.select("#score").remove();
d3.selectAll("path.team").transition().style("stroke",function(d){
return color(d.name);
});
});
//chord code
svg.append("g")
.attr("class","groups")
.attr("transform","translate("+.75*w+","+h/2+")")
.selectAll("path")
.data(chord.groups)
.enter().append("path")
.attr("class","rim")
.style("fill", function(d) { return chord_fill(d.index); })
.style("stroke", function(d) { return chord_fill(d.index); })
.attr("d", d3.svg.arc().innerRadius(innerRadius).outerRadius(outerRadius))
.on("mouseover", fade(.1))
.on("mouseout", fade(1));
var ticks = svg.append("g")
.attr("transform","translate("+.75*w+","+h/2+")")
.attr("class","ticks")
.selectAll("g")
.data(chord.groups)
.enter().append("g").selectAll("g")
.data(groupTicks)
.enter().append("g")
.attr("transform", function(d) {
return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")"
+ "translate(" + outerRadius + ",0)";
});
// Append tick lines
ticks.append("line")
.attr("x1", 1)
.attr("y1", 0)
.attr("x2", 5)
.attr("y2", 0)
.style("stroke", "#000");
// Append tick labels
ticks.append("text")
.attr("x", 8)
.attr("dy", ".35em")
.attr("transform", function(d) { return d.angle > Math.PI ? "rotate(180)translate(-16)" : null; })
.style("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; })
.text(function(d) { return d.label; });
// Append chords
svg.append("g")
.attr("class", "chord")
.attr("transform","translate("+.75*w+","+h/2+")")
.selectAll("path")
.data(chord.chords)
.enter().append("path")
.attr("class","inner")
.attr("d", d3.svg.chord().radius(innerRadius))
.style("fill", function(d) { return d.source.value == d.target.value ? chord_fill(chord_fill.range().length-1) : chord_fill(d.source.index); })
.style("opacity", 1);
// Returns an array of tick angles and labels, given a group.
function groupTicks(d) {
var k = (d.endAngle - d.startAngle) / d.value;
return d3.range(0, d.value, 1).map(function(v, i) {
return {
angle: v * k + d.startAngle,
label: i % 5 ? null : v / 1
};
});
}
function fade(opacity){
return function(g,i){
var target_team;
var goal_index;
svg.selectAll(".chord path")
.filter(function(d){
console.log(chord_fill(i));
target_team_index = colors.indexOf(chord_fill(i));
goal_index = i;
target_team = teams[i];
return d.source.index != i && d.target.index !=i;
})
.transition()
.style("opacity",opacity);
var offset = (.75*w -(w/3))/3;
var center = offset+(w/3);
if(opacity==.1){
var center_label = svg.append("text")
.attr("id","center_label")
.attr("x",center)
.attr("y",h/2)
.style("text-anchor","middle")
.style("font-size",30+"px")
.style("font-family","sans-serif")
.text(target_team);
var target_ind = max_scores.indexOf(target_team);
console.log(target_ind);
var target_wins = max_scores[target_ind+1];
var center_score = svg.append("text")
.attr("id","score")
.attr("x",center)
.attr("y",h/2+40)
.style("text-anchor","middle")
.style("font-size",35+"px")
.text(""+target_wins);
}
if(opacity==1){
d3.select("#center_label").remove();
d3.select("#score").remove();
}
//update scores
d3.selectAll(".logo_score")
.filter(function(d, j) { return j != i; })
.text(function(d, j) {
var target = j < i ? j : j + 1;
return matrix[i][target] + "-" + matrix[target][i]; })
.style("opacity", function() { return opacity == 1 ? 0 : 1; })
.style("border-color", function(d, j) {
var target = j < i ? j : j + 1;
if (matrix[i][target] > matrix[target][i]) return "#090";
else if (matrix[i][target] < matrix[target][i]) return "#930";
else return d3.select("body").style("color"); });
}
}
}
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.js to a secure url
https://d3js.org/d3.v3.js