javascript - Highchart Angular Directive(指令)不会从动态(ajax)数据表中重绘

标签 javascript ajax angularjs highcharts

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

指令:

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

Controller :

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 超时来刷新图表,它可以工作,但这意味着我在 Controller 内使用 DOM 操作。我正在尝试使用指令来实现此目的。

最佳答案

好的。我设法让它发挥作用。我认为问题在于,Highcharts 不知道这些变化,或者即使它知道这些变化,那一刻的 DOM 还没有完成渲染。这是代码的工作版本。

指令:

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

在 Controller 中,我们可以设置配置。

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

使用它:

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

其中属性config绑定(bind)到$scope.chartConfig,而watchwatch.$scope(的触发器) ) 在指令中。当 Controller 中的 $scope.levels 发生变化时,它将重新渲染图表。

我实际上不喜欢指令对我现在拥有的 watch 属性的依赖,但我不确定什么是最好的或其他方法来做到这一点。如果有人有更好的想法,请告诉我。

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

关于javascript - Highchart Angular Directive(指令)不会从动态(ajax)数据表中重绘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20672724/

相关文章:

javascript - 除了使用多行变量之外,还有其他方法可以存储 HTML 代码块吗?

javascript - 授予 jQuery 插件访问选定 DOM 对象的权限

javascript - Rxjs 包装 D3 (Observable) 中的其他库函数

javascript - 如何将 $http.get 的结果存储到变量中

javascript - 将哈希密码发送到 WebAPI

javascript - 如何对输入类型范围进行分组并保持所有范围组合在一起的最大值为 100%

Javascript for 循环查找之前、等于、之间和之后的值?

javascript - 如何使用 jquery ajax 将 json 对象正确传递给 Flask 服务器

javascript - MVC4 ajax调用并正确返回数据

javascript - 如何使用 for 循环迭代 Angular $scope 变量