D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
dukevis
Full window
Github gist
chord diagram + multiline chart
<!DOCTYPE html> <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