减少绘制的系列数会产生控制台错误

时间:2013-07-29 08:46:03

标签: angularjs angularjs-directive dygraphs

我在AngularJS应用程序中使用Dygraphs来显示来自数据记录器的数据的时间序列图。角度处理在数据到达时检索新数据并更新图形序列,Dygraphs正在使用Angular $watch()很好地更新图表。当我想切换到一组不同的数据时,问题就出现了,特别是那些包含较少系列的数据。我看到一个控制台错误(在OS X 10.6.8上使用Safari 5.1.9):

'undefined' is not an object (evaluating 'this.series_[b].yAxis')

dygraph-combined.js的第2行。似乎没有发生任何不幸的事情,并且图表正确更新,但我宁愿它没有发生!

我在使Angular正确切换图形数据源时遇到了一些问题:对我来说有用的是在$timeout(,0)调用中更改数据源,同时立即更改其他选项。这意味着系列数量和系列标题和/或轴的数量之间会有(短暂的)不匹配。如果系列的数量没有改变或增加,我不会得到这个错误。任何人都可以看到出了什么问题,并告诉我如何避免它?

我写了一个Angular指令来实例化Dygraph:

'use strict';
angular.module('dygraphs', []);

angular.module('dygraphs').directive('mrhDygraph', function ($parse, $q) {
    return {
        restrict: 'A',
        replace: true,
        scope: {data: '=', initialOptions: '@', options: '='},
        link: function (scope, element, attrs) {
            var dataArrived = $q.defer();
            dataArrived.promise.then(function (graphData) {
                scope.graph = new Dygraph(element[0], graphData, $parse(scope.initialOptions)(scope.$parent));
                return graphData.length - 1;
            }).then(function(lastPoint) {
                scope.graph.setSelection(lastPoint);
                scope.$emit('dygraphCreated', element[0].id, scope.graph);
            });
            var removeInitialDataWatch = scope.$watch('data', function (newValue, oldValue, scope) {
                if ((newValue !== oldValue) && (newValue.length > 0)) {
                    dataArrived.resolve(newValue);
                    removeInitialDataWatch();
                    scope.$watch('data', function (newValue, oldValue, scope) {
                        if ((newValue !== oldValue) && (newValue.length > 0)) {
                            var selection = scope.graph.getSelection();
                            scope.graph.updateOptions({'file': newValue});
                            if ((selection >= 0) && (selection < newValue.length)) {
                                scope.graph.setSelection(selection);
                            }
                        }
                    }, true);
                    scope.$watch('options', function (newValue, oldValue, scope) {
                        if (newValue !== undefined) {
                            scope.graph.updateOptions(newValue);
                        }
                    }, true);
                }
            }, true);
        }
    };
});

然后在我的控制器中,我切换图形数据源如下:

$scope.setGraphDataSource = function (plotData, sourceData, scaleFactor) {
    $timeout(function () {
            $scope[plotData] = [];
            for (series in removeWatch) {
                removeWatch[series]();
            }
            removeWatch = [];
            var col = 0;
            for (series in sourceData) {
                removeWatch[series] = function (col) {
                    return $scope.$watch(function () {return $scope.logs[sourceData[col]].data.length},
                    function (newValue, oldValue, scope) {
                        updateCol(plotData, col, scope, scope.logs[sourceData[col]],
                                    sourceData.length + 1, scaleFactor[col]);
                    })}(col);
                col = col + 1;
            }
        }, 0);
}

$scope.showTemperatureGraph = function () {
    $scope.setGraphDataSource('graphData', ['OutsideTemperature', 'InsideTemperature'], [1, 1]);
    $scope.graphOptions = {labels: ['Time', 'Outside', 'Inside'],
        series: {'Inside': {axis: 'y'}, 'Outside': {axis: 'y'}},
        axes: {x: {valueFormatter: function (ms) {return $filter('date')(new Date(ms), 'dd/MM HH:mm')}},
               y: {valueFormatter: function (num) {return num.toFixed(1)}}
            },
        xlabel: 'Local Time', ylabel: 'Temperature (ºC)', stepPlot: false};
};

欢迎任何建议,评论甚至答案!

由于

1 个答案:

答案 0 :(得分:0)

系列可能无法正确匹配。更新图形时,g.getOption(“labels”)的现有值是多少?你提供一套新的标签吗?输入数据是什么格式的?是CSV吗?如果是这样,它有标题吗?