6

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%

Leon Gaban
  • 36,509
  • 115
  • 332
  • 529

2 Answers2

7

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.

Shaunak
  • 17,377
  • 5
  • 53
  • 84
  • Thanks, but quick q, we don't init the chart with `var chart = new Highcharts.Chart({` Here is the full Gist of our DisplayChart function, how would I create a variable to connect to the chart? https://gist.github.com/leongaban/2e1e1c5cf2cd76e9b3a6 – Leon Gaban Jul 31 '15 at 20:52
  • @LeonGaban updated the answer that you could use based on your gist. Just remember to do somewhere after chart has been initialized. – Shaunak Jul 31 '15 at 21:01
  • Ugh I still can't get the chart associated correctly, I added more code above, if I'm still having problems later... may have to ask the other dev to refactor his code to how you have the highcharts setup in jsfiddle – Leon Gaban Jul 31 '15 at 21:19
  • 1
    did you try doing it in the controller as i suggested in the update? Which ever controller has access to chart_Config object. It is not very clear how you have wired up the chart from the gist you posted. Not sure where 'vs' comes from. But I am assuming it is inside the controller where you are doing something like var vs = this; in the beginning. IN which case just doing vs.chartConfig.getHighcharts(); should get the job done for you. This is actually the reason I prefer writing my own smaller directives than using monolithic ones written by someone else. – Shaunak Jul 31 '15 at 21:25
  • Sorry, I've updated my Gist with the full Directive code now, and yes trying out stuff in the Controller `vs = $scope` – Leon Gaban Jul 31 '15 at 21:32
  • Okay, I have left a comment for you on the Gist. Hope that solves the problem. You don't need to pull out chart object, the original dev is already doing it and saving the chart in `chartObject` . just use the same object and add the `reflowreflowNow ` function to it. I have suggested a place to add it in the gist comment, but it doesn't have to go in there. – Shaunak Jul 31 '15 at 21:45
  • Ah getting a little further now, this is working `vs.chartObject.reflowreflowNow = vs.chartObject.reflowNow = function()` – Leon Gaban Aug 01 '15 at 20:32
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/84901/discussion-between-leon-gaban-and-shaunak). – Leon Gaban Aug 01 '15 at 20:37
3

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);
    }
};
jaredwilli
  • 11,762
  • 6
  • 42
  • 41