Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HighCharts: How to use reflow to allow auto-resize after changing size

In our Angular app we're using highcarts-ng for our HighCharts implementation.

Here is the Chart Maximize and Minimize function, which works:

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();
}

Here 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();
}

This reflow function above, works perfectly in this jsFiddle, but not in our app.

The full Gist file of our HighChartsDirective file.

After clicking Maximize, the chart will expand to the full size of the browser window, but then after dragging to resize the browser window, I call the restoreChartSize function, which activates the reflow.

However the size of the chart does not go to auto-size 100% 100%, it goes back to the previous size of the chart :(

Before Maximize: enter image description here

After the Maximize function:

enter image description here

Now after resizing the browser window:

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

enter image description here

^ back to the smaller static sizes, not auto-size 100%

like image 256
Leon Gaban Avatar asked Jul 31 '15 20:07

Leon Gaban


People also ask

How do I change the size of my Highcharts?

Height and width is set either by setting a height and width of the container div, or by setting the chart. height and chart. width Highcharts options.

What is reflow in Highcharts?

reflow: booleanWhether to reflow the chart to fit the width of the container div on resizing the window.

Is Highcharts responsive?

Since Highcharts 5.0 you can create responsive charts much the same way you work with responsive web pages. A top-level option, responsive, exists in the configuration. One of the most handy options is chart.


2 Answers

You can do this by adding a new method to chart that will manually trigger the reflow like so:

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;
}

Then whenever you want to get away from manual resizing using setSize() just call chart.reflow()

Here's an working example: jsFiddle

Reference taken from: github-issue

UPDATE for ng-highcharts users

For doing this when using ng-highcharts library, you can simply pull out the chart object in the controller that has highcharts-ng dependency and add the reflowNow function, like so:

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

This is also the recommended way to pull out chart to do custom jobs by author of ng-highcharts as noted here and this fiddle.

like image 188
Shaunak Avatar answered Oct 21 '22 22:10

Shaunak


I ended up finding an alternative solution to be the only thing I could get working, and it actually was pretty simple and straight forward to do. In case anyone else is looking for a fix for this, here's links to the resources that were useful and solved the issue for me.

You can simply add this to your chart config object, at the same level as the config.series or config.options. The comment references info but the actual solution that worked for me uses $timeout with 0 seconds, here

*For using highcharts-ng obviously

http://plnkr.co/edit/14x7gfQAlHw12XZVhWm0?p=preview

$scope.chartConfigObject = {

    // function to trigger reflow in bootstrap containers
    // see: http://jsfiddle.net/pgbc988d/ and https://github.com/pablojim/highcharts-ng/issues/211
    func: function(chart) {
        $timeout(function() {
            chart.reflow();
            //The below is an event that will trigger all instances of charts to reflow
            //$scope.$broadcast('highchartsng.reflow');
        }, 0);
    }
};
like image 29
jaredwilli Avatar answered Oct 21 '22 20:10

jaredwilli