Having trouble getting Highcharts SVG element to refresh? Looking to incorporate custom freeform drawing features within Highcharts?

I have implemented highchart for graph rendering and utilized the renderer to draw a custom line within the chart. I am looking for a way to recalculate and repaint this path whenever there is a change in data. The framework being used is highcharts-ng along with Angular. Below is the code snippet:-

{
            options: {
                chart: {
                    type: 'line',
                    marginTop: 80,
                    style: {
                        fontFamily: 'serif',
                        fontSize:14
                    },
                    events:{
                        redraw:function(e){
                            console.log(e)
                            var elem=e.target.renderer.Element()
                            console.log(elem)
                            console.log('I am Reloaded')
                        }
                    }
                    //backgroundColor:'rgba(255, 255, 255, 0.1)'
                },
                exporting: {
                    enabled: false
                },
                plotOptions: {
                    series: {
                        animation: false,
                        marker: {
                            symbol: 'circle'
                        },
                        lineWidth: 1,
                        events: {
                            afterAnimate: function () {
                                console.log('lol')
                            }
                        }
                    }
                },
                colors: ['#2C91DE', '#165A8E'],
            },
            tooltip: {
                style: {
                    padding: 10,
                    fontWeight: 'bold'
                }
            },
            title: {
                text: ""
            },
            loading: false,
            series: [],
            func: (chart) => {
                this.$timeout(() => {
                    console.log(chart)
                    var ren = chart.renderer;
                    var group = ren.g().add();
                    var attrForVLine = {
                        'stroke-width': 3,
                        stroke: '#2C91DE',
                        dashstyle: 'solid'
                    };

                    for (var i = 0; i < chart.series[0].data.length; i++) {
                        var plot1 = chart.series[0].data[i];
                        var plot2 = chart.series[1].data[i];

                        /**
                         * Creating line segments across the graphs.
                         * Keeping the ZIndex low for these lines.
                         */
                        ren.path([
                            'M',
                            plot1.plotX + chart.plotLeft,
                            plot1.plotY + chart.plotTop,
                            'V',
                            plot2.plotY + chart.plotTop
                        ]).attr(attrForVLine).add();
                    }
                }, 1000);
            },
            yAxis: {
                tickInterval: 40,
                title: {
                    text: ''
                }
            },
            xAxis: {
                startOnTick: true,
                endOnTick: true,
                lineColor: '#000000',
                type: 'datetime',
                labels: {
                    rotation: -60,
                    format: '{value:%m-%d-%Y}',
                    align: 'right'
                }
            }
        };

Even though the chart renders correctly initially with the vertical lines, they do not update when the data changes. I am seeking assistance on how to dynamically update the rendered SVG elements. Your help is appreciated. Thank you.

The below chart showcases vertical lines drawn by the renderer https://i.sstatic.net/y6eR5.png

Upon changing the data, the lines drawn by the renderer do not get removed but remain static even though the graph repaints with new data points as demonstrated below https://i.sstatic.net/lfrS3.png

I would like to clear and redraw these lines dynamically.

Answer №1

Although it may be a little late, the SVGs are actually implemented as an overlay SVG on top of the chart's SVG. This means that when the chart changes, the SVGs remain independent and do not change along with it. To update the SVGs accordingly, you would need to manually delete the previous SVGs and then redraw them. One way to achieve this is by listening to the "render" event of the chart and calling a function to redraw your SVGs. Here's an example:

Highcharts.chart('container', {
  chart: {
    events: {
      render: function() {
        const points = [{
            x: 0.1,
            y: 0.1
          },
          {
            x: 0.2,
            y: 0.4
          },
          {
            x: 0.3,
            y: 0.9
          }
        ];
        const path = [];
        for (let i = 0; i < points.length; i++) {
          i === 0 ? path.push("M") : path.push("L");
          path.push(this.xAxis[0].toPixels(points[i].x));
          path.push(this.yAxis[0].toPixels(points[i].y));
        }
         if (this.customPath) {
          this.customPath.destroy()
          this.customPath = undefined
        }
        this.customPath = this.renderer.g('customPath').add()
        
        this.renderer.path(path)
          .attr({
            stroke: 'green',
            'stroke-width': 1,
            zIndex: 1
          })
          .add(this.customPath);
      }
    }
  },
  xAxis: {
    lineWidth: 1,
    min: 0,
    max: 1,
    minorTicks: true
  },

  yAxis: {
    lineWidth: 1,
    min: 0,
    max: 1,
    minorTicks: true
  },

  legend: {
    enabled: true
  },

  series: [{ id: "dummy" }]

});
<script src="https://code.highcharts.com/highcharts.js"></script>

<div id="container"></div>

JSFiddle link

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Notification from Apple - one message, multiple alerts received

After sending a notification to an iOS device, only one message is received, but the alert pops up multiple times (iOS 7+). However, when the notification is pushed to an Android device, everything works as expected: one message received and one alert disp ...

Tips for dynamically updating an HTML value with Javascript

