Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formatting labels for x-axis in D3js

I am trying to create some bar charts using d3js. I am using a same js as a template and passing different data to show the charts. In cases if their are less 10 data points the x-axis labels look fine. But if their are more than 10 data points the x-axis labels are overlapping and clustered. So I was trying to identify a way where in I could skip every 4 ticks .Below is the code. It doesnt show any ticks at all when greater than 9 data points.

` var ticks = d3.selectAll(".tick text");

               function tickLabels(dataLength, d) {
                   if (dataLength < 9) return "";
                   return  ticks.attr("class", function(d,i){
                       if(i%3 != 0) d3.select(this).remove();
                   })
                 }

              var xAxis = d3.axisBottom().scale(x)
                                .ticks()
                                .tickFormat(function(d,i) {  return tickLabels(all.length, d) })

             `
like image 465
SNT Avatar asked Oct 27 '25 18:10

SNT


1 Answers

There are two ways of doing what you want. The first one is using tickFormat.

So, suppose you have this crowded axis:

var svg = d3.select("svg");
var data = d3.range(30).map(function(d) {
  return "tick" + d
});
var scale = d3.scalePoint()
  .domain(data)
  .range([20, 480]);
var axis = d3.axisBottom(scale);
var gX = svg.append("g")
  .attr("transform", "translate(0,50)")
  .call(axis);
path, line {
  shape-rendering: crispEdges;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="100"></svg>

You can use tickFormat to show only one of every 4 ticks:

var svg = d3.select("svg");
var data = d3.range(30).map(function(d) {
  return "tick" + d
});
var scale = d3.scalePoint()
  .domain(data)
  .range([20, 480]);
var axis = d3.axisBottom(scale)
  .tickFormat(function(d, i) {
    return i % 3 === 0 ? d : null;
  });
var gX = svg.append("g")
  .attr("transform", "translate(0,50)")
  .call(axis);
path, line {
  shape-rendering: crispEdges;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="100"></svg>

However, this solution removes only the text, leaving the tick. If you want to remove the tick as well, you can create a new selection and use each:

var svg = d3.select("svg");
var data = d3.range(30).map(function(d) {
  return "tick" + d
});
var scale = d3.scalePoint()
  .domain(data)
  .range([20, 480]);
var axis = d3.axisBottom(scale);
var gX = svg.append("g")
  .attr("transform", "translate(0,50)")
  .call(axis);
d3.selectAll(".tick").each(function(d, i) {
  if (i % 3 != 0) {
    d3.select(this).remove()
  }
})
path,
line {
  shape-rendering: crispEdges;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="100"></svg>
like image 78
Gerardo Furtado Avatar answered Oct 29 '25 16:10

Gerardo Furtado



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!