Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
prevent vertical overlapping of labels in charts
define(function(require) {
'use strict';
var d3 = require('d3');
/*
* tries to eliminate vertical label overlappings
* by slightly moving the labels away from each
* other
*
* @param labels a D3 selection of labels created with d3.html.labels
* @param min_y the lower boundary for y
* @param max_y the upper boundary for y
* @param min_pad the minimum distance between two labels (default 0)
*/
return function(nodes, y_key, min_y, max_y, min_dist) {
if (!min_dist) min_dist = 10;
var vNodes = []; // virtual labels
nodes.forEach(function(node) {
vNodes.push({
node: node,
y: node[y_key],
dy: 0,
oy: node[y_key],
});
});
var iter = 0;
(function loop() {
var overlap = false;
vNodes.forEach(function(node0, p) {
vNodes.forEach(function(node1, q) {
if (q > p) {
var y0 = node0.y,
y1 = node1.y,
dy, l0up;
if (Math.abs(y0 - y1) < min_dist) {
overlap = true;
dy = (Math.abs(y0 - y1) - min_dist) * 0.35;
l0up = y0 < y1;
node0.dy += l0up ? dy : -dy;
node1.dy -= l0up ? dy : -dy;
}
}
});
});
if (overlap) {
vNodes.forEach(function(node) {
node.y = Math.min(Math.max(min_y, node.y + node.dy), max_y);
node.dy = 0;
});
}
if (overlap && ++iter < 10) loop();
})(); // end loop()
vNodes.forEach(function(node, i) {
node.node[y_key+'_d'] = node.y - node.oy;
node.node[y_key] = node.y;
});
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.