Utilizing HighCharts' Reflow Feature for Dynamic Chart Resizing

Our Angular application utilizes highcarts-ng for implementing HighCharts.

Check out the Chart Maximize and Minimize function that is currently operational:

function expandChartPanel() {
    vm.chartMaxed = !vm.chartMaxed;

    viewHeader = ScopeFactory.getScope('viewHeader');
    highChart  = ScopeFactory.getScope('highChart');

    var chart = highChart.chartObject;
    var highChartContainer       = document.getElementById("highchart-container");
    var highChartContainerWidth  = document.getElementById('highchart-container').clientWidth;
    var highChartContainerHeight = document.getElementById('highchart-container').clientHeight;

    var windowWidth  = window.innerWidth;
    var windowHeight = window.innerHeight;

    if (vm.chartMaxed) {

        vs.savedWidth  = highChartContainerWidth;
        vs.savedHeight = highChartContainerHeight;

        console.log('savedWidth  = ', vs.savedWidth);
        console.log('savedHeight = ', vs.savedHeight);

        root.chartExpanded          = true;
        viewHeader.vh.chartExpanded = true;
        highChart.highChartMax      = true;

        highChartContainerHeight = document.getElementById('highchart-container').clientHeight;
        windowWidth  = window.innerWidth;
        windowHeight = window.innerHeight;

        highChart.chartConfig.size.width  = windowWidth;
        highChart.chartConfig.size.height = windowHeight - 220;

        chart.setSize(windowWidth, windowHeight - 220);
    }
    else {
        root.chartExpanded          = false;
        viewHeader.vh.chartExpanded = false;
        highChart.highChartMax      = false;

        highChart.chartConfig.size.width  = vs.savedWidth;
        highChart.chartConfig.size.height = vs.savedHeight;

        chart.setSize(vs.savedWidth, vs.savedHeight);
    }

    highChart.restoreChartSize();
}

Also included is the reflow function:

function restoreChartSize() {
    console.log('restoreChartSize');
    if (!vs.chartObject.reflowNow) {
        vs.chartObject.reflowNow = vs.chartObject.reflowNow = function() {
            this.containerHeight = this.options.chart.height || window.window.HighchartsAdapter.adapterRun(this.renderTo, 'height');
            this.containerWidth  = this.options.chart.width  || window.window.HighchartsAdapter.adapterRun(this.renderTo, 'width');
            this.setSize(this.containerWidth, this.containerHeight, true);
            this.hasUserSize = null;
        }
     }

     vs.chartObject.reflowNow();
}

The above reflow function functions properly in this jsFiddle example, but not within our app.

You can find the complete Gist file of our HighChartsDirective here.

After clicking on Maximize, the chart expands to the full size of the browser window. However, upon resizing the browser window, calling the restoreChartSize function does not resize the chart to auto-size 100% as intended.

Before Maximizing: https://i.stack.imgur.com/d4Guh.png

After Maximization:

https://i.stack.imgur.com/YqegF.png

Upon resizing the browser window:

window.onresize = function(event) {
    console.log('window resizing...');
    highChart = ScopeFactory.getScope('highChart');
    highChart.restoreChartSize();
    console.log('highChart.chartConfig = ', highChart.chartConfig);
};

https://i.stack.imgur.com/d4Guh.png

^ reverts back to smaller static sizes instead of auto-size 100%

Answer №1

To manually trigger a reflow in the chart, you can add a new method like this:

chart.reflowNow = function(){
    this.containerHeight = this.options.chart.height || window.window.HighchartsAdapter.adapterRun(this.renderTo, 'height');
    this.containerWidth = this.options.chart.width || window.window.HighchartsAdapter.adapterRun(this.renderTo, 'width');
    this.setSize(this.containerWidth, this.containerHeight, false);
    this.hasUserSize = null;
}

Instead of using manual resizing with setSize(), simply call chart.reflow() when needed.

Here's an example demonstrating this: jsFiddle

Original reference source: github-issue

Update for ng-highcharts users

If you are using the ng-highcharts library, to achieve this functionality, extract the chart object in the controller with the highcharts-ng dependency and include the reflowNow function, as shown below:

var chart = this.chartConfig.getHighcharts();
chart.reflowreflowNow = function (){ ... }

This method is recommended by the author of ng-highcharts for custom operations. More details can be found here along with this fiddle.

Answer №2

I was able to discover a different solution that ended up being the only one that worked for me. Surprisingly, it was quite simple and easy to implement. For those who may be facing a similar issue, I have provided links to the resources that helped me resolve the problem.

To fix this issue, you just need to include the following code snippet in your chart configuration object, at the same level as the config.series or config.options. Although the comment provides some information, the actual solution that worked for me involved using $timeout with a delay of 0 seconds.

*Specifically for highcharts-ng usage

http://example.com/unique-link-here

$scope.chartConfigObject = {
    
    // A function to trigger reflow in bootstrap containers
    // Refer to: http://examplelink.com and https://github.com/example/repo
    func: function(chart) {
        $timeout(function() {
            chart.reflow();
            // The following event will initiate all chart instances to reflow
            //$scope.$broadcast('highchartsng.reflow');
        }, 0);
    }
};

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

