Ben
Ben

Reputation: 389

D3 Chord Diagram Google Chrome

Hello I am having trouble with a D3 Chord Diagram. For some reason it works perfect in IE and Firefox but in chrome two of the connecting chords actually swap colors?

Does anyone know why this is happening? Would appreciate all the help

I also tried to get rid of the chord that is off color, and another one is off color. Is there a reason why its off by one??

http://lkrawitz1.byethost3.com/viz/viz.html

//*******************************************************************
  //  CREATE MATRIX AND MAP
  //*******************************************************************
    var datas = []
d3.csv('data/data.csv', function (error, data) {
    var mpr = chordMpr(data);
datas = data;
    mpr
      .addValuesToMap('has')
      .setFilter(function (row, a, b) {
        return (row.has === a.name && row.prefers === b.name)
      })
      .setAccessor(function (recs, a, b) {
        if (!recs[0]) return 0;
        return +recs[0].count;
      });
    drawChords(mpr.getMatrix(), mpr.getMap());
  });
  //*******************************************************************
  //  DRAW THE CHORD DIAGRAM
  //*******************************************************************

function drawChords (matrix, mmap) {
    var w = 980, h = 800, r1 = h / 2, r0 = r1 - 100;
    var fill = d3.scale.ordinal()
        .domain([0])
        .range([""]);

    var chord = d3.layout.chord()
        .padding(.02)
        .sortSubgroups(d3.descending)
        .sortChords(d3.descending);

    var arc = d3.svg.arc()
        .innerRadius(r0)
        .outerRadius(r0 + 20);

    var svg = d3.select("body").append("svg:svg")
        .attr("width", w)
        .attr("height", h)
      .append("svg:g")
        .attr("id", "circle")
        .attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");

        svg.append("circle")
            .attr("r", r0 + 20);

    var rdr = chordRdr(matrix, mmap);
    chord.matrix(matrix);

 var g = svg.selectAll("g.group")
        .data(chord.groups())
      .enter().append("svg:g")
        .attr("class", "group")
        .on("mouseover", mouseover)
        .on("mouseout", function (d) { d3.select("#tooltip").style("visibility", "hidden") });


    d3.csv('data/outer_color.csv', function (error, data) {
            g.append("svg:path")
                .style("stroke", "black")
                .style("fill", function(d,i){return data[i].color})
                .attr("d", arc);
    });

    g.append("svg:text")
        .each(function(d) { d.angle = (d.startAngle + d.endAngle) / 2; })
        .attr("dy", ".35em")
        .style("font-family", "helvetica, arial, sans-serif")
        .style("font-size", "10px")
        .attr("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; })
        .attr("transform", function(d) {
          return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")"
              + "translate(" + (r0 + 26) + ")"
              + (d.angle > Math.PI ? "rotate(180)" : "");
        })
        .text(function(d) { return rdr(d).gname; });


      var chordPaths = svg.selectAll("path.chord")
            .data(chord.chords())
            .enter().append("svg:path")
            .attr("class", "chord")
            .style("stroke", function(d) { return d3.rgb(fill(d.target.index)).darker(); })
    .style("fill", function(d,i){return datas[i].color; })


            .attr("d", d3.svg.chord().radius(r0))
            .on("mouseover", function (d) {
              d3.select("#tooltip")
                .style("visibility", "visible")
                .style("top", function () { return (d3.event.pageY - 100)+"px"})
                .style("left", function () { return (d3.event.pageX - 100)+"px";})
            })
            .on("mouseout", function (d) { d3.select("#tooltip").style("visibility", "hidden") });

  function mouseover(d, i) {
        d3.select("#tooltip")
          .style("visibility", "hidden")
          .style("top", function () { return (d3.event.pageY - 80)+"px"})
          .style("left", function () { return (d3.event.pageX - 130)+"px";})

        chordPaths.classed("fade", function(p) {
          return p.source.index != i
              && p.target.index != i;
        });
      }
  }

Upvotes: 1

Views: 547

Answers (1)

Henry S
Henry S

Reputation: 3112

This is down to order in which chord path elements appear in the DOM for the different browsers.

In FireFox (presumably also in IE), the chords are drawn in the DOM in the same order that they appear in raw data. The first chord path (from the Firebug) is highlighted below:

chord element in FireFox

Chrome is different: It reorders two of the chord path elements. The first chord path (from the Chrome Dev Tools) is highlighted here:

enter image description here

As you can see from the path data, these are not the same paths. I'm not sure why Chrome renders paths in the DOM in this different (unexpected) order! Where this impacts your example is that you use:

svg.selectAll("path.chord")...

to select each chord before assigning a color to it. The order of paths in the selection is based on order they appear in the DOM, hence why order is important. I would suggest refactoring the code to you don't need to read data.csv in twice (once to get data for the chord path, and then again just to assign the colors to those paths).

Update

One solution to this problem is to sort the chordPaths selection, for example on startAngle, before assigning colors. To do this:

chordPaths = svg.selectAll("path.chord");
chordPaths.sort(function(a,b) {return a.source.startAngle - b.source.startAngle }) 
chordPaths.style("fill", ...

See this updated plunker: http://plnkr.co/edit/xGKvEVeTLkZZLsTAiUFs?p=preview

Documentation on selection.sort() at: https://github.com/mbostock/d3/wiki/Selections#sort

Upvotes: 1

Related Questions