Javascript 带条形图的NVD3对数Y轴

Javascript 带条形图的NVD3对数Y轴,javascript,d3.js,scale,bar-chart,nvd3.js,Javascript,D3.js,Scale,Bar Chart,Nvd3.js,我有一个用NVD3制作的条形图,它显示了最小值和最大值之间存在巨大差距的数据 这使得图表不是很好/有用 例如: Y值在4000到60000之间,然后一些值接近3m 我希望Y轴的值以对数方式递增,显示如下内容(请参见Y轴): 我试图改变yAxis规模,yAxis领域,但没有找到任何有效的解决方案 (仅供参考:我通过angularJs指令使用nvd3)问题的根源在于nvd3中的条形图从0开始,并且log(0)=无穷大 不幸的是,nvd3中有一行在计算图表的条形高度时使用y(0)。当y(0)的计算

我有一个用NVD3制作的条形图,它显示了最小值和最大值之间存在巨大差距的数据

这使得图表不是很好/有用

例如:

Y值在4000到60000之间,然后一些值接近3m

我希望Y轴的值以对数方式递增,显示如下内容(请参见Y轴):

我试图改变yAxis规模,yAxis领域,但没有找到任何有效的解决方案


(仅供参考:我通过angularJs指令使用nvd3)

问题的根源在于nvd3中的条形图从0开始,并且log(0)=无穷大

不幸的是,nvd3中有一行在计算图表的条形高度时使用y(0)。当y(0)的计算结果为无穷大时,一切都会中断。此外,nvd3目前正在进行重构,因此,它们不会对旧代码库进行任何拉取请求

这是对我有用的东西。这不是一般的解决方案,但我甚至无法在网上找到这一级别的信息,所以我将其发布在这里

在本例中,我使用的是直线加条形图,这可能不适用于其他条形图,但希望它能让您了解需要做什么

首先,确保图表设置正确

  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
现在在nvd3.js的第1600行(在nvd3 1.8中,行号是5605)中,您应该看到:

      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)) });
您需要将y(0)替换为y(1),这将为您提供:

.attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.max(Math.abs(y(getY(d,i)) - y(1)),1)) });
如果这不起作用,请查找nvd3设置bar.transition()并计算高度的其他情况。您可能需要修复将0传递给y()的其他情况


希望这对你有帮助。

这对你有用

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)})
仅适用于正值


这里有一个分叉的JSFIDLE显示了这个想法,但是在
d3.js
中,不能在
nvd3
中复制,你看到了吗?你不能在条形图上有一个真正的对数刻度-条形图自动包含零(条形图的底部),并且
log(0)
是负无穷大!我读过,但真的?我就是不能?即使我强制为1或yDomain为[1,XXX]?我发现了一个使用google图表API的解决方案,因此这在技术上是可行的:
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)})