我有一个Highcharts条形图,我正在尝试根据条形值和位置添加自定义形状。首先,我只是尝试使用highcharts.renderer.path,为每个条添加一条线,与条形图一样高,根据硬编码值定位在x轴上。这是我的意思的图片:
这应该很容易,而且是在chart.type =“column”时。在highcharts回调中,我会在每个条上使用getBBox(),并translate()将x轴值转换为像素值。
但是,尝试使用chart.type =“bar”时遇到了几个问题。首先,切换所有x和y值(我假设这是作者首先从柱形图创建条形图的方式)。对于图表的所有属性也是如此:plotLeft现在是顶部,plotTop现在是左边。
这应该有效:
function (chart) {
$.each(chart.series[0].data, function (pointIndex, point) {
var plotLine = {},
elem = point.graphic.element.getBBox(),
yStart,
xStart,
newline;
yStart = chart.plotTop+elem.x;
xStart = chart.plotLeft+elem.height;
plotLine.path = ["M", xStart, yStart+1, "L", xStart, yStart+point.pointWidth];
plotLine.attr = {
'stroke-width': 1,
stroke: point.color,
zIndex: 5
};
newline = chart.renderer.path(plotLine.path).attr(plotLine.attr).add();
});
});
完整示例:http://jsfiddle.net/Bh3J4/9/
第二个问题可能是一个无法克服的错误。看来,当存在多个数据点时,所有x和y值在这些点之间混淆。请注意,颜色与位置不匹配。我创建了issue on GitHub。
当只有一点时,这不是问题。当有两个点时,我可以轻松切换值以获得正确的定位。但是当有3个或更多点时,我似乎无法弄清楚这些值如何混淆的逻辑。
第三个问题是,对于条形图,translate函数似乎不适用于xAxis,即使它在yAxis上也是如此。
chart.yAxis[0].translate(4); // correct for bottom axis
chart.xAxis[0].translate(1); // incorrect for side axis
还有另一种方法可以实现我正在寻找的东西吗?我错过了那个小提琴里的东西,这实际上并不是一个错误吗?
答案 0 :(得分:1)
我能够实现我想要的结果,但我不知道这是巧合还是实际错误的解决方法。无论如何,使用反向排序数组中的x值似乎帮助我正确排列所有内容。这是highcharts的回调函数:
function (chart) {
var benchmarks = { A: 1.5, B: 3.6, C: 2 },
reverseData = _.clone(chart.series[0].data).reverse();
_.each(chart.series[0].data, function (point, pointIndex) {
var plotLine = {},
elem = point.graphic.element.getBBox(),
reverseElem = reverseData[pointIndex].graphic.element.getBBox(),
benchmark = benchmarks[point.category],
yStart = chart.plotTop+reverseElem.x,
xStart = chart.plotLeft+chart.yAxis[0].translate(benchmark),
yEnd = yStart+point.pointWidth-1;
plotLine.path = ["M", xStart, yStart+1, "L", xStart, yEnd];
plotLine.attr = {
'stroke-width': 1,
stroke: "red",
zIndex: 5
};
chart.renderer.path(plotLine.path).attr(plotLine.attr).add();
var margin = 5,
xPadding = 10,
yPadding = 5,
xSplit = xPadding/2,
ySplit = yPadding/2,
text,
box;
text = chart.renderer.text("Top Perf Avg " + benchmark, xStart, yEnd+margin+16).attr({
color: "#646c79",
align: "center",
"font-family": "Arial, sans-serif",
"font-size": 9,
"font-weight": "bold",
style: "text-transform: uppercase",
zIndex: 7
}).add();
box = text.getBBox();
chart.renderer.path(["M", box.x-xSplit, box.y-ySplit,
"l", (box.width/2)+xSplit-margin, 0,
margin, -margin,
margin, margin,
(box.width/2)+xSplit-margin, 0,
0, box.height+yPadding,
-(box.width+xPadding), 0,
0, -(box.height+yPadding)])
.attr({
'stroke-width': 1,
stroke: "#cccccc",
fill: "#ffffff",
zIndex: 6
}).add();
});
}
请在此处查看完整的工作图:http://jsfiddle.net/Bh3J4/18/
答案 1 :(得分:0)
事实上,Highcharts使用transform
旋转所有内容,因此请使用相同的方法旋转这些行,请参阅示例:http://jsfiddle.net/Bh3J4/19/
function (chart) {
var d = chart.series[0].data,
len = d.length;
for(var i =0; i < len; i++){
var point = d[i],
plotLine = {},
elem = point.graphic.element.getBBox(),
yStart,
xStart,
newline;
console.log(point,point.color);
xStart = point.plotX - point.pointWidth / 2;
yStart = point.plotY;
plotLine.path = ["M", xStart, yStart, "L", xStart+point.pointWidth, yStart];
plotLine.attr = {
transform: 'translate(491,518) rotate(90) scale(-1,1) scale(1 1)',
'stroke-width': 1,
stroke: point.color,
zIndex: 5
};
newline = chart.renderer.path(plotLine.path).attr(plotLine.attr).add();
};
}
答案 2 :(得分:0)
轻微调整似乎可以精确对齐:
请注意:更改为xStart / yStart的calc并更改为transform translate参数。
我的方法是让它适用于柱形图,然后进行翻译。
唯一不能令人满意的部分是xStart需要:'{1}}在'列'模式下与xStart = elem.x+chart.plotLeft;
在'bar'模式下...
xStart = elem.x;