Search code examples
d3.jsformatdata-visualizationaxis

Is it possible to make axis ticks with appended text to have dynamic padding in d3?


I have y axis ticks with a K as thousands and M as millions coming from the ticksFromat and then I'm appending a pound symbol '£' to that, however sometimes if the number is too long it overlaps with a pound sign and vice versa when the number is too short as a single digit then the gap between the symbol and the number is huge. Is there anyway to make It dynamic as I thought adding attr('dx', 'xpx') to the text would fix that but this doesn't work.

const yAxisTickFormat = (d) => {
  //Logic to reduce big numbers
  const limits = [1000000000000000, 1000000000000, 1000000000, 1000000, 1000];
  const shorteners = ["Q", "T", "B", "M", "K"];
  for (let i in limits) {
    if (d > limits[i]) {
      return (d / limits[i]).toFixed() + shorteners[i];
    }
  }
  return d;
};

const yAxis = d3
      .axisLeft()
      .scale(yScale)
      .tickFormat((d) => yAxisTickFormat(d))
      .ticks(6)
      .tickSize(-width, barMargin, 0)
      .tickPadding(10);

 svg
      .append('g')
      .attr('transform', `translate(${xMargin},${yMargin})`)
      .attr('class', 'yAxis')
      .call(yAxis)
      .attr('fill', '#65757E')
      .selectAll('.tick')
      .append('text')
      .attr('x', '-40px')
      .attr('y', '3.15px')
      .text((d) => (d == 0 ? null : '£'));

Ticks


Solution

  • Could you try to append your '£' symbol directly within .tickFormat as follow:

    .tickFormat((d) => "£" + yAxisTickFormat(d)) instead of appending it in another text element?