Reputation: 389
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
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:
Chrome is different: It reorders two of the chord path
elements. The first chord path (from the Chrome Dev Tools) is highlighted 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