Highchart角度指令不会从动态(ajax)数据表重绘 [英] Highchart angular directive doesn't redraw from dynamic (ajax) data table

查看:70
本文介绍了Highchart角度指令不会从动态(ajax)数据表重绘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个AngularJs应用程序,它从API中检索数据并将它们填充到表中。然后,我使用Highcharts根据该表绘制图表。如果我在表中使用静态数据,它工作的很好,但是当我通过AJAX更新表时它不起作用。它不会重绘。

I have an AngularJs app that retrieves data from API and populates them into table. Then, I'm using Highcharts to draw chart based on that table. It is working fine if I'm using static data in the table, but it doesn't work when I update the table through AJAX. It doesn't get redraw.

指令:

Directive:

app.directive('highChart', function ($parse) {
    return {        
        link: function(scope, element, attrs) {
            scope.$watch('chartConfig', function (newVal) {
                if (newVal) {
                    var props = $parse(attrs.highChart)(scope);
                    props.chart.renderTo = element[0];
                    new Highcharts.Chart(props);
                }
            });
        }
    };
});

控制器:

appControllers.controller('SummaryController', ['$scope', '$timeout', 'Summaries',
    function ($scope, $timeout, Summaries) {
        // Request from API
        Summaries.get({ table: 'level'}).$promise.then(
            // success callback
            function(data) {
                $scope.levels = data.level[0][today];
                $scope.chartConfig = {
                    data: {
                        table: document.getElementById('daily-level')
                    },
                    chart: {
                        type: 'column'
                    },
                    title: {
                        text: 'Data extracted from a HTML table in the page'
                    },
                    yAxis: {
                        allowDecimals: false,
                        title: {
                            text: 'Units'
                        }
                    },
                    tooltip: {
                        formatter: function () {
                            return '<b>' + this.series.name + '</b><br/>' +
                                this.y + ' ' + this.x;
                        }
                    }
                 };
            }
    }]);

HTML

<div id="top-chart" high-chart="chartConfig"></div>

它只显示一个空的图表。我的表确实通过AJAX请求进行更新。我甚至在指令中检查了 console.log(props),并且 props.data.table 显示更新表,但不知何故图表不会重绘。我尝试了多种方式来做到这一点,但都取得了相同的结果。目前,我只是使用jQuery超时刷新图表,它的工作原理,但这意味着我在控制器内使用DOM操作。我试图实现这个使用指令。

It just displays an empty chart. My table does get updated by the AJAX request. I even did check for console.log(props) inside the directive and props.data.table does show the updated table, but somehow the chart doesn't get redraw. I've tried multiple ways to do this, but all come down to the same result. Currently, I'm just using jQuery timeout to refresh the chart, it works but that means I'm using DOM manipulation inside controller. I'm trying to achieve this using directive.

推荐答案

好的。我设法让它工作。我认为问题在于,Highcharts没有意识到这些变化,或者是否知道这些变化,那时DOM还没有完成渲染。这是代码的工作版本。

Ok. I managed to get it to work. I think the problem is that, Highcharts does not aware about the changes or if it knows about the changes, the DOM at that moment hasn't finish rendering. This is the working version of the code.

指令:

Directive:

app.directive('highchart', function($parse, $timeout) {
    return {
        restrict: 'E',
        template: '<div></div>',
        replace: true,
        link: function(scope, element, attrs) {
            var config = $parse(attrs.config)(scope);
            $(element[0]).highcharts(config);

            scope.$watch(attrs.watch, function(newVal) {
                if (newVal) {
                    var complete = function (options) {
                        var chart = $(element[0]).highcharts();
                        // capture all available series
                        var allSeries = chart.series;
                        for (var i = 0; i < allSeries.length; i++) {
                            allSeries[i].setData(options.series[i].data, false);
                        }

                        chart.redraw();
                    };

                    // doesn't work without the timeout 
                    $timeout(function() {
                        Highcharts.data({
                            table: config.data.table,
                            complete: complete
                        });   
                    }, 0);
                }
            });
        }
    };
});

在控制器中,我们可以设置配置。

In controller, we can setup the config.

    $scope.chartConfig = {
         // config here
    };

使用它:

To use it:

<highchart config="chartConfig" watch="levels"></highchart>

其中属性 config 绑定到$ $ scope.chartConfig watch watch的触发器$ scope() code>在指令中。当控制器中的 $ scope.levels 更改时,它会重新呈现图表。

where the attribute config is bind to the $scope.chartConfig and watch is the trigger for watch.$scope() in the directive. When $scope.levels changes in controller, it would re-render the chart.

实际上我没有比如指令依赖于我现在拥有的 watch 属性,但我不确定最佳或其他方式是做什么的。如果有人有更好的主意,请让我知道。

I don't actually like the dependency of the directive to the watch attribute that I have right now, but I'm not sure what is the best or other way to do this. If anyone have a better idea, do let me know.

请注意,这只会将表格转换为高图。对于其他人,您可能需要使用其他angularjs highcharts指令。

Please note that this will only work to convert table to highchart. For others, you might need to use other angularjs highcharts directive.

这篇关于Highchart角度指令不会从动态(ajax)数据表重绘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