2015-04-07 112 views
0

本週我開始學習Angular Js和D3 Js。下面的代碼可能是可悲的,但請耐心等待。如何將REST響應返回到角JS標籤來繪製D3 js餅圖

問題:我在嘗試使用返回json {「chatjson」:「[10,20,30]」}的REST服務。 我想使用從REST收到的[10,20,30]繪製餅圖。

代碼覆蓋:我正在使用ng控制器'validateCtrl'中的三個REST服務。兩個服務運行正常,並顯示所需的角度數據,但從第三個REST(請參閱函數'$ scope.getChartData')返回{「chatjson」:「[10,20,30]」},這是JSON,應該根據
圓角圖代碼中的響應顯示餅圖,這是我沒有得到的。 D3 Js代碼寫在底部。 D3代碼與硬編碼數據一起工作良好。

實際代碼

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
<html> 

<head> 
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> 
<script src="http://d3js.org/d3.v3.min.js"></script> 
</head> 



<body> 
<h2>Angular Example</h2> 

<form ng-app="myApp" ng-controller="validateCtrl" 
name="myForm" novalidate> 

<p>Username:<br> 
<input type="text" name="user" ng-model="user" required> 
<span style="color:red" ng-show="myForm.user.$dirty && myForm.user.$invalid"> 
<span ng-show="myForm.user.$error.required">Username is required.</span> 
</span> 
</p> 

<p>country:<br> 
<input type="text" name="country" ng-model="country" required> 
<span style="color:red" ng-show="myForm.country.$dirty && myForm.country.$invalid"> 
<span ng-show="myForm.country.$error.required">country is required.</span> 

</span> 
</p> 

<p> 
<input type="submit" value="save" ng-click="send()" 
ng-disabled="myForm.user.$dirty && myForm.user.$invalid || 
myForm.country.$dirty && myForm.country.$invalid"> 
</p> 

<ul> 
    <li ng-repeat="y in detail"> 
    {{ y.name + ', ' + y.country }} 
    </li> 
</ul> 

<input type="submit" value="Get Country List" ng-click="getData()"> 
<input type="submit" value="Get Pie Chart" ng-click="getChartData()"> 

<ul> 
    <li ng-repeat="x in names"> 
    {{ x.name + ', ' + x.country }} 
    </li> 
</ul> 

<div> 
<donut-chart data="chartData"></donut-chart> 
</div> 
</form> 

<script> 
var app = angular.module('myApp', []); 
app.controller('validateCtrl', function($scope,$http) { 



    $scope.chartData=[12,13,60]; // Hard coded for testing purpose 
    $scope.user = 'Anukul'; 
    $scope.country = 'India'; 
//=============== REST for fetching data from DB for Table details ============== 
    $scope.getData = function(){ 
    var getApi="http://localhost:9080/nextapp/person/getList"; 

    $http.get(getApi).success(function(response){$scope.names=response.records; 
    }); 
    }; 
//=============== REST for fetching data for drawing chart ============== 
    $scope.getChartData = function(){ 
    var getchartApi="http://localhost:9080/nextapp/person/getChart"; 

    $http.get(getchartApi).success(function(response){$scope.chartData=response; 
    }); 
    }; 
//=============== REST for inserting data in DB ============== 
    $scope.send = function(){ 
    var name = $scope.user; 
    var country = $scope.country; 
    var api="http://localhost:9080/nextapp/person/"+name+"/"+country; 
    $http.get(api) 
    .success(function(response) {$scope.detail = response.result;}); 
}; 
//========== End of REST ============================== 
}); 


//===================== new add for D3 Pie chart ============ 

    app.directive('donutChart',function(){ 
    function link(scope,el){ 
    //---- D3 code goes here 
    var data = scope.data; 
    var color = d3.scale.category10() 
    var el = el[0] 
    var width = 500 
    var height = 500 
    var min = Math.min(width,height) 


    var pie = d3.layout.pie().sort(null) 
    var arc = d3.svg.arc() 
       .outerRadius(125) 
       .innerRadius(75) 

    var group = d3.select(el).append('svg') 
     .attr({width:width,height:height}) 
     .append('g') 
      .attr('transform','translate('+width/2+','+height/2+')') 

    var arcs = group.selectAll(".arc") 
       .data(pie(data)) 
       .enter() 
       .append('g') 
       .attr("class","arc") 
    arcs.append("path") 
     .attr("d",arc) 
     .attr("fill",function(d){return color(d.data);}); 

    arcs.append("text") 
     .attr("transform",function(d){return "translate (" + arc.centroid(d)+")";}) 
     .text(function(d){return d.data;}); 



    //d3.select(el[0]).append('svg') 
    } 

    return{ 
    link: link, 
    restrict:'E', 
    scope:{data:'='} 
    } 
    } 
    ) 




</script> 

</body> 
</html> 
+0

[代碼形式](http://plnkr.co/edit/GBXJFozKqhZnK4Z46G2f?p=preview),對於任何感興趣的人。 –

+0

並[在這裏工作](http://plnkr.co/edit/Zm9F9eJZIp5KjRySJAO6?p=preview)。現在寫出答案。 –

回答

0

我認爲主要的問題是,指令只運行他們的鏈接功能一次。發佈在您的問題中的代碼將執行鏈接函數中的所有繪圖,該函數只能訪問初始硬編碼數據。

的解決方案,那麼,是繪圖代碼從表單中的鏈接功能,你可以從一個觀察者調用分離:

app.directive('donutChart',function(){ 
    function link(scope,element){ 
     scope.el = element[0]; // Cache a reference to the element 
     draw(scope.data, scope.el); // Initial draw 
    } 

    function draw(data, el) { 
     var color = d3.scale.category10(), 
      width = 500, 
      height = 500, 
      min = Math.min(width,height), 


      pie = d3.layout.pie().sort(null), 
      arc = d3.svg.arc() 
        .outerRadius(125) 
        .innerRadius(75); 

     d3.select("svg").remove(); // Clear old pie chart 

     var group = d3.select(el).append('svg') 
      .attr({width:width,height:height}) 
      .append('g') 
      .attr('transform','translate('+width/2+','+height/2+')'), 

      arcs = group.selectAll(".arc") 
      .data(pie(data)) 
      .enter() 
      .append('g') 
      .attr("class","arc"); 

     arcs.append("path") 
      .attr("d",arc) 
      .attr("fill",function(d){return color(d.data);}); 

     arcs.append("text") 
      .attr("transform",function(d){return "translate (" + arc.centroid(d)+")";}) 
      .text(function(d){return d.data;}); 
    } 

    return{ 
     link: link, 
     restrict:'E', 
     scope:{data:'='}, 
     // Add a controller here to $watch for data changes 
     controller: function($scope) { 
     $scope.$watch('data', function(newData) { 
      draw(newData, $scope.el); // Re-draw the chart 
     }); 
     } 
    }; 
    }); 

我注意到可能不是一個實際的問題,另一件事情,因爲它依賴在實際的服務器響應。當設置圖表數據,你這樣做:

$scope.chartData = response; 

然而,根據你的問題的文本,預期的反應是這樣的:

{ "chartjson": [10, 20, 30] } 

如果是這樣的話,你的測試圖表數據只是一個數組,如下所示:

$scope.chartData = [12, 13, 60]; 

然後我會希望得到這樣的迴應數組:

$scope.chartData = response.chartjson; 

你可以看到in this plunker,我嘲笑出$httpBackend從你的問題返回示例對象,這似乎工作。