【问题标题】:How to draw an allipse (oval) on a Highchart graph如何在 Highchart 图表上绘制椭圆(椭圆)
【发布时间】:2017-11-08 06:38:04
【问题描述】:

我有两个系列和它们的交点。我想在图表上有一个椭圆(椭圆),中心在交点。椭圆半径应根据轴单位设置,以显示每个轴的感兴趣区域。

Highcharts.chart('container', {
    series: [
      // first series
      {
        name: 'IPR',
        data: [[0, 30.5],[18.5, 25.4],[30, 19.4],[38, 9.7],[42, 0.02]]
      }, 
      // second series
      {
        name: 'VLP', 
        data: [[2, 0.5],[7, 1],[14, 6],[21, 22],[29, 29.6],[40, 30.3],[50, 27.2]]
      }, 
      // intersection
      {
        name: 'Operating point',
        data: [
          [22.42, 23.35]
        ]
      }
    ],
})

如何以编程方式在相交处绘制椭圆并进行缩放?

【问题讨论】:

    标签: javascript highcharts ellipse rect oval


    【解决方案1】:

    您可以使用Renderer.createElement 在 Highcharts 中创建其他 SVG 元素:

        this.renderer.createElement('ellipse').attr({
          cx: 60,
          cy: 60,
          rx: 50,
          ry: 25,
          'stroke-width': 2,
          stroke: 'red',
          fill: 'yellow',
          zIndex: 3
        }).add();
    

    如@Anton Rybalko 建议的那样,要转换为轴单位,请使用toPixels


    现场演示: http://jsfiddle.net/kkulig/ds6aj5yp/

    API 参考:

    【讨论】:

    • 这个比使用rect好
    【解决方案2】:

    SVG 渲染器并不是一个很好的答案。

    应该使用多边形特征(有很多点,你可以在后端离线生成,或者在前端解析):

    series: [{
            name: 'Target',
            type: 'polygon',
            data: [[153, 42], [149, 46], [149, 55], [152, 60], [159, 70], [170, 77], [180, 70],
                [180, 60], [173, 52], [166, 45]],
            color: Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0.5).get(),
            enableMouseTracking: false
    
        }
    

    https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/polygon/

    【讨论】:

    • 哇,有用的功能!感谢您的回答,但我需要以特定半径显示兴趣点周围的区域。所以我需要为多边形计算几个点来绘制一个椭圆。我不想这样做:)
    【解决方案3】:

    可以使用SVGRenderer 绘制圆、线等。但是没有画椭圆的方法。但是可以使用带圆角的rect()

    以下代码可用于在点 (100, 200) px、水平半径 20 px 和垂直半径 10 px 处绘制椭圆:

    chart.renderer.rect(100, 100, 20, 10, '50%')
        .attr({
            'stroke-width': 1,
            'stroke': 'green',
            'fill': 'yellow',
            zIndex: 0
        })
        .add();
    

    可以使用Axis.toPixels() 以轴单位指定 x、y 和半径。如果我们需要将点 (22.42, 23.35) 转换为像素,可以这样做:

    var x = chart.xAxis[0].toPixels(22.42),
        y = chart.yAxis[0].toPixels(23.35)
    

    所以绘制椭圆的函数是:

    var drawEllipse = function(chart, x, y, xr, yr) {
      var x1 = chart.xAxis[0].toPixels(x-xr)
      var x2 = chart.xAxis[0].toPixels(x+xr)
      var y1 = chart.yAxis[0].toPixels(y-yr)
      var y2 = chart.yAxis[0].toPixels(y+yr)
      $('.' + rectClass).remove()
      chart.renderer.rect(x1, y2, x2 - x1, y1 - y2, '50%')
        .attr({
            'stroke-width': 1,
            'stroke': 'green',
            'fill': 'yellow',
            'zIndex': 0
        })
        .add();
    };
    

    Finnaly redraw 事件可用于缩放后重绘椭圆:

    $(function() {
      var drawEllipse = function(chart, x, y, xr, yr) {
        // get pixel coordinates of rect
        var x1 = chart.xAxis[0].toPixels(x-xr)
        var x2 = chart.xAxis[0].toPixels(x+xr)
        var y1 = chart.yAxis[0].toPixels(y-yr)
        var y2 = chart.yAxis[0].toPixels(y+yr)
        // remove previous ellipse
        var rectClass = 'operating-point-ellipse'
        $('.' + rectClass).remove()
        // draw ellipse using rect()
        chart.renderer.rect(x1, y2, x2 - x1, y1 - y2, '50%')
          .attr({
            'stroke-width': 1,
            'stroke': 'green',
            'fill': 'green',
            'fill-opacity': 0.2,
            'zIndex': 0
          })
          .addClass(rectClass)
          .add();
      };
    
      $('#container').highcharts({
        chart: {
          events: {
            redraw: function() {
              drawEllipse(this, 22.42, 23.35, 6, 3);
            },
            load: function() {
              drawEllipse(this, 22.42, 23.35, 6, 3);
            }
          }
        },
        //...
      });
    });
    

    在 jsFiddle 上查看完整代码:http://jsfiddle.net/arybalko/rcct2r0b/

    【讨论】: