Search code examples
javascriptd3.jschord-diagram

D3 and chord diagram


I am week old to D3 & a JS newbie. I am trying to make a chord diagram between few 'equally related' categories

  var chart = d3.chart.dependencyWheel();
  var data = {
  packageNames: ['Category A', 'Category B', 'Category C', 'Category D', 'Category E', 'Category F', 'Category G'
                ,'Category H', 'Category I', 'Category J', 'Category K', 'Category L', 'Category M', 'Category N'
                ,'Category O', 'Category P', 'Category Q', 'Category R', 'Category S', 'Category T', 'Category U'],
  matrix: [ // 1st 7 categories are equally related to one another
           [0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           [1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],  
           [1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           [1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           [1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           [1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           // next 9 categories are equally related to one another
           [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0], 
           // next 2 categories are equally related to one another
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], 
           // next 3 categories are Not at all related
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
           ] 
};
    d3.select('#chart_placeholder')
        .datum(data)
        .call(chart);

The output is like enter image description here

What i don't like is the color display. ideally i want each category to use a unique color and show data when a use Hover overs.

I googled around and found this http://racingtadpole.com/blog/flows-d3-chord-hover/ I modified it to add an unrelated category

var colors = d3.scale.ordinal().range(["#AAA", "steelblue", "green", "orange", "brown","#7FFF00"]);
  var hoverHtml = {'Category A': '<h1>Introverts</h1>Like to be by themselves', 
      'Category B': '<h1>Extroverts</h1>Like the company of other people', 
      'Category C': '<h1>Optimists</h1>Look on the bright side of life',
      'Category D': '<h1>Neutrals</h1>Life could be good, it could be bad',
      'Category E': '<h1>Pessimists</h1>See the glass half empty',
      'Unrelated Category':'<h1>Unrelated Category</h1>Unrelated Category'}
  var chordDiagram = d3.elts.flowChord().colors(colors).hoverHtml(hoverHtml).rimWidth(30);
  var data = [['Alpha','Category C','Category D','Category E'],['Category A', 0.8, 0.4, 0.67], ['Category B', 0.2, 0.6, 0.33],['Unrelated Category', 0.0, 0.0, 0.0]]
  d3.select("#flow").datum(data).call(chordDiagram);

The issue here is , the unrelated category is not visible on UI enter image description here

Not sure how to achieve my use case.

Ideally i want a chord diagram

  • each category is shown in its own unique color
  • some data comes over when a user hovers over
  • unrelated categories should be shown on UI

Will appreciate any pointers on same


Solution

  • You've passed 0 values for the Unrelated Category datapoint

    ['Unrelated Category', 0.0, 0.0, 0.0]

    Consequently your Unrelated Category arc will span 0 degrees (i.e. it won't exist).

    The degrees spanned by each arc is a relative measure of the sum of the values linked to it. For example, if you had 6 categories, each linked to exactly 3 others with equal value, you'd have 60 degree arcs.


    That said, you could insert 2 dummy categories, color them same and map them to each other to take up some arc degrees, like so

    var colors = d3.scale.ordinal().range(["#AAA", "steelblue", "green", "green", "orange", "brown", "#7FFF00"]);
    var hoverHtml = {
        'Category A': '<h1>Introverts</h1>Like to be by themselves',
        'Category B': '<h1>Extroverts</h1>Like the company of other people',
        'Category C': '<h1>Optimists</h1>Look on the bright side of life',
        'Category D': '<h1>Neutrals</h1>Life could be good, it could be bad',
        'Category E': '<h1>Pessimists</h1>See the glass half empty',
        'Unrelated': '<h1>Unrelated Category</h1>Unrelated Category',
        'Unrelated': '<h1>Unrelated Category</h1>Unrelated Category'
    }
    var chordDiagram = d3.elts.flowChord().colors(colors).hoverHtml(hoverHtml).rimWidth(30);
    var data = [['Alpha', 'Unrelated', 'Category C', 'Category D', 'Category E'],
                ['Category A', 0, 1, 1, 1],
                ['Category B', 0, 1, 1, 1],
                ['Unrelated', 1, 0, 0, 0]]
    d3.select("#flow").datum(data).call(chordDiagram);
    
    // hide the flow (we select by index just as an example)
    d3.select('.flows path:nth-child(7)').style('opacity', 0);
    

    with this CSS

    .labels text:nth-child(4n) {
        display: none;
    }
    

    If you want to position the label in the center, you could either do it using d3, or you could actually have 2 dummy categories instead of 1 mapping to the actual unrelated category in the middle and hide the labels for the dummy categories.