【问题标题】:NVD3.js multiChart x-axis labels is aligned to multiple lines, but not multiple barsNVD3.js multiChart x轴标签与多条线对齐,但不是多条
【发布时间】:2014-09-07 23:23:13
【问题描述】:

这个问题与NVD3.js multiChart x-axis labels is aligned to lines, but not bars有关

我正在使用 NVD3.js multiChart 在图表中显示多条线多条条。一切正常,但 x 轴标签仅与线点对齐,而不是与条对齐。我想正确对齐标签直接在条形下方。但我明白了:

如您所见 - x 轴(例如 2014 年 2 月)未与 条形图对齐。

1) 如何将x轴标签同时对齐条和线

2) 我需要这个解决方案来解决NVD3.js 或如何正确集成。

我做了jsFiddle:http://jsfiddle.net/n2hfN/28/

谢谢!

【问题讨论】:

    标签: d3.js nvd3.js


    【解决方案1】:

    这里的问题是nv.models.multiChart 对其 x 轴使用线性刻度,然后在绘制条形时调用nv.models.multiBar,它使用带有.rangeBands() 的序数刻度。

    你可以通过源代码来跟踪这个烂摊子:

    首先让我们看看multiChart.js

    HERE 将 x 比例设置为线性比例。

    HERE 它调用nv.models.multiBar 模型来创建条形图。

    如果我们跳过去看看multiBar.js

    HERE 它创建一个序数刻度,HERE 它使用.rangeBands() 设置刻度范围

    结果是用于放置条形的序数比例和用于图表轴的线性比例不对齐。如果绘制在轴上,这两个比例分别是这样的:

    解决方案是强制图表根据条形使用的序数比例呈现折线图和 x 轴。这适用于您的情况,因为条形图和线条都对 x 轴使用相同的数据。如果您正在制作自己的图表并且不依赖 nvd3,这非常简单,正如我在对您之前的问题 HERE 的回答中所展示的那样。如果您尝试在 nvd3 中工作,这将非常复杂,并且许多其他人尝试切换 nvd3 图表使用的默认比例但失败了。例如,查看自 2013 年 1 月以来一直开放的 this issue on the nvd3 github page

    我自己尝试了多种方法来重用条形的序数比例,但收效甚微。如果您想四处寻找并尝试自己暴力破解,我可以告诉您,从我的实验中,我最接近使用chart.bars1.xScale().copy() 复制条形的比例,并设置其域和范围。不幸的是,由于图表的宽度是在渲染时计算的,而且我似乎无法在 chart.update 函数中创建挂钩,因此无法将 rangeBands 的范围设置为正确的值。

    简而言之,如果您不能忍受标签偏移,您可能需要编写自己的图表而不使用 nvd3,或者为您的可视化找到不同类型的布局。

    【讨论】:

      【解决方案2】:

      在使用 jshanley 的回答提供的非常有用的指导玩弄了 NVD3 v1.7.1 源代码之后,我想我已经设法想出了一个答案(也许比一个很好的解决方案)。

      1. 我所做的是让 x 轴标签与条形对齐,并使线数据点与条形对齐。

        1.1。为了对齐 x 轴标签,我将 x 轴向右移动,以便第一个标签出现在第一个条的中间下方。然后我将最后一个标签向左移动,使其出现在最后一个栏的中间下方。见代码here。偏移量在绘图时使用.rangeBand() 计算并保存在rbcOffset 变量中(我必须修改multiBar.js 才能工作)。

        1.2。要将线数据点与条对齐,还需要类似的移位。幸运的是,这部分很简单,因为scatter.js(用于折线图)带有一个padData 布尔变量,它已经完成了我们想要的操作。所以基本上,我只是将padData 设置为true,然后线条会移动以与条对齐,请参阅here

      2. 为了与 NVD3 正确集成并使一切看起来不错,需要进行一些额外的更改。我在 GitHub 上 fork了 NVD3,所以你可以在那里看到完整的解决方案。当然,欢迎投稿。

      【讨论】:

      • 感谢您的回答!我稍后会检查它。
      【解决方案3】:

      我使用最后一个解决方案并且它运行。所以,你可以指定

      lines1.padData(true)

      为了对齐线条。

      【讨论】:

      • 能否提供jsFiddle(现有的可以修改一个)?
      • 这只是将折线图与条形图对齐,但 xAxis 标签仍未对齐。
      【解决方案4】:

      同样,我使用了最后一个解决方案,它也对我有用。在 multiChart.js 中找到以下行

      if(dataLines1.length){
          lines1.scatter.padData(true); // add this code to make the line in sync with the bar
          d3.transition(lines1Wrap).call(lines1);
      }
      

      【讨论】:

      • 谢谢!我会检查的。
      【解决方案5】:

      我遇到了同样的问题并用下面的代码修复了它:

      在第 7832 和 7878 行替换

      .attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',0)'; })
      

      与:

      var w = (x.rangeBand() / (stacked && !data[j].nonStackable ? 1 : data.length));
      var sectionWidth = availableWidth/(bars.enter()[0].length - 1);
      if(bars.enter().length == 2)
          return 'translate(' + ((i-1)*w + i*w + (i*(sectionWidth - 2*w))) + ',0)';
      else
          return 'translate(' + ((i-0.5)*w + i*(sectionWidth - w)) + ',0)';
      

      第一种情况处理多条情况,而第二种情况处理单条情况。

      【讨论】:

        【解决方案6】:

        lawry 的解决方案有效。此外,如果使用交互式指南,您需要移动交互式线以匹配新比例。修改:

        if(useInteractiveGuideline){
                        interactiveLayer
                            .width(availableWidth)
                            .height(availableHeight)
                            .margin({left:margin.left, top:margin.top})
                            .svgContainer(container)
                            .xScale(x);
                        wrap.select(".nv-interactive").call(interactiveLayer);    
                                                                                  
                        //ADD THIS LINE 
                        wrap.select(".nv-interactiveGuideLine")
                        .attr('transform', 'translate(' + rbcOffset +', ' + 0  + ')' +
                        'scale(' + ((availableWidth - rbcOffset*2)/availableWidth) + ', 1)');
                    }
        

        在 multiChart.js 中。

        【讨论】:

          猜你喜欢
          • 2014-08-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多