1

I have two series and their intersection point. I want to have an oval (ellipse) on a chart with center in intersection. Oval radiuses should be set in terms of axis units to show area of interest for each axis.

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]
        ]
      }
    ],
})

How can I programmatically draw an oval in intersection and make zoom work?

Anton Rybalko
  • 1,229
  • 17
  • 23

3 Answers3

4

You can use Renderer.createElement to create other SVG elements in Highcharts:

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

For translating to axis units use toPixels as @Anton Rybalko suggested.


Live demo: http://jsfiddle.net/kkulig/ds6aj5yp/

API references:

Kamil Kulig
  • 5,756
  • 1
  • 8
  • 12
3

The SVG Renderer is not really a great answer.

The polygon feature should be used (with many points, which you can generate offline in a backend, or analytically in the front end):

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/

Jonathan Nikkel
  • 111
  • 1
  • 4
  • Wow, useful feature! Thanks for the answer, but I need to show the area around the point of interest with specific radius. So I need to calculate several points for polygon to draw an ellipse. I don't want to do this :) – Anton Rybalko Nov 09 '18 at 13:03
2

To draw a circle, line etc SVGRenderer can be used. But there is no method to draw an ellipse. However rect() with rounded corners can be used.

Following code can be used to draw an ellipse in point (100, 200) px, horizontal radius 20 px and vertical radius 10 px:

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

To specify x, y and radiuses in terms of axis untits Axis.toPixels() can be used. If we need to convert point (22.42, 23.35) to pixels it can be done like:

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

So function to draw an ellipse would be:

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 event can be used to redraw ellipse after zoom:

$(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);
        }
      }
    },
    //...
  });
});

See full code on jsFiddle: http://jsfiddle.net/arybalko/rcct2r0b/

Anton Rybalko
  • 1,229
  • 17
  • 23