此问题与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/
谢谢!
答案 0 :(得分:10)
这里的问题是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的情况下编写自己的图表,或者为您的可视化找到不同类型的布局。
答案 1 :(得分:4)
在使用jshanley的答案提供的极其有用的指导来玩NVD3 v1.7.1源代码后,我想我已经设法得到了答案(或许更多的是一个比一个很好的解决方案)。
我所做的是让x轴标签与条形对齐,并使线条数据点与条形对齐。
1.1。为了对齐x轴标签,我将x轴向右移动,使第一个标签出现在第一个条的中间。然后我将最后一个标签向左移动,使它出现在最后一个条的中间。请参阅代码here。转换的数量是使用.rangeBand()
在绘图时计算的,并保存在rbcOffset
变量中(我必须修改multiBar.js
才能使其生效)。
1.2。为了使线数据点与条对齐,还需要类似的移位。幸运的是,这部分很容易,因为scatter.js
(由折线图使用)附带一个padData
布尔变量,它可以完成我们想要的操作。所以基本上,我只是将padData
设置为true并且线条移动以与条形对齐,请参阅here。
为了与NVD3正确集成并使一切看起来都很好,还需要进行一些额外的更改。我在GitHub上分配了NVD3,这样你就可以在那里看到完整的解决方案。当然,欢迎捐款。
答案 2 :(得分:3)
我使用上一个解决方案然后运行。所以,你可以指定
lines1.padData(true)
也是为了对齐线条。
答案 3 :(得分:0)
在这里,我使用了最后一个解决方案,它也适用于我。在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);
}
答案 4 :(得分:0)
我遇到了同样的问题并使用以下代码修复了它:
在第7832和7878行替换
line.replace(';', ';\n')
with:
.attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',0)'; })
第一种情况处理多个条形外壳,而第二种情况处理单个条形外壳。
答案 5 :(得分:0)
劳瑞的解决方案有效。同样,如果使用交互式指南,则需要移动交互式行以匹配新比例。修改:
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中。