Search code examples
javascriptsvghighcharts

Dynamically changing the attribute of an svg element in a highcharts chart


For a certain application, I have created draggable SVG rectangles in my highcharts chart. I wish to access them and modify their attributes dynamically from an external function where I have the 'chart' variable.

This is my svg rect:

var chart = this,
    lineWidth = 2,
    draggablePlotLine = chart.renderer.rect(100, chart.plotTop, lineWidth, chart.plotHeight)
    .attr({
        fill: 'blue'
    })
    .add();

I wish to do something like this from function say 'changeLinePosition':

if (
   //a certain condition is met
) {
    draggablePlotLine.attr({
    x: //a specific value
})
}

Here is what I have now:

var chart = Highcharts.chart('container', {
  chart: {
    events: {
      load() {
        var chart = this,
          lineWidth = 2,
          draggablePlotLine = chart.renderer.rect(100, chart.plotTop, lineWidth, chart.plotHeight)
          .attr({
            fill: 'blue'
          })
          .add();
        chart.container.onmousemove = function(e) {
          if (draggablePlotLine.drag) {
            let normalizedEvent = chart.pointer.normalize(e),
              extremes = {
                left: chart.plotLeft,
                right: chart.plotLeft + chart.plotWidth
              };
            // Move line
            if (
              e.chartX >= extremes.left &&
              e.chartX <= extremes.right
            ) {
              draggablePlotLine.attr({
                x: e.chartX
              })
            }
          }
        }
        draggablePlotLine.element.onmousedown = function() {
          draggablePlotLine.drag = true
        }
        draggablePlotLine.element.onmouseup = function() {
          draggablePlotLine.drag = false
        }
      }
    }
  },
  series: [{
    name: 'Installation',
    data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
  }],
});
#container {
  min-width: 310px;
  max-width: 800px;
  height: 400px;
  margin: 0 auto
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://rawgithub.com/highcharts/draggable-points/master/draggable-points.js?1"></script>
<div id="container"></div>

Here is the jsfiddle link for more information: https://jsfiddle.net/m8tr2Lcw/


Solution

  • You can easily do that by adding a reference for the draggablePlotLine into the chart variable.

    var chart = this,
      lineWidth = 2,
      draggablePlotLine = chart.draggablePlotLine = chart.renderer.rect(100, chart.plotTop, lineWidth, chart.plotHeight)
    

    Later, inside of your function, you can access it by the chart.draggablePloLine notation:

    function changeLinePosition() {
      chart.draggablePlotLine.attr({
            x: 200
      });
    }
    

    Demo: https://jsfiddle.net/BlackLabel/nx7j6af0/