Konrad Viltersten Konrad Viltersten - 4 months ago 7
Javascript Question

Pie layout produces different ordering on Firefox and Chrome for the same dataset

I'm running the following script in the console and it produces a different output in Firefox and in Chrome. First off, I need someone to verify it because after a few hours of trouble-shooting, I feel that I might have gone insane.

The pie is supposed to be turned a quarter counter-clockwise, hence the offset. Then, the data's supposed to be sorted. In the parentheses I've listed the actual size. The order of the first set is as it's supposed to be (see the element starting with the angle -1.57), while the second one is wrong in Chrome but correct in FireFox.

Please tell me I'm going mad...

var offset = -Math.PI / 2;
var pie = d3.layout.pie()
.sort(function (a, b) { return a.val < b.val; })
.startAngle(offset).endAngle(2 * Math.PI + offset)
.value(function (d) { return d.val; });

var points1 = [
{key: "Cat 1", val: 14660}, {key: "Cat 2", val: 5264}, {key: "Cat 3", val: 17020},
{key: "Cat 4", val: 8076}, {key: "Cat 5", val: 5497}, {key: "Cat 6", val: 15833},
{key: "Cat 7", val: 5906}, {key: "Cat 8", val: 8331}, {key: "Cat 9", val: 9775}
];

var points2 = [
{key: "Key 10", val: 414}, {key: "Key 11", val: 246}, {key: "Key 12", val: 489},
{key: "Key 13", val: 241}, {key: "Key 14", val: 332}, {key: "Key 15", val: 368},
{key: "Key 16", val: 322}, {key: "Key 3", val: 420}, {key: "Key 4", val: 494},
{key: "Key 5", val: 269}, {key: "Key 6", val: 414}, {key: "Key 7", val: 363},
{key: "Key 8", val: 497}, {key: "Key 9", val: 395}
];

points1.forEach(function(e){ console.log(e); })
pie(points1).forEach(function(e){
console.log(e.data.key + "(" + e.data.val + "): "
+ Math.round(e.startAngle * 100) / 100 + " / "
+ Math.round(e.endAngle * 100) / 100);});

points2.forEach(function(e){ console.log(e); })
pie(points2).forEach(function(e){
console.log(e.data.key + "(" + e.data.val + "): "
+ Math.round(e.startAngle * 100) / 100 + " / "
+ Math.round(e.endAngle * 100) / 100);});


The wrong output I'm getting on Chrome is this (because the Key 3 with value 420 is starting the pie at angle -1.57). On FireFox it's correct (i.e. Key 8 with value 497 is the one starting at the angle -1.57). For the first set, the order is always correct, for any browser, as far I could tell. And I can't see any relevant different between those data sets.


Category 1(14660): 0.71 / 1.73

Category 2(5264): 4.35 / 4.71

Category 3(17020): -1.57 / -0.39

Category 4(8076): 2.99 / 3.55

Category 5(5497): 3.96 / 4.35

Category 6(15833): -0.39 / 0.71

Category 7(5906): 3.55 / 3.96

Category 8(8331): 2.41 / 2.99

Category 9(9775): 1.73 / 2.41

Key 10(414): -1.07 / -0.58

Key 11(246): 4.13 / 4.42

Key 12(489): -0.58 / 0.01

Key 13(241): 4.42 / 4.71

Key 14(332): 3.03 / 3.43

Key 15(368): 2.16 / 2.6

Key 16(322): 3.43 / 3.81

Key 3(420): -1.57 / -1.07

Key 4(494): 1.1 / 1.69

Key 5(269): 3.81 / 4.13

Key 6(414): 0.6 / 1.1

Key 7(363): 2.6 / 3.03

Key 8(497): 0.01 / 0.6

Key 9(395): 1.69 / 2.16

Answer

If instead of this...

.sort(function (a, b) { return a.val < b.val; })

...I write this:

.sort(function (a, b) { return d3.descending(a.val, b.val) })

I get the same values in Chrome and Firefox. Check the snippet:

var offset = -Math.PI / 2;
var pie = d3.layout.pie()
  .sort(function (a, b) { return d3.descending(a.val, b.val) })
  .startAngle(offset).endAngle(2 * Math.PI + offset)
  .value(function (d) { return d.val; });

var points1 = [
  {key: "Cat 1", val: 14660}, {key: "Cat 2", val: 5264}, {key: "Cat 3", val: 17020},
  {key: "Cat 4", val: 8076}, {key: "Cat 5", val: 5497}, {key: "Cat 6", val: 15833},
  {key: "Cat 7", val: 5906}, {key: "Cat 8", val: 8331}, {key: "Cat 9", val: 9775}
];

var points2 = [
  {key: "Key 10", val: 414}, {key: "Key 11", val: 246}, {key: "Key 12", val: 489},
  {key: "Key 13", val: 241}, {key: "Key 14", val: 332}, {key: "Key 15", val: 368},
  {key: "Key 16", val: 322}, {key: "Key 3", val: 420}, {key: "Key 4", val: 494},
  {key: "Key 5", val: 269}, {key: "Key 6", val: 414}, {key: "Key 7", val: 363},
  {key: "Key 8", val: 497}, {key: "Key 9", val: 395}
];

points1.forEach(function(e){ console.log(e); })
pie(points1).forEach(function(e){
  console.log(e.data.key + "(" + e.data.val + "): " 
    + Math.round(e.startAngle * 100) / 100 + " / " 
    + Math.round(e.endAngle * 100) / 100);});

points2.forEach(function(e){ console.log(e); })
pie(points2).forEach(function(e){
  console.log(e.data.key + "(" + e.data.val + "): " 
    + Math.round(e.startAngle * 100) / 100 + " / " 
    + Math.round(e.endAngle * 100) / 100);});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>

Comments