0
votes

I have several charts utilizing the highcharts plugin and directive, and tables using ng-grid through my app. When viewing a page with a chart or table directly after viewing the homepage, the charts and tables don't respect their frame widths, and expand to a width of 1900px (see image: http://i.imgur.com/6uDrZBc.png?1). After refreshing the page once, the charts and grids fit within their frames as they should. What could be causing this issue?

Code below, let me know if any other code would be helpful. Thanks.

HTML for one of the offending pages:

<div class="col-md-7" id="chart">
    <div class="panel panel-default">
        <div class="panel-heading" ng-init="isCollapsed = false">
            <div class="panel-title">
                Top 8 Drugs by 2013 Revenue
                <button class="pull-right btn btn-xs" ng-click="isCollapsed = !isCollapsed"><span
                        class="text-center"
                        ng-class="{'fa fa-plus': isCollapsed, 'fa fa-minus': !isCollapsed}"></span></button>
            </div>
        </div>
        <div class="panel-body" collapse="isCollapsed" ng-if="Revenues[0].evaluate_productRevenue2013 > 0">
            <div class="col-xs-12" ng-cloak>
                <highchart id="company-chart-overview-1" config="chartConfig"></highchart>
            </div>
            <div class="row-fluid col-xs-offset-5">
                <div class='my-legend'>
                    <div class='legend-title'>RxScore Safety Indicator </div>
                    <div class='legend-scale'>
                        <ul class='legend-labels'>
                            <li><span style='background:#008000;'></span>Low</li>
                            <li><span style='background:#FFFF00;'></span></li>
                            <li><span style='background:#E69628;'></span></li>
                            <li><span style='background:#FF0004;'></span>High</li>
                        </ul>
                    </div>
                </div>
            </div>
         </div>
    </div>
</div>

Highcharts config:

exports.getOverviewChart = function (RevenueSlices) { var companyName;

    var Series = [
        {name: 'Revenue ($MM USD)', data: [], type: 'column'}
    ];
    var cCategories = [];
    var colors = ['green', 'yellow', '#CD7D0F', 'red'];
    var thresholds = [47.17, 55.81, 61.83, 82.83];
    var cleanSlices = _.reject(RevenueSlices, function (sl) {
        return sl.BrandName === "Unknown";

    });

    cleanSlices = _.filter(cleanSlices, function (cs) {
        return Math.abs(cs.evaluate_productRevenue2013) > 0;
    });

    angular.forEach(cleanSlices, function (o) {
        var s = Math.abs(o.metric_rxscore);
        var color;
        if (s >= thresholds[2]) {
            color = colors[3];
        } else if (s >= thresholds[1]) {
            color = colors[2];
        } else if (s >= thresholds[0]) {
            color = colors[1];
        } else if (s >= 1) {
            color = colors[0];
        } else {
            color = 'lightgrey';
        }

        companyName = o.parent;
        cCategories.push(o.BrandName);
        Series[0].data.push({name: o.BrandName, color: color, y: Math.abs(o.evaluate_productRevenue2013)});
    });
   var overviewChart = {
        options: {
            chart: {
                type: 'StockChart'
            }, legend: {
                enabled: false
            },


            exporting: {
                enabled: false
            },
            plotOptions: {
                series: {
                    stacking: ''
                }
            }
        },
        size: {
            // width: 573,
            height: 380
        },
        xAxis: {
            title: {
                text: 'Drug'
            },
            categories: cCategories
        },
        yAxis: {
            title: {
                text: '2013 Revenue'
            },
            labels: {
                format: '{value} $MM USD'
            }


        }, credits: {
            enabled: false
        },
        series: Series,
        title: {
            style: { 'display': 'none' }
        }

    };


    return  overviewChart;

};

ng-grid options:

var tmp = companyChartService.getOverviewChart(Revenues.slice(0, 8));
$scope.colDefs = companyGridService.getColDefs();
$scope.ToolTipper = tooltipService.getTooltip;

$scope.colDefs = companyGridService.getColDefs();

$scope.myData = Revenues;
$scope.gridOptions = {
    data: 'myData',
    enableSorting: true,
    enableColumnResize: true,
    showGroupPanel: true,
    enableCellGrouping: true,
    showColumnMenu: true,
    enablePinning: true,
    showFilter: true,
    jqueryUITheme: true,
    //cellClass: 'drugName',
    columnDefs: 'colDefs'
    //rowClass: 'drugName'
};
1
Try calling window.resize() in your console. ng-grid 2.x has a bug with immediate rendering and non-fixed widths. If that fixes the rendering, then there may be a quick hack to fix it.c0bra
Thanks, that works when I put the window.resize() in a timeout block with a timeout of 2000 or more, and it also flashes the expanded grid/chart, so not an ideal solution. I've tried the ng-if solution proposed in one of your tutorials to no avail as well.Daniel Bogart

1 Answers

0
votes

This issue was being caused by errant css rules that were being applied with the ng-class directive. The css was not being removed until after the new state had loaded, so even though it wasn't visible, it affected the page width that ng-grid and highcharts use to determine their size. After rewriting the css and removing ng-class, the problem was solved.

Another few possible solutions for those with similar issues are highlighted in the ng-grid tutorial here http://ui-grid.info/docs/#/tutorial/108_hidden_grids:

  1. Give the grid a specific height and width as in the example below.
  2. Use an ng-if to prevent the grid from being rendered until the element it is in (tab/accordion/etc) is active, as in this plunker.
  3. Use the autoResize feature let the grid redraw itself as needed. This may cause some flickering as the check is on a 250ms cycle. Here's is a plunker demonstrating this.