Summary of My Issue: This involves PHP, JS, Smarty, and HTML <form name="todaydeal" method="post"> <span id="fix_addonval"></span> <input type="radio" name="offer" id="offer_{$smarty.section.mem.index+1}" value="{$display_offe ...

Using Node.js setTimeout method

I'm struggling with understanding how to utilize the setTimeOut function in NodeJS. Let's say I need: function A() to be executed every 10 seconds. If function A returns 'true' from its callback, it should trigger a call to a specific ...

What is the best way to search for documents that have all conditions met within a sub-array entry?

My rolesandresponsibilities collection document is displayed below: [{ "_id": { "$oid": "58b6c380734d1d48176c9e69" }, "role": "Admin", "resource": [ { "id": "blog", "permissions": [ " ...

Avoid sudden page movements when validating user input

After successfully implementing the "Stars rating" feature from https://codepen.io/462960/pen/WZXEWd, I noticed that the page abruptly jumps up after each click. Determined to find a solution, I attempted the following: const labels = document.querySelect ...

Leveraging Ajax to fetch JQuery

Currently, I am utilizing Ajax to trigger a PHP file for processing upon form submission. The JQuery form validation mechanism evaluates the variables' values to determine whether to proceed with submitting the form or to return false while displaying ...

What is the best way to create operating system-neutral file paths in Node.js?

I'm currently fixing issues with my code while running integration tests on an EC2 instance of a Windows machine. Despite resolving the filenames-are-too-long problem, several paths remain unresolved due to being hardcoded for UNIX systems. I've ...

The Issue of Double-Clicking on Table Cells in Internet Explorer 8

I implemented a JQuery function to add a double click event listener to a table, which triggers a modal popup when a cell is double-clicked. While this functionality works seamlessly in Firefox, there is an issue in IE8 where double-clicking a cell highli ...

Check if an element possesses a specific property and corresponding value in JavaScript

I was looking to determine if an object has a specific property with a certain value, and wanted to search for it within an array of objects. var test = [{name : "joey", age: 15}, {name: "hell", age: 12}] After testing the code snippet below, I realized ...

Designing a personalized look for a property with Styled-System

Styled-System offers various props related to css grid: I have a suggestion for a new prop, gridWrap. My idea is to allow users to adjust the auto-fit value using the gridWrap prop. Here's the base CSS code: grid-template-columns: repeat(auto-fit, mi ...

Leveraging Parse methods within a Node JS Cron job

My current task involves writing a Cron Job that requires the use of Parse methods. I have the following code snippet at hand: var crontab = require('node-crontab'); var jobId = crontab.scheduleJob("* * * * * *", function(){ ...

What is the best way to add a new item to an object using its index value?

Can the Locations object have a new property added to it? The property to be added is: 2:{ name: "Japan", lat: 36, lng: 138, description: 'default', color: 'default', url: 'default' } The current Location ...

I am having trouble getting the hoverOffset feature to work with doughnut charts in vue-charts.js

It appears that no matter what I try, the hoverOffset property is not working on my doughnut charts. Here's the component code: <script> import { Doughnut } from 'vue-chartjs' export default { extends: Doughnut, props: { ch ...

Issues with Gulp and Browser Sync integration

Encountering errors while running Gulp with Browser Sync in Chrome: NonESPMessageInterface --- nonEspMessageInterface.js:8 TypeError: Cannot read property 'insertBefore' of null --- angular.js:13708 Checklist message was invalid, from origin # ...

Organize an array based on its ratio

I am attempting to organize an array based on the win and lose ratio of each player. This is how my code currently looks: const array = [{playerName: 'toto', win: 2, lose: 2}, {playerName: 'titi', win: 0, lose: 0}, {playerName: &apo ...

Creating redux reducers that rely on the state of other reducers

Working on a dynamic React/Redux application where users can add and interact with "widgets" in a 2D space, allowing for multiple selections at once. The current state tree outline is as follows... { widgets: { widget_1: { x: 100, y: 200 }, widg ...

Implementing $timeout within the Scope.$watch function allows for monitoring

Hi there, I'm currently working on implementing some functionality in Angular but running into a few issues. I have an ng-model and example-directive configured as follows: <input ng-model="model" type="text" class="form-control"> <div ex ...

Setting up a Variable with an Object Attribute in Angular

I am attempting to create a variable that will set a specific property of an object retrieved through the get method. While using console.log in the subscribe function, I am able to retrieve the entire array value. However, as a beginner, I am struggling ...

Rotating an input 90 degrees within a div for unique positioning

I used JavaScript to make an input range vertical, like so: var range_pitch = document.createElement("input"); range_pitch.setAttribute("type", "range"); range_pitch.style.webkitTransform = "rotate(90deg)"; range_pitch.style.mozTransform = "rotate(90deg)" ...

Having trouble getting the calendar to display correctly on the FullCalendar AngularJS Directive

As a beginner in AngularJS, I am facing the challenge of integrating an Admin LTE full calendar feature into my web application. Fortunately, I came across an Angular directive specifically designed for the Arshaw FullCalendar JQuery plugin. You can check ...