我正在使用NVD3.js multiChart
在图表中显示多个线条和条形图。一切正常,但x轴标签仅与线点对齐,而不是条线。我想在标尺正下方正确对齐标签。但我明白了:
用红线标出标签应该在哪里。
我做了jsFiddle:http://jsfiddle.net/n2hfN/
谢谢!
正如@Miichi提到的,这是nvd3中的一个错误......
我很惊讶他们有一个TODO来“弄清楚为什么价值似乎会被移动”,因为它非常明显......这些条形使用.rangeBands()
的序数尺度,并且该线条使用线性比例,这两个尺度永远不会彼此相关,除非他们共享相同的端点。
一种解决方案是从条形图中取出序数尺度,然后简单地将其调整为条形宽度的一半以使线条具有x尺度。这会将线点放在条形的中心。我想在@LarsKotthoff提到的nv.models.linePlusBarChart
中做了类似的事情。
基本上,你的线的x尺度看起来像这样:
var xScaleLine = function(d) {
var offset = xScaleBars.rangeBand() / 2;
return xScaleBars(d) + offset;
};
...其中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}
];
然后设置条形的比例。对于x标度,我将使用序数标度和rangeRoundBands
与nvd3的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);
现在这是重要的部分。对于线的x刻度,不要单独制作刻度,而只是使其成为条形x刻度的函数:
var xScaleLine = function(d) {
var offset = xScaleBars.rangeBand() / 2;
return xScaleBars(d) + offset;
};
以下是JSBin的完整示例。我试图用注释记录主要部分,因此很容易遵循它的整体逻辑。如果您可以从nvd3源代码中确切地知道调用multiChart的每个元素以及如何设置组成部分的各个比例,那么您可能只需插入新的比例。
我的感觉就是你需要很好地处理d3如何使用nvd3做任何有用的事情,如果你想自定义它,你可能最好只是滚动你自己的图表。这样,您就可以完全了解和控制图表各部分的元素类和变量名称,并且可以随心所欲地执行任何操作。如果nvd3得到适当的文档,也许这将成为一个简单的修复。祝你好运,我希望这至少可以帮助你开始。