Geometry is fun! Rotated x-axis labels calculated by input.
Last active
August 29, 2015 14:19
-
-
Save ajfarkas/b20386c7be8fda68505e to your computer and use it in GitHub Desktop.
Rotated x-axis labels for D3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
.axis text { | |
font: 10px sans-serif; | |
} | |
.axis line, | |
.axis path { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
</style> | |
<body> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script> | |
var margin = {top: 250, right: 40, bottom: 250, left: 40}, | |
width = 960 - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom | |
var x = d3.time.scale() | |
.domain([new Date(2014, 0, 1), new Date(2015, 0, 1)]) | |
.range([0, width]) | |
var xAxis = d3.svg.axis() | |
.scale(x) | |
var svg = d3.select("body").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")") | |
svg.append("g") | |
.attr("class", "x axis") | |
.call(xAxis) | |
var rotateXLabels = function(deg) { | |
var axis = d3.select('.x').selectAll('text') | |
var rotateLabel = function() { | |
var d3Label = d3.select(this), | |
sign = Math.sign(deg) | |
// get coordinates and dimensions of this | |
bBox = this.getBBox(), | |
width = bBox.width, | |
height = bBox.height, | |
bx = d3Label.attr('data-bx') || bBox.x, | |
by = d3Label.attr('data-by') || bBox.y, | |
// convert to radians | |
rad = Math.abs(deg) * Math.PI/180, | |
anchor = 'middle' | |
/* move along non-hypoteneuse sides of triangle created by connecting | |
** top right corner of rotated label with top center of original. | |
*/ | |
if (sign === -1) { | |
var | |
dy = Math.sin(rad) * width/2, | |
shift = Math.sqrt(Math.pow(width,2) + Math.pow(width/2,2) - Math.pow(width,2) * Math.cos(rad) ), | |
dx = - Math.sqrt(Math.pow(shift,2) - Math.pow(dy,2)) | |
} | |
/* move along non-hypoteneuse sides of triangle created by extending | |
** left side of rotated label to meet in right angle with line | |
** extended from top center of original. | |
*/ | |
else if (sign === 1) { | |
var | |
dy = - Math.cos(Math.PI/2 - rad) * width/2, | |
dx = Math.sin(Math.PI/2 - rad) * width/2 | |
} | |
// don't move. But reset the anchor. | |
else { | |
var | |
dy = height/2, | |
dx = 0 | |
anchor = 'start' | |
} | |
d3Label | |
.attr('transform', 'rotate('+deg+' '+bx+' '+by+')') | |
.attr('x', 0) | |
// add padding | |
.attr('y', 16.1) | |
.attr('dx', dx + 4 * sign) | |
.attr('dy', dy - height/2) | |
.attr('text-anchor', anchor) | |
.attr('data-bx', bx) | |
.attr('data-by', by) | |
} | |
// rotate each member of x-axis | |
axis.each(rotateLabel) | |
} | |
rotateXLabels(-90) | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment