Skip to content

Instantly share code, notes, and snippets.

@denisemauldin
Last active December 8, 2017 23:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save denisemauldin/8edc9a08a689f37d5617e993130a61be to your computer and use it in GitHub Desktop.
Save denisemauldin/8edc9a08a689f37d5617e993130a61be to your computer and use it in GitHub Desktop.
two arc chord graph
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
.faculty-group text,
.area-group text
{
font: 11px sans-serif;
pointer-events: none;
}
.faculty-group path,
.area-group path
{
stroke: #000;
fill-opacity: 0.7;
}
.area-group path {
fill-opacity: 0.5;
}
path.chord {
stroke-width: .75;
fill-opacity: .75;
}
</style>
</head>
<body>
This doesn't work yet - v3 version: http://jsfiddle.net/che85hL9/
<script>
// Feel free to change or delete any of the code you see in this editor!
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500)
var areas = [
{"id":"2","area":"Group A","color":"#374900"},
{"id":"3","area":"Group B","color":"#0f2d4f"},
{"id":"4","area":"Group C","color":"#2f0f4f"},
{"id":"5","area":"Group D","color":"#4c2506"},
{"id":"6","area":"Group E","color":"#595605"}
];
var data = [
{"id":"DM459","first_name":"Person One","area":"2","active":"1","plans":[
{"destination":"BC234","count":"1"},
{"destination":"AB123","count":"1"}
]},
{"id":"CD459","first_name":"Person Two","area":"3","active":"1","plans":[
{"destination":"AB123","count":"2"}
]},
{"id":"MN549","first_name":"Person Three","area":"3","active":"1","plans":[
{"destination":"GH529","count":"2"}
]},
{"id":"GH529","first_name":"Person Four","area":"4","active":"1","plans":[
{"destination":"EF329","count":"1"},
{"destination":"MN549","count":"2"}
]},
{"id":"AB123","first_name":"Person Five","area":"5","active":"1","plans":[
{"destination":"BC234","count":"5"},
{"destination":"CD459","count":"2"},
{"destination":"DM459","count":"1"},
{"destination":"EF329","count":"1"}
]},
{"id":"BC234","first_name":"Person Six","area":"5","active":"1","plans":[
{"destination":"AB123","count":"5"},
{"destination":"DM459","count":"1"},
{"destination":"EF329","count":"1"}
]},
{"id":"EF329","first_name":"Person Seven","area":"6","active":"1","plans":[
{"destination":"BC234","count":"1"},
{"destination":"AB123","count":"1"},
{"destination":"GH529","count":"1"}
]}
];
// initialize square matrix for plan and assign faculty unique ids
var plans = [],
faculty = {};
for(var i = 0; i < data.length; i++) {
plans[i] = [];
// stash a unique integer for each faculty member
faculty[data[i].id] = i;
for (var j = 0; j < data.length; j++) {
plans[i][j] = 0;
}
}
// populate the plan matrix
data.forEach(function(facultyMember) {
facultyMember.plans.forEach(function(destination) {
//console.log("adding " + destination.count + " plans involving source: " + facultyMember.id + "(" + faculty[facultyMember.id] + ") and destination " + destination.destination + "(" + faculty[destination.destination] + ")");
plans[faculty[facultyMember.id]][faculty[destination.destination]] = +destination.count;
});
});
// initialize square matrix for areas and stash the unique id for each area
var areaMatrix = [],
areaIds = {};
for(var i = 0; i < areas.length; i++) {
areaMatrix[i] = [];
areaIds[areas[i].id] = i;
for (var j = 0; j < areas.length; j++) {
areaMatrix[i][j] = 0;
}
}
// populate the areas matrix
areas.forEach(function(area) {
data.forEach(function(facultyMember) {
facultyMember.plans.forEach(function(destination) {
areaMatrix[areaIds[facultyMember.area]][areaIds[data[faculty[destination.destination]].area]] += +destination.count;
});
});
});
console.log("areaMatrix", areaMatrix);
var width = 500,
height = 500,
outerRadius = Math.min(width, height) / 2 - 20,
innerRadius = outerRadius - 20,
colorIncrement = 0.07,
currentColorIncrement = 0,
currentArea = 0;
var areasArc = d3.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var areasLayout = d3.chord(plans);
var facultyArc = d3.arc()
.innerRadius(innerRadius - 24)
.outerRadius(outerRadius - 24);
var facultyLayout = d3.chord(plans);
//.sortGroups(d3.descending)
//.sortSubgroups(d3.descending)
//.sortChords(d3.descending)
//.padding(0.04);
var ribbon = d3.ribbon(plans)
.radius(innerRadius - 24);
// The color scale, for different categories of "worrisome" risk.
var fill = d3.scaleOrdinal()
.domain([0, 1, 2])
.range(["#DB704D", "#D2D0C6", "#ECD08D", "#F8EDD3"]);
// attach svg object to the content well
var g = svg.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
console.log(plans);
//console.log(facultyLayout);
// Add faculty groups
var facultyGroups = svg.selectAll("g.faculty-group")
.data(facultyLayout.groups)
.enter()
.append("svg:g")
.attr("class", "faculty-group");
// Add the faculty group arc
facultyGroups.append("svg:path")
.style("fill", function(d, i) {
return areas[areaIds[data[i].area]].color;
})
.attr("id", function(d, i) {
return "faculty-group" + d.index + "-" + j;
})
.attr("d", facultyArc)
.append("svg:title")
.text(function(d, i) {
var planCount = 0;
data[i].plans.forEach(function(plan) {
planCount += +plan.count;
});
return data[i].first_name + ' (' + planCount + ')';
});
// add faculty names
facultyGroups.append("svg:text")
.attr("x", 6)
.attr("dy", 15)
.append("svg:textPath")
.attr("xlink:href", function(d) {
return "#faculty-group" + d.index + "-" + j;
})
.text(function(d, i) {
return data[i].first_name;
});
// add area groups
var areaGroups = svg.selectAll("g.area-group")
.data(areasLayout.groups)
.enter()
.append("svg:g")
.attr("class", "area-group");
// Add the area group arc
areaGroups.append("svg:path")
.style("fill", function(d, i) {
return areas[i].color;
})
.attr("id", function(d, i) {
return "area-group" + d.index + "-" + j;
})
.attr("d", areasArc)
.append("svg:title")
.text(function(d, i) {
return areas[i].area;
});
// add area names
areaGroups.append("svg:text")
.attr("x", 6)
.attr("dy", 15)
.append("svg:textPath")
.attr("xlink:href", function(d) {
return "#area-group" + d.index + "-" + j;
})
.text(function(d, i) {
return areas[i].area;
});
// Add chords between faculty
svg.selectAll("path.chord")
.data(facultyLayout.chords)
.enter()
.append("svg:path")
.attr("class", "chord")
.style("fill", function(d, i) {
return areas[areaIds[data[d.source.index].area]].color;
})
.style("stroke", function(d) {
return d3.rgb(areas[areaIds[data[d.source.index].area]].color).darker();
})
.attr("d", chord)
.append("svg:title")
.text(function(d) {
var title = data[d.source.index].first_name + ' and ' + data[d.target.index].first_name + ": " + d.source.value + " plan";
if(d.source.value > 1) {
title = title + 's';
}
return title;
});
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment