title: How to add categories to your chord diagram in D3.js?
body: <p>This is my chord diagram with d3.js version 4 (based on <a href="https://bl.ocks.org/nbremer/d2720fdaab1123df73f4806360a09c9e" rel="nofollow noreferrer">this chart</a> in v3) with two added "super categories" (i.e., the the yellow and grey overarching categories) via <em>Photoshop</em>: </p>
  
  <p><a href="https://i.stack.imgur.com/M9g4m.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/M9g4m.jpg" alt="enter image description here"></a></p>
  
  <p>You can run the code here: </p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>  ////////////////////////////////////////////////////////////
    //////////////////////// Set-Up ////////////////////////////
    ////////////////////////////////////////////////////////////
    var margin = {left:90, top:90, right:90, bottom:90},
        width =  1000 - margin.left - margin.right, // more flexibility: Math.min(window.innerWidth, 1000)
        height =  1000 - margin.top - margin.bottom, // same: Math.min(window.innerWidth, 1000)
        innerRadius = Math.min(width, height) * .39,
        outerRadius = innerRadius * 1.1;
  
      var names = ["Test1","Test2","AMO-DB","YouTube","Twitter", "Google+", "Pflegeratgeber" ,"O-Mag","RuV"],
        colors = ["#301E1E", "#083E77", "#342350", "#567235", "#8B161C", "#DF7C00"],
        opacityDefault = 0.8;
  
      var matrix = [
        [0,1,1,1,1,1,1,1,1], //Test1
        [0,0,1,1,1,1,1,0,1], //Test2
        [0,1,0,1,1,1,1,1,1], //Hawkeye
        [0,1,1,0,1,1,0,1,1], //The Hulk
        [0,1,1,1,0,1,1,1,1], //Iron Man
        [0,1,1,1,1,0,1,1,1],
        [0,1,1,1,1,1,0,1,1], //Iron Man
        [0,1,1,1,1,1,1,0,1],
        [0,1,1,1,1,1,1,0,0] //Thor //Thor
      ];
  
      ////////////////////////////////////////////////////////////
      /////////// Create scale and layout functions //////////////
      ////////////////////////////////////////////////////////////
  
      var colors = d3.scaleOrdinal()
          .domain(d3.range(names.length))
        .range(colors);
  
      var chord = d3.chord()
        .padAngle(.15)
        .sortChords(d3.descending)
  
        var arc = d3.arc()
        .innerRadius(innerRadius*1.01)
        .outerRadius(outerRadius);
  
      var path = d3.ribbon()
      .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) + ")")
      .datum(chord(matrix));
  
    ////////////////////////////////////////////////////////////
    ////////////////// Draw outer Arcs /////////////////////////
    ////////////////////////////////////////////////////////////
  
    var outerArcs = svg.selectAll("g.group")
      .data(function(chords) { return chords.groups; })
      .enter().append("g")
      .attr("class", "group")
      .on("mouseover", fade(.1))
      .on("mouseout", fade(opacityDefault))
  
      // text popups
      .on("click", mouseoverChord)
      .on("mouseout", mouseoutChord);
  
  
    ////////////////////////////////////////////////////////////
    ////////////////////// Append names ////////////////////////
    ////////////////////////////////////////////////////////////
  
    //Append the label names INSIDE outside
    outerArcs.append("path")
      .style("fill", function(d) { return colors(d.index); })
      .attr("id", function(d, i) { return "group" + d.index; })
      .attr("d", arc);
  
     outerArcs.append("text")
             .attr("x", 6)
             .attr("dx", 60)
            .attr("dy", 18)
          .append("textPath")
            .attr("href", function(d) { return "#group" + d.index;})
            .text(function(chords, i){return names[i];})
            .style("fill", "white");
  
    ////////////////////////////////////////////////////////////
    ////////////////// Draw inner chords ///////////////////////
    ////////////////////////////////////////////////////////////
  
    svg.selectAll("path.chord")
      .data(function(chords) { return chords; })
      .enter().append("path")
      .attr("class", "chord")
      .style("fill", function(d) { return colors(d.source.index); })
      .style("opacity", opacityDefault)
      .attr("d", path);
  
    ////////////////////////////////////////////////////////////
    ////////////////// Extra Functions /////////////////////////
    ////////////////////////////////////////////////////////////
  
    function popup() {
      return function(d,i) {
        console.log("love");
      };
    }//popup
  
    //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 &amp;&amp; d.target.index != i; })
        .transition()
            .style("opacity", opacity);
      };
    }//fade
  
      //Highlight hovered over chord
    function mouseoverChord(d,i) {
  
      //Decrease opacity to all
      svg.selectAll("path.chord")
        .transition()
        .style("opacity", 0.1);
      //Show hovered over chord with full opacity
      d3.select(this)
        .transition()
            .style("opacity", 1);
  
      //Define and show the tooltip over the mouse location
      $(this).popover({
        //placement: 'auto top',
        title: 'test',
        placement: 'right',
        container: 'body',
        animation: false,
        offset: "20px -100px",
        followMouse: true,
        trigger: 'click',
        html : true,
        content: function() {
          return "&lt;p style='font-size: 11px; text-align: center;'&gt;&lt;span style='font-weight:900'&gt;"  +
               "&lt;/span&gt; text &lt;span style='font-weight:900'&gt;"  +
               "&lt;/span&gt; folgt hier &lt;span style='font-weight:900'&gt;" + "&lt;/span&gt; movies &lt;/p&gt;"; }
      });
      $(this).popover('show');
    }
    //Bring all chords back to default opacity
    function mouseoutChord(d) {
      //Hide the tooltip
      $('.popover').each(function() {
        $(this).remove();
      })
      //Set opacity back to default for all
      svg.selectAll("path.chord")
        .transition()
        .style("opacity", opacityDefault);
      }      //function mouseoutChord</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code> body {
    font-size: 12px;
    font-family: 'Lato', sans-serif;
    text-align: center;
    fill: #2B2B2B;
    cursor: default;
  }
  
  @media (min-width: 600px) {
    #chart{
      font-size: 16px;
    }
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
    &lt;head&gt;
      &lt;meta http-equiv="Content-Type" content="text/html;charset=utf-8"/&gt;
      &lt;title&gt;Chord Diagram&lt;/title&gt;
  
      &lt;!-- D3.js --&gt;
      &lt;script src="https://d3js.org/d3.v4.min.js" charset="utf-8"&gt;&lt;/script&gt;
      &lt;!-- Google Fonts --&gt;
      &lt;link href='https://fonts.googleapis.com/css?family=Lato:400,900' rel='stylesheet' type='text/css'&gt;
      &lt;!-- bootstrap 4(!) --&gt;
      &lt;link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous"&gt;
      &lt;script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"&gt;&lt;/script&gt;
      &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"&gt;&lt;/script&gt;
      &lt;script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"&gt;&lt;/script&gt;
  
    &lt;/head&gt;
    &lt;body&gt;
      &lt;div id = "chart"&gt;&lt;/div&gt;
    &lt;/body&gt;
  &lt;/html&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>I don’t think, there’s a function in D3.js for "overarching categories" out of the box. I can’t wrap my head around how to implement that. For starters, I thought to define an array where groups are defined and the <strong>sub</strong>groups are included. Then, they are somehow passed to D3.js? </p>
  
  <pre><code>// not all arcs in a group must be categorised in super groups.
  var groups = [ ["group_name1", "RuV","Test1"], ["group_name2", "Twitter","Google+", "Pflegeratgeber"] ]
  </code></pre>
  
  <p><strong>Bonus</strong>: I can choose the colours of the super groups.</p>