Sometimes svg chart appear more small than normal. This problem is solved Reloading Screen.
//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
}
];
}
}
SVG element with the following html tags appears with wrong dimensions.
<g class="nvd3 nv-wrap nv-linePlusBar" transform="translate(35,10)">
This problem does not always happen, but when it happens is arranged refreshing the screen.
I think this patch is a bad idea and I would like to understand what is happening .
Thanks
I think your problem ultimately stems from your watch:
$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);
}
});
The problem I see is that you're using setTimeout
to call your sleep function a half second after the watch fires. As it is now, this will be fine if your $digest is still running in 500ms. setTimeout
is a vanilla JavaScript function, so calling it won't notify angularjs that there are any changes after the $digest has ended. Angular only triggers a $digest after 'user-initiated' events like ajax, clicks, entering data, etc. (read more here). If the $digest is running, you'll get lucky and angularjs will just happen to see those changes. You'll need to inform angular of your changes using $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();
}
});
There are a lot of ways to use $scope.$apply
, so be sure to check out the documentation. Also do a search on something like 'when to use $scope.$apply' and you'll find a lot of people for and against it. It does trigger another $digest loop, which can be costly if you have a lot of bindings or if you're at the end of the final digest loop and apply causes it to start over.
I don't think it's actually a good idea to be updating your model using setTimeout
from within a watch function. Does this not work without it? You may have some other async code that needs to be applied in the same fashion. Generally, you want $scope.$apply
to be as close to the non-angular asynchronous code as possible.