2016-07-19 11 views
1

XHRレスポンスに応じてチャートやテーブルをホストする必要があるdivがあります。グラフの場合、chart.jsがグラフを表示するために使用するcanvas要素で置き換えるにはdivの内容が必要です。Angular-chart.jsで動的に作成されたキャンバスにチャートを作成

キャンバス要素をHTMLコードに追加すると、angular-chart.jsによってグラフがレンダリングされます。ただし、javascriptを使用してdivにキャンバスを挿入すると、canvas要素はdomにありますが、グラフは表示されません。

どうすれば対処できますか?

HTML

<div ng-controller="ChartCtrl"> 
    <div> 
    {{chart.name}} 
    This works (doughnut): 
    <canvas id="chart-{{$index}}" class="chart chart-doughnut" chart-data="chart.data" chart-labels="chart.labels"></canvas> 
    </div> 
    This Doesn't work ({{chart.type}}): 
    <div id="chartDiv"> </div> 
</div> 

Javascriptを

var myApp = angular.module('myApp', ['chart.js']); 

// Create the controller, the 'ToddlerCtrl' parameter 
// must match an ng-controller directive 
myApp.controller('ChartCtrl', function ($scope) { 
    var chart_div = $('#chartDiv'); 
    chart_div.empty(); 
    canvas_html = '<canvas id="chart-2" class="chart chart-doughnut" chart-data="chart.data" chart-labels="chart.labels"></canvas>'; 
    console.log(canvas_html) 
    chart_div.append(canvas_html); 
    //console.log(chart_div) 
    $scope.chart = { 
    name: 'Chart 1', 
    type: 'Doughnut', 
    labels: ['EVSC', 'ISB'], 
    data: [13, 44] 
    }; 
}); 

Plunker例:http://plnkr.co/edit/9JkANojIl8EXRj3hJNVH?p=preview

答えて

1

あなたはDOMの構造を変更している、あなたは、新しく作成されたを追加することはできません要素を "バニラ"や "jQuery"のように使用します。

あなたのHTML文字列またはDOM要素をテンプレートに入れてscopeにリンクされるテンプレート関数を生成する必要があります。プロセスはDOMツリーを歩き、DOM要素をdirectivesに合わせます。

// Instantiate the app, the 'myApp' parameter must match what is in ng-app 
var myApp = angular.module('myApp', ['chart.js']); 

// Create the controller, the 'ToddlerCtrl' parameter must match an ng-controller directive 
myApp.controller('ChartCtrl', function ($scope, $compile) { 
    canvas_html = '<canvas id="chart-2" class="chart chart-doughnut" chart-data="chart.data" chart-labels="chart.labels"></canvas>'; 

    var element = angular.element(canvas_html); 
    $compile(element)($scope); 
    angular.element('#chartDiv').append(element); 

    $scope.chart = { 
    name: 'Chart 1', 
    type: 'Doughnut', 
    labels: ['EVSC', 'ISB'], 
    data: [13, 44] 
    }; 
}); 

あなたはthis Plunker exampleで結果をチェックアウトすることができます。

+0

スーパー!私はこれを消化する必要があります。迅速な答えをありがとう! – Lmwangi

1

@ HiDeoの回答が上にありますが、ここでも同じことをする簡略化された指令です($compileに気づきます)。 scopeに添付されているchartData変数はChartjsのグラフのプリセットです。唯一の注意点は、updateプロパティに追加した$watchです。チャートを更新する予定がある場合は、何かすることをお勧めしますあなたの手をきれいに保つためだけのように。

.directive('replaceWithChart',function($compile){ 
    return { 
     restrict: 'A', 
     scope: { 
      chartData: '=replaceWithChart', 
      height: '=', 
      width: '=' 
     }, 
     compile: function(element){ 
      var canvasModel = angular.element('<canvas></canvas>'); 
      return { 
       post: function postLink(scope,elem,attr){ 
        elem.empty(); 
        var canvas = canvasModel.clone(); 
        elem.append($compile(canvas)(scope)); 

        !scope.height && (scope.height = elem[0].style.height || (elem[0].offsetHeight || elem[0].clientHeight)); 
        !scope.width && (scope.width = elem[0].style.width || (elem[0].offsetWidth || elem[0].clientWidth)); 

        var chart = new Chart(canvas[0].getContext('2d'),scope.chartData); 
        canvas.attr('height',(canvas[0].style.height = scope.height + 'px')); 
        canvas.attr('width',(canvas[0].style.width = scope.width + 'px')); 

        scope.$watch('chartData.update',function(){ 
         scope.chartData.update && !(scope.chartData.update = false) && chart.update(); 
        }); 
        elem.on('$destroy',chart.destroy.bind(chart)); 
        // Fixed some rendering issue, but I can't remember which 
        window.setTimeout(function(){ 
         var padding = elem[0].style.padding || (window.getComputedStyle(elem[0],null).getPropertyValue('padding')); 
         elem[0].style.padding = '0'; 
         elem[0].style.padding = padding; 
         chart.resize(); 
        },300); // Magic number - I found this worked best 
       } 
      }; 
     } 
    }; 
}) 
関連する問題