有时svg图表不适合容器,但它在屏幕刷新时有效

时间:2015-02-27 12:02:57

标签: angularjs d3.js nvd3.js angularjs-nvd3-directives

有时svg图表看起来比正常情况要小。重新加载屏幕解决了这个问题。

//Values Graphic
$scope.$watch(vm.dataGraphic.watch, function () {
    var data = vm.dataGraphic.watch ? $scope.$eval(vm.dataGraphic.watch) : vm.dataGraphic;

    setTimeout(sleep,500); //patch to "solve" this issue

    function sleep(){
        vm.dataValues = getDataValues(data);
    }

});
function getDataValues(data) {
    vm.dataGraphic = data || dataGraphicTest;
    if (vm.dataGraphic.values.length == 0) {
        return [];
    } else {
        vm.dataKeyValues = transformForKeyValues(vm.dataGraphic.values, vm.dataGraphic.accumulated);

        vm.barValues = transformBarValues(vm.dataGraphic.values, vm.dataGraphic.limit);
        var lineValues = transformLineValues(vm.barValues, vm.dataGraphic.limit, vm.dataGraphic.accumulated, vm.dataGraphic.startMonthlyLimit);
        vm.maxY = calculateMaxY(vm.barValues, lineValues);

        return [
            {
            "key": vm.dataGraphic.labelX.name,
            "bar": true,
            "color": _graphicsColors.bar,
            "values": vm.barValues
            },
            {
            "key": _graphicsValorPorDefecto,
            "color": _graphicsColors.line,
            "values": lineValues
            }
        ];
    }
}

带有以下html标记的SVG元素显示的尺寸错误。

<g class="nvd3 nv-wrap nv-linePlusBar" transform="translate(35,10)">

这个问题并不总是会发生,但是当它发生时会安排刷新屏幕。

我认为这个补丁是一个坏主意,我想了解发生了什么。

由于

1 个答案:

答案 0 :(得分:2)

我认为你的问题最终源于你的观察:

$scope.$watch(vm.dataGraphic.watch, function () {
    var data = vm.dataGraphic.watch ? $scope.$eval(vm.dataGraphic.watch) : vm.dataGraphic;

    setTimeout(sleep,500); //patch to "solve" this issue

    function sleep(){
        vm.dataValues = getDataValues(data);
    }

});

我看到的问题是,你会在手表开火后半秒钟使用setTimeout来调用你的睡眠功能。就像现在一样,如果您的$ digest仍然在500毫秒运行,这将没有问题。 setTimeout是一个vanilla JavaScript函数,因此调用它不会通知angularjs $ digest结束后有任何更改。 Angular仅在“用户启动”事件(如ajax,点击,输入数据等)后触发$摘要(read more here)。如果$ digest正在运行,你会很幸运,而angularjs恰好会看到这些变化。您需要使用$scope.$apply

通知角度更改
$scope.$watch(vm.dataGraphic.watch, function () {
    var data = vm.dataGraphic.watch ? $scope.$eval(vm.dataGraphic.watch) : vm.dataGraphic;

    setTimeout(sleep,500); //patch to "solve" this issue

    function sleep(){
        vm.dataValues = getDataValues(data);
        $scope.$apply();
    }

});

有很多方法可以使用$scope.$apply,所以请务必查看文档。还可以搜索“何时使用$ scope。$ apply”这样的内容,你会发现很多人反对它。它确实触发了另一个$ digest循环,如果你有很多绑定,或者如果你在最终的摘要循环结束并且应用导致它重新开始,这可能是昂贵的。

我认为从监视函数中使用setTimeout更新模型实际上并不是一个好主意。没有它,这不起作用吗?您可能需要以相同的方式应用其他一些异步代码。通常,您希望$scope.$apply尽可能接近非角度异步代码。