如何将REST响应返回到角JS标签来绘制D3 js饼图

问题描述:

本周我开始学习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)。现在写出答案。 –

我认为主要的问题是,指令只运行他们的链接功能一次。发布在您的问题中的代码将执行链接函数中的所有绘图,该函数只能访问初始硬编码数据。

的解决方案,那么,是绘图代码从表单中的链接功能,你可以从一个观察者调用分离:

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从你的问题返回示例对象,这似乎工作。