Skip to content

Instantly share code, notes, and snippets.

@nbremer
Last active May 1, 2024 09:36
Show Gist options
  • Save nbremer/d2720fdaab1123df73f4806360a09c9e to your computer and use it in GitHub Desktop.
Save nbremer/d2720fdaab1123df73f4806360a09c9e to your computer and use it in GitHub Desktop.
Data based orientations in SVG Gradients - Step 1
height: 700

This Chord diagram shows the first step of the example used in my blog on Data-based orientations for gradients in a d3.js Chord Diagram

What you see here are movie collaborations between the Avengers in the MCU (up until & including Thor Ragnarok). This is how a normal chord diagram would look with the Avenger collaborations dataset. As you can see each chord is given only 1 color. But because collaborations are symmetrical, the chords are all as thick at the beginnen as at the end. Therefore, I wanted each chord to represent both the Avengers that it connects through a gradient. That is what will be addressed in the next two steps.

You can find the steps after this one here

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Step 1 - Collaborations between MCU Avengers</title>
<!-- D3.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
<!-- Google Fonts -->
<link href='https://fonts.googleapis.com/css?family=Lato:400,900' rel='stylesheet' type='text/css'>
<style>
body {
font-size: 12px;
font-family: 'Lato', sans-serif;
text-align: center;
fill: #2B2B2B;
cursor: default;
}
@media (min-width: 600px) {
#chart{
font-size: 16px;
}
}
</style>
</head>
<body>
<div id = "chart"></div>
<script src = "script.js"></script>
</body>
</html>
////////////////////////////////////////////////////////////
//////////////////////// Set-Up ////////////////////////////
////////////////////////////////////////////////////////////
var margin = {left:90, top:90, right:90, bottom:90},
width = Math.min(window.innerWidth, 700) - margin.left - margin.right,
height = Math.min(window.innerWidth, 700) - margin.top - margin.bottom,
innerRadius = Math.min(width, height) * .39,
outerRadius = innerRadius * 1.1;
var Names = ["Black Widow","Captain America","Hawkeye","the Hulk","Iron Man","Thor"],
colors = ["#301E1E", "#083E77", "#342350", "#567235", "#8B161C", "#DF7C00"],
opacityDefault = 0.8;
var matrix = [
[0,4,3,2,5,2], //Black Widow
[4,0,3,2,4,3], //Captain America
[3,3,0,2,3,3], //Hawkeye
[2,2,2,0,3,3], //The Hulk
[5,4,3,3,0,2], //Iron Man
[2,3,3,3,2,0], //Thor
];
////////////////////////////////////////////////////////////
/////////// Create scale and layout functions //////////////
////////////////////////////////////////////////////////////
var colors = d3.scale.ordinal()
.domain(d3.range(Names.length))
.range(colors);
var chord = d3.layout.chord()
.padding(.15)
.sortChords(d3.descending)
.matrix(matrix);
var arc = d3.svg.arc()
.innerRadius(innerRadius*1.01)
.outerRadius(outerRadius);
var path = d3.svg.chord()
.radius(innerRadius);
////////////////////////////////////////////////////////////
////////////////////// Create SVG //////////////////////////
////////////////////////////////////////////////////////////
var svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + (width/2 + margin.left) + "," + (height/2 + margin.top) + ")");
////////////////////////////////////////////////////////////
////////////////// Draw outer Arcs /////////////////////////
////////////////////////////////////////////////////////////
var outerArcs = svg.selectAll("g.group")
.data(chord.groups)
.enter().append("g")
.attr("class", "group")
.on("mouseover", fade(.1))
.on("mouseout", fade(opacityDefault));
outerArcs.append("path")
.style("fill", function(d) { return colors(d.index); })
.attr("d", arc);
////////////////////////////////////////////////////////////
////////////////////// Append Names ////////////////////////
////////////////////////////////////////////////////////////
//Append the label names on the outside
outerArcs.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]; });
////////////////////////////////////////////////////////////
////////////////// Draw inner chords ///////////////////////
////////////////////////////////////////////////////////////
svg.selectAll("path.chord")
.data(chord.chords)
.enter().append("path")
.attr("class", "chord")
.style("fill", function(d) { return colors(d.source.index); })
.style("opacity", opacityDefault)
.attr("d", path);
////////////////////////////////////////////////////////////
////////////////// Extra Functions /////////////////////////
////////////////////////////////////////////////////////////
//Returns an event handler for fading a given chord group.
function fade(opacity) {
return function(d,i) {
svg.selectAll("path.chord")
.filter(function(d) { return d.source.index != i && d.target.index != i; })
.transition()
.style("opacity", opacity);
};
}//fade
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment