score:2

Accepted answer

as @martin pointed it out, it is an issue of chart.js not showing the chart when initiliazed in a hidden dom element (its height and width remain at 0px even after showing the hidden element).

this issue is tracked here.

i share you my home made solution if you are blocked by components like tabs initialized hidden. i have created a directive in which i compile the canvas element. in order to be able to refresh the element when needed (eg when the tab is opened), i watch an attribute i will manually change on tab change in my controller.

here is my directive :

app.directive('graphcanvasrefresh', ['$compile', function($compile) {
function link(scope, elem, attrs) {

    function refreshdom() {
        var markup = '<canvas class="chart chart-pie" id="graph" data="entitygraph.data" labels="entitygraph.labels" legend="true" colours="graphcolours" ></canvas>';
        var el = angular.element(markup);
        compiled = $compile(el);
        elem.html('');
        elem.append(el);
        compiled(scope);
    };

    // refresh the dom when the attribute value is changed
    scope.$watch(attrs.graphcanvasrefresh, function(value) {
        refreshdom();
    });

    // clean the dom on destroy
    scope.$on('$destroy', function() {
        elem.html('');
    });
};

return  {
    link: link
};
}]);

dirty as hell, but this is a working solution you can use waiting for chart.js update. hope it can help someone.

score:0

added some functionally to @bviale answer.

app.directive('graphcanvasrefresh', function ($compile, $timeout) {
    return {
        scope:{
            labels: "=",
            data: "=",
            type: "=",
            refresh: "="
        },
        link: function (scope, elem, attrs) {

            function refreshdom() {
                var markup = '<canvas class="chart chart-' + scope.type + '" id="' + scope.type + scope.$id + '" chart-labels="' + scope.labels + '" ' +
                                                'chart-legend="false"  chart-data="' + scope.data +'" ></canvas>';
                var newel = $compile(markup)(scope.$parent.$new());
                elem.html(newel);
                scope.refresh = false;
            };

            // refresh the dom when the attribute value is changed
            scope.$watch('refresh', function (value) {
                $timeout(
                refreshdom(), 100);
            });

            // clean the dom on destroy
            scope.$on('$destroy', function () {
                elem.html('');
            });
        }
    };

});

Related Query

More Query from same tag