forked from JulienAssouline's block: Chord Diagram with color gradient and opacity
forked from benlhy's block: Chord Diagram with color gradient and opacity
license: mit |
forked from JulienAssouline's block: Chord Diagram with color gradient and opacity
forked from benlhy's block: Chord Diagram with color gradient and opacity
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>D3: Loading TopoJSON data and generating SVG paths</title> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style type="text/css"> | |
/* No style rules here yet */ | |
body,html{ | |
margin: 0; | |
padding: 0; | |
font-family: "Arial", sans-serif; | |
font-size: 11px; | |
text-align: center; | |
} | |
#chart{ | |
background-color: #F5F2EB; | |
border: 1px solid #F5F2EB; | |
} | |
/*rect{ | |
fill: #b0859f; | |
}*/ | |
/*path.chord{ | |
fill-opacity: 0.1; | |
}*/ | |
</style> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
var w = 1050; | |
var h = 700; | |
var margin = { | |
top: 20, | |
bottom: 0, | |
left: 0, | |
right: 0 | |
} | |
var width = w - margin.left - margin.right; | |
var height = h - margin.top - margin.bottom; | |
var svg = d3.select("body") | |
.append("svg") | |
.attr("id", "chart") | |
.attr("width", w) | |
.attr("height", h) | |
var wrapper = svg.append("g") | |
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") | |
var outerRadius = Math.min(width, height) * 0.5 -55 | |
var innerRadius = outerRadius - 30 | |
var Names = [ | |
"onion", | |
"ground beef", | |
"celery", | |
"tomato", | |
"carrot", | |
"potato", | |
"milk", | |
"honey", | |
"bacon", | |
"egg" | |
] | |
var colors = ["#e6d2d8","#f9906f", "#9DCE5C", "#ff6347", "#ed9121", "#b79268", "#fdfff5","#fee0a5", "#772907", "#ffcc5f"] | |
var opacity = [1, 1, 1, 1, 1,1,1,1,1,1] | |
var matrix = [ | |
[0, 6030, 5203, 7181, 3623, 4601, 4381, 806, 2886, 6968], | |
[3651, 374, 549, 359, 0, 258, 750, 34, 262, 1693], | |
[6069, 0, 837, 3494, 374, 1083, 759, 168, 514, 948], | |
[5256, 837, 0, 966, 549, 600, 490, 151, 612, 1150], | |
[7201, 3469, 959, 0, 357, 2136, 903, 513, 469, 1699], | |
[4614, 1083, 600, 2142, 257, 0, 1244, 60, 603, 1051], | |
[4401, 759, 490, 904, 750, 1248, 0, 717, 831, 12979], | |
[809, 168, 151, 513, 34, 60, 717, 0, 111, 1516], | |
[2898, 514, 612, 472, 262, 603, 831, 111, 0, 1344], | |
[6934, 939, 1140, 1690, 1671, 1044, 12802, 1505, 1324, 0]] | |
; | |
var chordGenerator = d3.chord() | |
.padAngle(0.1) | |
.sortSubgroups(d3.descending) | |
.sortChords(d3.descending) | |
// .sortGroups(d3.descending) | |
var chord = chordGenerator(matrix); | |
var arcs = d3.arc() | |
.innerRadius(innerRadius) | |
.outerRadius(outerRadius); | |
var ribbon = d3.ribbon() | |
.radius(250) | |
var opacities = d3.scaleOrdinal() | |
.domain(d3.range(10)) | |
.range(opacity) | |
var color = d3.scaleOrdinal() | |
.domain(d3.range(10)) | |
.range(colors) | |
// d3.csv("Character_mentions.csv", function(error, data){ | |
// data.forEach(function(d){ | |
// d.index = d.index; | |
// d.Character = d.Character; | |
// d.Count = +d.Count; | |
// }) | |
// var g = svg.append("g") | |
// .datum(chord(matrix)) | |
// creating the fill gradient | |
function getGradID(d){ return "linkGrad-" + d.source.index + "-" + d.target.index; } | |
var grads = svg.append("defs") | |
.selectAll("linearGradient") | |
.data(chord) | |
.enter() | |
.append("linearGradient") | |
.attr("id", getGradID) | |
.attr("gradientUnits", "userSpaceOnUse") | |
.attr("x1", function(d, i){ return innerRadius * Math.cos((d.source.endAngle-d.source.startAngle) / 2 + d.source.startAngle - Math.PI/2); }) | |
.attr("y1", function(d, i){ return innerRadius * Math.sin((d.source.endAngle-d.source.startAngle) / 2 + d.source.startAngle - Math.PI/2); }) | |
.attr("x2", function(d,i){ return innerRadius * Math.cos((d.target.endAngle-d.target.startAngle) / 2 + d.target.startAngle - Math.PI/2); }) | |
.attr("y2", function(d,i){ return innerRadius * Math.sin((d.target.endAngle-d.target.startAngle) / 2 + d.target.startAngle - Math.PI/2); }) | |
// set the starting color (at 0%) | |
grads.append("stop") | |
.attr("offset", "0%") | |
.attr("stop-color", function(d){ return color(d.source.index)}) | |
//set the ending color (at 100%) | |
grads.append("stop") | |
.attr("offset", "100%") | |
.attr("stop-color", function(d){ return color(d.target.index)}) | |
// making the ribbons | |
d3.select("g") | |
.selectAll("path") | |
.data(chord) | |
.enter() | |
.append("path") | |
.attr("class", function(d) { | |
return "chord chord-" + d.source.index + " chord-" + d.target.index // The first chord allows us to select all of them. The second chord allows us to select each individual one. | |
}) | |
.style("fill", function(d){ return "url(#" + getGradID(d) + ")"; }) | |
.attr("d", ribbon) | |
// .style("stroke", function(d){ return d3.rgb(color(d.target.index)).darker(); }) | |
// making the arcs | |
var g = wrapper.selectAll("g") | |
.data(chord.groups) | |
.enter() | |
.append("g") | |
.attr("class", "group") | |
.on("mouseover", fade(.1)) | |
.on("mouseout", fade(1)) | |
g.append("path") | |
.style("fill", function(d){ return color(d.index)}) | |
// .style("stroke", function(d){ return d3.rgb(color(d.index)).darker(); }) | |
.attr("d", arcs) | |
.style("opacity",1) | |
/// adding labels | |
g.append("text") | |
.each(function(d){ d.angle = (d.startAngle + d.endAngle) / 2; }) | |
.attr("dy", ".35em") | |
.attr("class", "titles") | |
.attr("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; }) | |
.attr("transform", function(d) { | |
return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")" | |
+ "translate(" + (outerRadius + 10) + ")" | |
+ (d.angle > Math.PI ? "rotate(180)" : ""); | |
}) | |
.text(function(d,i){ return Names[i]; }) | |
.style("font-size", "15px") | |
function fade(opacity) { | |
return function(g, i) { | |
console.log("enter"); | |
svg.selectAll(".chord") | |
.filter(function(d) { | |
return d.source.index != i && d.target.index != i; | |
}) | |
.transition() | |
.style("opacity", opacity); | |
}; | |
} | |
</script> | |
</body> | |
</html> |