NVD3 Logarithmic Y axis with barchart

≡放荡痞女 提交于 2019-12-10 23:14:36

问题


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,000 and 60,000 then some value are near 3m.

I would like to have an Y Axis value increasing logarithmically, that show something like this (see the y Axis):

I tried to change yAxis scale, yAxis Domain, but didn't find any working solution

(FYI: I use nvd3 through angularJs directives)


回答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




回答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.



来源:https://stackoverflow.com/questions/25041829/nvd3-logarithmic-y-axis-with-barchart

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!