【问题标题】:Create a SVG object with a arrow line Highcharts创建带有箭头线的 SVG 对象 Highcharts
【发布时间】:2017-03-03 22:10:56
【问题描述】:

我需要在我的 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
    }]
  });
});

【问题讨论】:

    标签: svg highcharts


    【解决方案1】:

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

    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()
      

    您还应该考虑点在标签右侧和标签顶部的情况 - 旋转和角度计算保持不变,但需要调整点与标签的连接。

    实时示例和输出

    http://jsfiddle.net/savpscya/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-13
      • 1970-01-01
      • 1970-01-01
      • 2021-10-20
      • 1970-01-01
      • 2019-12-29
      • 1970-01-01
      相关资源
      最近更新 更多