Jonah Bishop Jonah Bishop - 3 months ago 84
Javascript Question

Show every other tick label on d3 time axis?

I've got a d3 chart with an x-axis that uses a custom time format:

var x = d3.time.scale.utc()
.domain([start, end])
.range([0, width]);

var customTimeFormat = d3.time.format.utc.multi([
["%b %d", function(d) { return d.getUTCDate() != 1; }],
["%b", function(d) { return d.getUTCMonth(); }],
["%Y", function() { return true; }]
]);

var xAxisTop = d3.svg.axis()
.scale(x)
.orient("top")
.tickFormat(customTimeFormat)
.innerTickSize(-height)
.outerTickSize(0)
.ticks(d3.time.month.utc, 1);


What I'd like to be able to do is to have a tick for each month, but only a label for each third month. All I seem to be able to do, however, is to either (a) have a tick and label for each month or (b) have a tick and label for every third month.

How can I specify to draw ticks every month, but only have the labels show up for every third month?

Answer

You can do that independent of the fact that your x axis uses a custom time format.

One solution is simply finding the text in that tick and removing it:

var ticks = d3.selectAll(".tick text");
ticks.attr("class", function(d,i){
    if(i%3 != 0) d3.select(this).remove();
});

I'm using the modulo (i%3) to get the multiples of 3.

Check this snippet:

var width = 550, height = 200;

var data = [{month: "Jan"},
{month: "Feb"},
{month: "Mar"},
{month: "Apr"},
{month: "May"},
{month: "Jun"},
{month: "Jul"},
{month: "Aug"},
{month: "Sep"},
{month: "Oct"},
{month: "Nov"},
{month: "Dec"},
];

var svg = d3.select("body")
	.append("svg")
	.attr("width", width)
	.attr("height", height);
	
var xScale = d3.scale.ordinal()
    .domain(data.map(function(d){ return d.month}))
    .rangeBands([0, width*0.95])
	
var xAxis = d3.svg.axis().scale(xScale)
	.orient("bottom");

svg.append("g")
	.attr("transform", "translate(10,100)")
	.attr("class", "x axis")
	.call(xAxis);
	
var ticks = d3.selectAll(".tick text");

ticks.attr("class", function(d,i){
 if(i%3 != 0) d3.select(this).remove();
});
.axis path, .axis line {
fill: none;
stroke: #4e5a64;
shape-rendering: crispEdges;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Comments