JSFiddle - React, Tailwind, and code Playground
by boinky
HTML
<!DOCTYPE html>
<html>
<head>
<style>
#tooltip {
color: white;
opacity: .9;
background: #333;
padding: 5px;
border: 1px solid lightgrey;
border-radius: 5px;
position: absolute;
z-index: 10;
visibility: hidden;
white-space: nowrap;
pointer-events: none;
}
#circle circle {
fill: none;
pointer-events: all;
}
path.group {
fill-opacity: .8;
}
path.chord {
fill-opacity: .8;
stroke: #000;
stroke-width: .25px;
}
#circle:hover path.fade {
display: none;
}
</style>
</head>
<body>
<div id="tooltip"></div>
<div id="chord"></div>
<script>
//<script src="http://projects.delimited.io/experiments/chord-diagrams/lib/d3.js">
</script>
<script src="https://d3js.org/d3.v5.js"></script>
<script src="https://underscorejs.org/underscore-min.js"></script>
<script>
//<script src="http://projects.delimited.io/experiments/chord-diagrams/js/mapper.js"></script>
<script>
//*******************************************************************
// CREATE MATRIX AND MAP
//*******************************************************************
var hairCSV = `has,prefers,count,blah
"black","red",2868, "blah blah blah"
"blonde","brown",2060
"brown","blonde",16145
"red","black",1013
"black","brown",8916
"blonde","blonde",10048
"brown","black",8010
"red","red",6907
"black","blonde",5871
"blonde","black",1951
"brown","red",8045
"red","brown",940
"black","black",11975
"blonde","red",6171
"brown","brown",8090
"red","blonde",990`;
var parsed = d3.csvParse(hairCSV, function(d) {
return{
has:d.has,
prefers:d.prefers,
count: +d.count,
blah: d.blah
};
});
var mpr = chordMpr(parsed);
mpr
.addValuesToMap('has')
...
JavaScript
// blog-post - http://www.delimited.io/blog/2013/12/8/chord-diagrams-in-d3
//*******************************************************************
// CHORD MAPPER
//*******************************************************************
function chordMpr (data) {
var mpr = {}, mmap = {}, n = 0,
matrix = [], filter, accessor;
mpr.setFilter = function (fun) {
filter = fun;
return this;
},
mpr.setAccessor = function (fun) {
accessor = fun;
return this;
},
mpr.getMatrix = function () {
matrix = [];
_.each(mmap, function (a) {
if (!matrix[a.id]) matrix[a.id] = [];
_.each(mmap, function (b) {
var recs = _.filter(data, function (row) {
return filter(row, a, b);
})
matrix[a.id][b.id] = accessor(recs, a, b);
});
});
return matrix;
},
mpr.getMap = function () {
return mmap;
},
mpr.printMatrix = function () {
_.each(matrix, function (elem) {
console.log(elem);
})
},
mpr.addToMap = function (value, info) {
if (!mmap[value]) {
mmap[value] = { name: value, id: n++, data: info }
}
},
mpr.addValuesToMap = function (varName, info) {
var values = _.uniq(_.pluck(data, varName));
_.map(values, function (v) {
if (!mmap[v]) {
mmap[v] = { name: v, id: n++, data: info }
}
});
return this;
}
return mpr;
}
//*******************************************************************
// CHORD READER
//*******************************************************************
function chordRdr (matrix, mmap) {
return function (d) {
var i,j,s,t,g,m = {};
if (d.source) {
i = d.source.index; j = d.target.index;
s = _.where(mmap, {id: i });
t = _.where(mmap, {id: j });
m.sname = s[0].name;
m.sdata = d.source.value;
m.svalue = +d.source.value;
m.stotal = _.reduce(matrix[i], function (k, n) { return k + n }, 0);
m.tname = t[0].name;
m.tdata = d.target.value;
...