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;
     ...