使用箭头线Highcharts创建SVG对象

时间:2017-03-03 22:10:56

标签: svg highcharts

我需要绘制一条指向我的高位图中特定点的箭头线。 我能够绘制线条,但不知道在显示之前如何使用箭头。

这是我的小提琴和代码。

http://jsfiddle.net/48kyq3wq/1/

$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=usdeur.json&callback=?', function(data) {

  var callout = function(chart) {
    $('.cO').remove();
    var xAxis = chart.xAxis[0],
      yAxis = chart.yAxis[0],
      point = chart.series[0].data[100],
      lineXLength = 100,
      lineYLength = -50;
    chart.renderer.path(['M', xAxis.toPixels(point.x), yAxis.toPixels(point.y), 'L', xAxis.toPixels(point.x) + lineXLength, yAxis.toPixels(point.y) + lineYLength,]).attr({
      'stroke-width': 5,
      stroke: 'red',
      zIndex: 0
    }).addClass('C0').add();

    chart.renderer.label('Custom label', xAxis.toPixels(point.x) + lineXLength, yAxis.toPixels(point.y) + lineYLength - 22, 'rect')
      .css({
        color: '#FFFFFF'
      })
      .attr({
        fill: 'rgba(0, 0, 0, 0.75)',
        padding: 8,
        r: 5,
        width: 100,
        height: 30,
        zIndex: 6
      }).addClass('cO')
      .add();
  };


  Highcharts.chart('container', {
    chart: {
      events: {
        load: function() {
          callout(this);
        },
        redraw: function() {
          callout(this);
        }
      }
    },
    xAxis: {
      type: 'datetime'
    },
    legend: {
      enabled: false
    },
    series: [{
      data: data
    }]
  });
});

1 个答案:

答案 0 :(得分:0)

您需要创建一个箭头并根据点和标签的位置旋转它。

  1. 创建连接标签和点

    的路径
    const x0 = label.x;
    const y0 = label.y + label.height / 2;
    const x1 = x;
    const y1 = y;
    
    const path = chart.renderer.path([
      'M', label.x, label.y + label.height / 2,
      'L', x, y,
    ]).attr({
      'stroke-width': 1,
      stroke: 'black',
      zIndex: 6
    }).add()
    
  2. 创建旋转点的方法。它将围绕箭头顶点旋转点

    function rotatePoint(c, angle, p) {
      const sin = Math.sin(angle);
      const cos = Math.cos(angle);
      const x = p[0] - c[0];
      const y = p[1] - c[1];
    
      const nx = x * cos - y * sin;
      const ny = x * sin + y * cos;
    
      return [nx + c[0], ny + c[1]];
    }
    
  3. 创建一个箭头,找到标签和点之间的角度,并根据角度旋转箭头。

    const array = [[x1 - 5, y1 - 15], [x1 + 5, y1 - 15], [x1, y1], [x1 - 5, y1- 15]]
    const angle = Math.atan2(y0 - y1, x0 - x1) + 90 * Math.PI / 180;
    const ma = array.map(point => rotatePoint(array[2], angle, point));
    
  4. 渲染箭头

    const arrow = chart.renderer.path({
      fill: 'black',
      zIndex: 6,
      d: ['M', ma[0].join(' '), 'L', ma[1].join(' '), ma[2].join(' '), ma[3].join(' ')].join(' ')
    }).add()
    
  5. 当点位于标签的右侧和标签的顶部时,您还应该考虑这种情况 - 旋转和角度计算保持不变,但需要调整点与标签的连接。

    实例和输出

    http://jsfiddle.net/savpscya/

    arrowed label