Show every other tick label on d3 time axis?
I think tickformats are really helpful here to keep it clean, atleast worked for me.
code is untested but i just want to draw attention to how we can manipulate tickformat.
var xAxisTop = d3.svg.axis()
.scale(x)
.orient("top")
.tickFormat((interval,i) => {
return i%3 !== 0 ? " ": interval;
})
.innerTickSize(-height)
.outerTickSize(0)
.ticks(d3.time.month.utc, 1);
I had this problem and I ended up using CSS. Each tick element has two children, <text>
for the label and <line>
for the grid-line so you have to select the inner text element and the grid-line will stay in place
.tick:nth-child(3n) text {
visibility: hidden;
}
You can do that regardless your x axis using a custom time format.
One solution is simply finding the text in that tick and removing it:
var ticks = d3.selectAll(".tick text");
ticks.each(function(_,i){
if(i%3 !== 0) d3.select(this).remove();
});
I'm using the modulo (i%3
) to get the multiples of 3. You can use any other number you want.
Here is a demo:
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.scaleBand()
.domain(data.map(function(d) {
return d.month
}))
.range([0, width * 0.95])
var xAxis = d3.axisBottom(xScale);
svg.append("g")
.attr("transform", "translate(10,100)")
.attr("class", "x axis")
.call(xAxis);
var ticks = d3.selectAll(".tick text");
ticks.each(function(_, 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/5.7.0/d3.min.js"></script>