Search code examples
javascriptd3.jsdata-visualizationbar-chartaxis

D3 same ticks being showed twice on y axis


Same ticks value being displayed multiple times (1M in this case) on y axis. I don't think the problem is in how I'm formatting the ticks with yAxisTickFormat. What am I doing wrong?

CodeSandbox

export const yAxisTickFormat = (d) => {
  //Logic to reduce big numbers
  const limits = [1000000, 10000, 1000];
  const shorteners = ['M', 'K', 'K'];
  for (let i in limits) {
    if (d > limits[i]) {
      return (d / limits[i]).toFixed() + shorteners[i];
    }
  }
  return d;
};

const maxValue = storeData.dataset.reduce((maxAll, item) => {
  return item.values.reduce((maxItem, val) => 
    Math.max(maxItem, val.value), maxAll);
}, 0);
    
const yScale = d3.scaleLinear().range([-120, height - 200]);

yScale.domain([maxValue, 0]);

 const yAxis = d3
  .axisLeft()
  .scale(yScale)
  .tickFormat((d) => (d === 0 ? null : '£') + yAxisTickFormat(d))
  .ticks(5)
  .tickSize(-width, barMargin, 0)
  .tickPadding(10);

enter image description here


Solution

  • On the contrary, problem is in number formating. You are passing 1400000 and 1200000 which are converts to 1M. Try to add several digits after comma by passing argument to .toFixed method

    export const yAxisTickFormat = (d) => {
      //Logic to reduce big numbers
      const limits = [1000000, 10000, 1000];
      const shorteners = ['M', 'K', 'K'];
      for (let i in limits) {
        if (d > limits[i]) {
          return (d / limits[i]).toFixed(1) + shorteners[i];
        }
      }
      return d;
    };
    

    Which will convert your numbers to 1.4m and 1.2m accordingly.