I am creating a D3.js plot of multiple years of data. I would like to use the month names as the the axis labels. I am currently using the number of days into the year corresponding with the first day of that month as the labels as shown in the screenshot of my x-axis:
I believe all the relevant code is shown below:
var margins = {'top' : 20, 'right' : 20, 'bottom' : 50, 'left' : 70};
var height = 500;
var width = 960;
var plotHeight = height - margins.top - margins.bottom;
var plotWidth = width - margins.right - margins.left;
var x = d3.scaleLinear()
.domain([0,366])
.range([margins.left, plotWidth]);
// I am not concerned with leap years
var monthDays = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
var monthAbr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var svg = d3.select('.svg').attr('width',width).attr('height',height);
svg.append('g').attr('transform', 'translate(0,' + plotHeight + ')').call(d3.axisBottom(x).tickValues(monthDays));
Is there some way to map the position on the x-axis to the correct month (i.e.: 31 to Feb.)? I have tried using d3.timeMonth/d3.timeMonths and ordinal scales but haven't found something suitable yet.
You can use tickFormat
:
.tickFormat(function(d,i){ return monthAbr[i]})
Here is a working demo based on your code:
var margins = {'top' : 20, 'right' : 20, 'bottom' : 50, 'left' : 20};
var height = 100;
var width = 600;
var plotHeight = height - margins.top - margins.bottom;
var plotWidth = width - margins.right - margins.left;
var x = d3.scaleLinear()
.domain([0,366])
.range([margins.left, plotWidth]);
// I am not concerned with leap years
var monthDays = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
var monthAbr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var svg = d3.select('body').append("svg").attr('width',width).attr('height',height);
svg.append('g').attr('transform', 'translate(0,' + plotHeight + ')').call(d3.axisBottom(x).tickValues(monthDays).tickFormat(function(d,i){ return monthAbr[i]}));
<script src="https://d3js.org/d3.v4.min.js"></script>