Manipulating a 2D array in Javascript and Jquery: Implementing push functionality

I am trying to set up an array structure as follows: track[divID][wrapID] However, when I attempted track[divID][wrapID] = wrapID, I encountered an issue. This is because I need to add more elements to the second dimension in another loop, like this: tr ...

Unable to load the JSON texture file

I recently exported a 3D model to JS from Blender, but I'm encountering an issue with the texture not showing up properly. Even when I remove the texture file, the browser generates an error saying that 'map.png' cannot be found. This indica ...

What is the process of accessing JSON data from a server using AngularJS within the Eclipse environment?

Here is a snippet of my HTML code that I have pasted in the WebContent folder created using Dynamic Web Project in eclipse: <!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <title>Insert title here</title> < ...

Once the stripe token is generated, proceed to submit the form

Having issues submitting a form using jQuery with the Stripe.js plugin. I need to submit the form after creating a Stripe token. The jQuery validation is working correctly, but I'm getting an error message in the console saying "object is not a functi ...

How to surround values and keys with double quotes using regular expressions in JavaScript

I am in need of a valid JSON format to request ES. I currently have a string that looks like this: { time: { from:now-60d, mode:quick, to:now } } However, when I attempt to use JSON.parse, I encounter an error because my ...

The specific module 'franc' does not have the export named 'default' as requested

Every time I attempt to use the franc package, I encounter the following error message: "The requested module 'franc' does not provide an export named 'default'." Unfortunately, I am unsure of what this means, despite trying to resolve ...

Troubleshooting issues with AngularJS routing

Having trouble clicking on the show button and seeing anything displayed. I've spent a lot of time on this without success, can someone please assist. Files.... app.js controller.js index.html show.html index.html <html ng-app='Java4sApp& ...

Access the outcome by utilizing a for loop

Within my code, I am utilizing both a function and a loop: var songs = Musics.searchSongs(query).then(function(rs) { return rs; }); for (var i = 0; i < songs.length; i++) { console.log(songs[i]); } I am now looking for a way to execute the ...

Encountered an error while attempting to execute the command npx create react app: spawn UNKNOWN error occurred

After attempting to execute a basic npx create-react-app, an unexpected error occurred: D:\>npx create-react-app abc npx: installed 67 in 4.255s Creating a new React app in D:\abc. Installing packages. This might take a couple of minutes. In ...

Compare the precise value of $(window).height() to a specific scroll value

Initially, I retrieve $(window).height() and compare this height with the specific scroll value. $(window).scroll(function (event) { var scroll = $(window).scrollTop(); var windowHeight = $(window).height(); console.log("window hei ...

Is it possible to alter the value of a global variable within a function and switch its value based on a local variable?

Currently, I am facing an issue with changing the value of a global variable dynamically from a function. The variable has a global scope and is also present in the same function as a local variable. However, despite my efforts, I am unable to successful ...

Refreshing the Dropdown Menu with Jquery

Looking for a way to create a reusable dropdown menu using css/jquery? Check out this codepen: https://codepen.io/anon/pen/NxXXPg Is there a method to reset the 'active' status when clicking on a blank space or another html element? Here's ...

Verify in Jquery whether a table row contains no elements with a specified class before removing any duplicates

I have an HTML table: <div class="1233">hello</div> <table cellpadding="0" cellspasing="0" class="sortable zebra tablesorter tablesorter-default" id="articles-table"> <thead> <tr class="tablesorter-headerRow"> ...

Guide to installing a dynamic favicon on a Next.js application for a specific route

I am trying to set up different favicons for my Next.js app based on the route. Here is where I want to implement this feature, displaying the country's flag as the favicon when a user navigates to that specific page. Below is the code snippet from m ...

Check if a Discord.js bot responds based on whether a user holds a designated role

I'm looking to make my bot respond to a specific role. If the user does not have that role, I want the bot to reply with a message saying "You are not allowed to perform this command." Here is the code snippet I am using: client.on("message", (message ...

Tips for adding content to a textarea with JavaScript without disrupting the editing history

I have a specific requirement where I want the user to be able to highlight text in a textarea, then press ctrl + b to automatically surround that selected text with stars. Here is what I envision happening: 1) The initial content of the textarea is: "he ...

Load a page and sprinkle some contents with a slide effect

I am brand new to jQuery and just starting out, so please excuse me if this question seems basic or silly. I would like the header and footer of my page to stay in place while the center content slides in from the right side when the page loads. This websi ...

Controller unable to properly increment values

$scope.isChecked = function(id){ var i=0,j=0,k=0; //$scope.abc[i].usertype[j].keywords[0].key_bool=true; if($scope.abc[i].type_selected == true){ while($scope.abc[i].usertype.length){ while($scope.abc[i].userty ...

Is there a way for me to retrieve SCSS color variables within the javascript of a Vue template?

I have a unique challenge in my application involving a component called Notification. To bring notifications to other components, I utilize the mixin method toast('message to display', 'color-variable'). My goal is to set the backgroun ...

Unable to access path for children through buttons in parent path

As a data scientist entering the world of frontend development, I find myself faced with the task of creating a UI at the request of my boss. Please bear with me as I attempt to explain my issue in layman's terms. Currently, I am using Vue.js and hav ...