【问题标题】:NVD3 Logarithmic Y axis with barchartNVD3 对数 Y 轴带条形图
【发布时间】:2014-07-30 16:13:56
【问题描述】:

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

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

示例:

Y 值在 4,000 到 60,000 之间,然后一些值接近 3m。

我希望 Y 轴值以对数方式增加,显示如下 (参见 y 轴)

我尝试更改 yAxis 比例、yAxis Domain,但没有找到任何可行的解决方案

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

【问题讨论】:

  • 这是一个分叉的 JSFiddle 展示了这个想法,但在 d3.js 中,无法在 nvd3 jsfiddle.net/KemCake/ku22G 中重现
  • 你见过this SO answer吗?
  • 你不能在条形图上有一个真正的对数刻度——条形图自动包含零(条形的底),log(0) 是负无穷大!
  • 我读过,但真的吗?我就是不能?即使我强制 Y 为 1 或 yDomain 为 [1,XXX] ?
  • 我找到了一个使用谷歌图表 API 的解决方案,所以这在技术上是可行的:jsfiddle.net/KemCake/4DV2N

标签: javascript d3.js scale bar-chart nvd3.js


【解决方案1】:

这对你有用

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)})

仅适用于正值

【讨论】:

    【解决方案2】:

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

    不幸的是,nvd3 中有一条特定的线在计算图表的条形高度时使用 y(0)。当 y(0) 计算为 Infinity 时,事情就会中断。此外,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)) });
    

    最后一句话:

    .attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.max(Math.abs(y(getY(d,i)) - y(0)),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() 的情况。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2013-06-21
      • 2016-08-13
      • 2014-12-07
      • 1970-01-01
      • 2019-06-01
      • 2014-06-06
      • 2013-06-18
      • 1970-01-01
      • 2016-08-25
      相关资源
      最近更新 更多