HighCharts:如何使用reflow在改变大小后允许自动调整大小

7
在我们的Angular应用中,我们使用highcharts-ng来实现HighCharts。以下是图表最大化和最小化功能,它可以正常工作:
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();
}

这里是回流函数:

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

上述的回流函数在jsFiddle中运作得很好,但在我们的应用程序中却不行。

我们的HighChartsDirective文件的完整Gist文件

点击最大化后,图表将扩展到浏览器窗口的全尺寸,但是在拖动调整浏览器窗口大小后,我调用restoreChartSize函数,激活回流。

然而,图表的大小并没有自动调整为100% 100%,而是恢复到了先前的图表大小 :(

最大化之前: enter image description here

最大化后:

enter image description here

现在调整浏览器窗口大小后:
window.onresize = function(event) {
    console.log('window resizing...');
    highChart = ScopeFactory.getScope('highChart');
    highChart.restoreChartSize();
    console.log('highChart.chartConfig = ', highChart.chartConfig);
};

enter image description here

回到较小的静态尺寸,而不是自动调整大小为100%。

2个回答

7
您可以通过在图表中添加一个新的方法来手动触发重新布局,如下所示:
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;
}

每当您想要摆脱手动调整大小并使用setSize()时,只需调用chart.reflow()

这是一个工作示例:jsFiddle

参考来源:github-issue

ng-highcharts用户的更新

当使用ng-highcharts库时,您可以在具有highcharts-ng依赖项的控制器中提取图表对象并添加reflowNow函数,如下所示:

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

这也是ng-highcharts的作者建议的一种方式,可以通过如此来提取图表以进行自定义工作,详见此处和这个示例


1
你尝试按照我在更新中建议的在控制器中完成吗?无论哪个控制器都可以访问chart_Config对象。 从您发布的要点中,不太清楚您如何连接图表。不确定“vs”来自何处。但是我假设它在您正在执行类似于var vs = this;的控制器内部。在这种情况下,只需执行vs.chartConfig.getHighcharts();即可为您完成工作。这实际上是我更喜欢编写自己的较小指令而不是使用其他人编写的庞大指令的原因。 - Shaunak
抱歉,我已经在我的Gist中更新了完整的指令代码,是的,我正在控制器中尝试一些东西 vs = $scope - Leon Gaban
好的,我已经在Gist上为您留言了。希望这能解决问题。您不需要提取图表对象,原始开发人员已经在做并将图表保存在chartObject中。只需使用相同的对象并向其添加reflowreflowNow函数即可。我已经在Gist评论中建议了一个添加位置,但它不一定要放在那里。 - Shaunak
啊,现在有点进展了,这个vs.chartObject.reflowreflowNow = vs.chartObject.reflowNow = function()正在工作。 - Leon Gaban
让我们在聊天中继续这个讨论 - Leon Gaban
显示剩余3条评论

3
我最终找到了一种替代解决方案,这是我能够让它正常工作的唯一方法,而且实际上非常简单和直接。如果有人正在寻找解决此问题的方法,以下是对我有用并解决了该问题的资源链接。
您可以将此内容添加到图表配置对象中,与config.series或config.options位于同一级别。注释引用信息,但实际上对我有效的解决方案使用了0秒的$timeout,在此处。
*显然,对于使用highcharts-ng的情况。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接