D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
denisemauldin
Full window
Github gist
two arc chord graph
Built with
blockbuilder.org
<!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: https://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>
https://d3js.org/d3.v4.min.js