D3.js single axis
by Jan TeplĂ˝
HTML
<div id="chart"></div>
CSS
.axis path, .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
svg {
background: red;
}
JavaScript
//test min and max
var min=-6000;
var max=10500;
var margin;
var width;
var height;
//Inicial margin, width and height
margin = {top: 0,
right: 5,
bottom: 0,
left: 5};
width = 400 - margin.left - margin.right;
height = 100 - margin.top - margin.bottom;
//Inicial scale
var x = d3.scale.linear()
.domain([min,max])
.range([0, width]);
//Ticks on the scale
var ticks=x.ticks(3);
var firstTick=ticks[0];
var lastTick=ticks[ticks.length-1];
var format=d3.format(',.0');
//sets offset of tick from start/end of scale
var offsetFirstTick=x(firstTick);
var offsetLastTick=width-x(lastTick);
//font size is set to 14px => 1ch(width of 0) ~ 8xp
//division by 2 reflect that label is centered with tick
var firstTickLabelHalfWidth=(format(firstTick)+"").length*(8/2);
var lastTickLabelHalfWidth=(format(lastTick)+"").length*(8/2);
//Compute minimal margin needet to contain tick label
var leftMinimalMargin=firstTickLabelHalfWidth-offsetFirstTick;
var rightMinimalMargin=lastTickLabelHalfWidth-offsetLastTick;
//Update margin with check if new margin is higher than innicial
margin = {top: 0,
right: Math.max(margin.right,rightMinimalMargin),
bottom: 0,
left: Math.max(margin.left,leftMinimalMargin)};
width = 400 - margin.left - margin.right;
height = 100 - margin.top - margin.bottom;
//Update scale to new width
x = d3.scale.linear()
.domain([min,max])
.range([0, width]);
//Create axis
var xAxis = d3.svg.axis()
.scale(x)
.ticks(3)
.outerTickSize(0)
.orient("bottom")
//Generate svg and append to body
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);