From a53af7ac65ec4c18fa44ae0cd24f5803a338d939 Mon Sep 17 00:00:00 2001 From: Robin Hu Date: Mon, 28 Oct 2013 11:05:50 -0400 Subject: [PATCH] Piechart: Added solution to overlapping pie chart labels. Needs more refinement, but it works for very narrow situations. --- nv.d3.js | 21 ++++++++++++++++++++- src/models/pie.js | 21 ++++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/nv.d3.js b/nv.d3.js index 97c2bea..d0efdfd 100644 --- a/nv.d3.js +++ b/nv.d3.js @@ -10388,6 +10388,13 @@ nv.models.pie = function() { }); + var labelLocationHash = {}; + var avgHeight = 14; + var avgWidth = 140; + var createHashKey = function(coordinates) { + + return Math.floor(coordinates[0]/avgWidth) * avgWidth + ',' + Math.floor(coordinates[1]/avgHeight) * avgHeight; + }; pieLabels.transition() .attr('transform', function(d) { if (labelSunbeamLayout) { @@ -10403,7 +10410,19 @@ nv.models.pie = function() { } else { d.outerRadius = radius + 10; // Set Outer Coordinate d.innerRadius = radius + 15; // Set Inner Coordinate - return 'translate(' + labelsArc.centroid(d) + ')' + + /* + Overlapping pie labels are not good. What this attempts to do is, prevent overlapping. + Each label location is hashed, and if a hash collision occurs, we assume an overlap. + Adjust the label's y-position to remove the overlap. + */ + var center = labelsArc.centroid(d); + var hashKey = createHashKey(center); + if (labelLocationHash[hashKey]) { + center[1] -= avgHeight; + } + labelHash[createHashKey(center)] = true; + return 'translate(' + center + ')' } }); pieLabels.select(".nv-label text") diff --git a/src/models/pie.js b/src/models/pie.js index 9b98a3b..b0ab998 100644 --- a/src/models/pie.js +++ b/src/models/pie.js @@ -191,6 +191,13 @@ nv.models.pie = function() { }); + var labelLocationHash = {}; + var avgHeight = 14; + var avgWidth = 140; + var createHashKey = function(coordinates) { + + return Math.floor(coordinates[0]/avgWidth) * avgWidth + ',' + Math.floor(coordinates[1]/avgHeight) * avgHeight; + }; pieLabels.transition() .attr('transform', function(d) { if (labelSunbeamLayout) { @@ -206,7 +213,19 @@ nv.models.pie = function() { } else { d.outerRadius = radius + 10; // Set Outer Coordinate d.innerRadius = radius + 15; // Set Inner Coordinate - return 'translate(' + labelsArc.centroid(d) + ')' + + /* + Overlapping pie labels are not good. What this attempts to do is, prevent overlapping. + Each label location is hashed, and if a hash collision occurs, we assume an overlap. + Adjust the label's y-position to remove the overlap. + */ + var center = labelsArc.centroid(d); + var hashKey = createHashKey(center); + if (labelLocationHash[hashKey]) { + center[1] -= avgHeight; + } + labelHash[createHashKey(center)] = true; + return 'translate(' + center + ')' } }); pieLabels.select(".nv-label text")