NVD3.js multiChart x轴标签与线条对齐,但不与条线对齐

Orb*_*tum 6 d3.js nvd3.js

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

在此输入图像描述

用红线标出标签应该在哪里.

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

谢谢!

jsh*_*ley 10

正如@Miichi提到的,​​这是nvd3中的一个错误......

我很惊讶他们有一个TODO来"弄清楚为什么价值似乎会被移动",因为它非常明显......这些条形使用了序数尺度,.rangeBands()并且该线条使用了线性比例,并且这两个尺度从未制作过相互关联,除非他们共享相同的端点.

一种解决方案是从条形图中取出序数尺度,然后简单地将其调整为条形宽度的一半以使线条具有x尺度.这会将线点放在条形的中心.我想在nv.models.linePlusBarChart@LarsKotthoff提到的类似事情中已经完成了.

基本上,你的线的x尺度看起来像这样:

var xScaleLine = function(d) {
  var offset = xScaleBars.rangeBand() / 2;
  return xScaleBars(d) + offset;  
};
Run Code Online (Sandbox Code Playgroud)

... xScaleBars用于图表条形部分的x刻度在哪里.

通过梳理nvd3的源代码,似乎可以访问此比例chart.bars1.scale().

也许有一天,nvd3的作者将决定他们的库的库存值得一些文档.现在,我可以告诉你的那种会解决这个问题,通过使自定义图表,显示了两个尺度会如何关联的事情.

首先,我将使用您的数据,但将line和bar数据分成两个数组:

var barData = [
  {"x":0,"y":6500},
  {"x":1,"y":8600},
  {"x":2,"y":17200},
  {"x":3,"y":15597},
  {"x":4,"y":8600},
  {"x":5,"y":814}
];

var lineData = [
  {"x":0,"y":2},
  {"x":1,"y":2},
  {"x":2,"y":4},
  {"x":3,"y":6},
  {"x":4,"y":2},
  {"x":5,"y":5}
];
Run Code Online (Sandbox Code Playgroud)

然后设置条形的比例.对于x标度,我将使用序数标度和rangeRoundBandsnvd3的默认组间距multiBar,即0.1.对于y标度,我将使用常规线性标度,.nice()使得标度不会像在默认情况下在nvd3中那样以尴尬值结束.有一些空间高于最大值会给你一些上下文,这在尝试解释图表时"很好".

var xScaleBars = d3.scale.ordinal()
  .domain(d3.range(barData.length))
  .rangeRoundBands([0, w], 0.1);

var yScaleBars = d3.scale.linear()
  .domain([0, d3.max(barData, function(d) {return d.y;})])
  .range([h, 0])
  .nice(10);
Run Code Online (Sandbox Code Playgroud)

现在这是重要的部分.对于线的x刻度,不要单独制作刻度,而只是使其成为条形x刻度的函数:

var xScaleLine = function(d) {
  var offset = xScaleBars.rangeBand() / 2;
  return xScaleBars(d) + offset;  
};
Run Code Online (Sandbox Code Playgroud)

这是JSBin的完整示例.我试图用注释记录主要部分,因此很容易遵循它的整体逻辑.如果您可以从nvd3源代码中确切地知道调用multiChart的每个元素以及如何设置组成部分的各个比例,那么您可能只需插入新的比例.

我的感觉就是你需要很好地处理d3如何使用nvd3做任何有用的事情,如果你想自定义它,你可能最好只是滚动你自己的图表.这样,您就可以完全了解和控制图表各部分的元素类和变量名称,并且可以随心所欲地执行任何操作.如果nvd3得到适当的文档,也许这将成为一个简单的修复.祝你好运,我希望这至少可以帮助你开始.