Skip to content Skip to sidebar Skip to footer

Nvd3 Logarithmic Y Axis With Barchart

I have a barchart made with NVD3 that shows datas with a huge gap between min value and max value. This makes the chart not really nice/usefull. Example : Y value are between 4

Solution 1:

This will work for you

chart.y(function(d) { return d.value>0?Math.log10(d.value+1):0 })
chart.yAxis.tickFormat(function(d){return (Math.pow(10,d)-1).toFixed(2)})

Works only for positive values

Solution 2:

The root of the issue is that barcharts in nvd3 start at 0, and log(0) == Infinity.

Unfortunately there is a particular line in nvd3 that uses y(0) when calculating the height of the bar for your chart. When y(0) evaluates to Infinity things break. Furthermore, nvd3 is currently undergoing a refactor so, they aren't taking any pull requests for the old code base.

Here is what worked for me. It's not a general soltuion, but I couldn't even find this level of info online so I'm posting it here.

In this case I'm using a Line plus Bar Chart, this may not work for other bar charts, but hopefully it gives you and idea of what needs to be done.

First, make sure your chart is setup properly.

  yourChart.bars.yScale(d3.scale.log());
  yourChart.bars.forceY([1]); //Make sure y axis starts at 1 not 0
  yourChart.y1Axis.tickValues([1, 10, 100]); //Continue pattern for more ticks

now in nvd3.js around line 1600 (in nvd3 1.8 line number is 5605) you should see:

      bars.transition()
          .attr('y', function(d,i) {
            var rval = getY(d,i) < 0 ?
                    y(0) :
                    y(0) - y(getY(d,i)) < 1 ?
                      y(0) - 1 :
                      y(getY(d,i));
            return nv.utils.NaNtoZero(rval);
          })
          .attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.max(Math.abs(y(getY(d,i)) - y(1)),1)) });

In the very last statement:

.attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.max(Math.abs(y(getY(d,i)) - y(0)),1)) });

You need to replace y(0) with y(1) which will give you this:

.attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.max(Math.abs(y(getY(d,i)) - y(1)),1)) });

If this doesn't work, look for other cases where nvd3 sets up bars.transition() and calculates the height. You may need to fix up other cases where 0 is passed to y().

Hope this helps.

Post a Comment for "Nvd3 Logarithmic Y Axis With Barchart"