Highcharts路径上的SVG标记

时间:2014-03-02 11:28:47

标签: svg highcharts

我想在我的Highcharts图表上绘制箭头,然后提出this到目前为止。看起来不错,但有问题:

  • 较高的笔划宽度会产生较长的箭头。
  • 旋转箭头需要进行复杂的计算,例如here

如果我可以在Highcharts路径上使用SVG标记like in this SVG tutorial绘图箭头会变得更容易

我的代码:

  renderer.path(['M', 200, 0, 'L', 200, 200,'L', 225, 200,'L',200,250,'L', 175, 200,'L', 200, 200])
    .attr({
        'stroke-width': 5,
        stroke: 'red',fill:'red'
    })
    .add();
renderer.path(['M', 400, 0, 'L', 400, 200,'L', 425, 200,'L',400,250,'L', 375, 200,'L', 400, 200])
    .attr({
        'stroke-width': 50,
        stroke: 'red',fill:'red'
    })
    .add();

1 个答案:

答案 0 :(得分:3)

我设法在不使用SVG标记的情况下绘制箭头。无论旋转如何,箭头都指向正确的位置。它甚至可以考虑起点和终点的半径。

enter image description here

请参阅fiddle

  function drawArrow(startX, startY, startRadius, endX, endY, endRadius, width) {

    var angle = Math.PI + Math.atan((endX - startX) / (endY - startY)),
        arrowLength = 3 * width,
        arrowWidth = 1.5 * width,
        path = [],
        startArrowX,
        startArrowY,
        margin = 5;

    if (endY >= startY) {
        //correct for circle radius
        startX -= ((startRadius + margin) * Math.sin(angle));
        startY -= ((startRadius + margin) * Math.cos(angle));
        endX += ((endRadius + margin) * Math.sin(angle));
        endY += ((endRadius + margin) * Math.cos(angle));

        //correct for arrow head length
        endX += (arrowLength * Math.sin(angle));
        endY += (arrowLength * Math.cos(angle));

        //draw arrow head
        path.push('M', endX, endY);
        path.push(
            'L',
        endX - arrowWidth * Math.cos(angle),
        endY + arrowWidth * Math.sin(angle));
        path.push(
        endX - arrowLength * Math.sin(angle),
        endY - arrowLength * Math.cos(angle));
        path.push(
        endX + arrowWidth * Math.cos(angle),
        endY - arrowWidth * Math.sin(angle), 'Z');
    } else {
        //correct for circle radius
        startX += ((startRadius + margin) * Math.sin(angle));
        startY += ((startRadius + margin) * Math.cos(angle));
        endX -= ((endRadius + margin) * Math.sin(angle));
        endY -= ((endRadius + margin) * Math.cos(angle));

        //correct for arrow head length
        endX -= (arrowLength * Math.sin(angle));
        endY -= (arrowLength * Math.cos(angle));

        //draw arrow head
        path.push('M', endX, endY);
        path.push(
            'L',
        endX + arrowWidth * Math.cos(angle),
        endY - arrowWidth * Math.sin(angle));
        path.push(
        endX + arrowLength * Math.sin(angle),
        endY + arrowLength * Math.cos(angle));
        path.push(
        endX - arrowWidth * Math.cos(angle),
        endY + arrowWidth * Math.sin(angle), 'Z');

    }

    renderer.path(path)
        .attr({
        'stroke-width': 1,
        stroke: '#989898',
        fill: '#989898'
    }).add();
    renderer.path(['M', startX, startY, 'L', endX, endY])
        .attr({
        'stroke-width': width,
        stroke: '#989898'
    }).add();