将数据从Angular AJAX调用加载到D3图

将数据从Angular AJAX调用加载到D3图

问题描述:

我在从外部API将JSON数据加载到D3图中时遇到了一些问题。我使用Quandl的API在一段时间内加载布伦特原油价格,这是我试图绘制的数据。我在我的项目中使用了Angular,所以我有一个服务设置为进行AJAX调用,然后将其提供给范围。只要我不尝试涉及我的D3代码,我就可以成功地做到这一点。将数据从Angular AJAX调用加载到D3图

当我这样做,我得到几个错误:

GET http://localhost:3000/[object%20Object] 404 (Not Found)

这:

Uncaught TypeError: Cannot read property 'forEach' of undefined

绑定在一些错误在我的D3-代码,我不能很好地理解。

下面是完整的代码产生错误:

app.service('oilService', function($http) { 
    delete $http.defaults.headers.common['X-Requested-With']; 
    this.getData = function() { 
    var URL = "https://www.quandl.com/api/v1/datasets/CHRIS/ICE_B1.json"; 
    return $http({ 
    method: 'GET', 
    url: URL 
    }) 
}}) 

.directive('oilGraph', function() { 
    return { 
    scope: {}, 
    controller: function(oilService) { 
    var width = 200; 
    var height = 100; 

    var parseTime = d3.timeParse("%y-%m-%d"); 

    var x = d3.scaleTime().range([0, width]); 
    var y = d3.scaleLinear().range([height, 0]); 

    var valueline = d3.line() 
     .x(function(d) { return x(d.date); }) 
     .y(function(d) { return y(d.settle); }); 
    var svg = d3.select("#oilgraph").append("svg") 
     .attr("width", width) 
     .attr("height", height); 

    oilService.getData() 
    .then(function(data) { 
    d3.json(data, function(error, data) { 
     if (error) { 
     console.log(error); 
     } 

     data.forEach(function(d) { 
     d.date = parseTime(d[0]); 
     d.settle = d[4]; 
     }) 

     x.domain(d3.extent(data, function(d) { return d.date; })); 
     y.domain([0, d3.max(data, function(d) { return d.settle; })]); 

     svg.append("path") 
      .data([data]) 
      .attr("class", "line") 
      .attr("d", valueline); 

     svg.append("g") 
      .attr("transform", "translate(0," + height + ")") 
      .call(d3.axisBottom(x)); 

     svg.append("g") 
      .call(d3.axisLeft(y)); 
    }) 
    }) 
    } 
} 
}) 

(请不要介意花括号,乱)

+1

第二个错误是因为'data'在'data.forEach(函数(d){... '未定义 - 由于第一个错误,你可以通过在console.log中记录'oilService.getData()'的结果:'.then(function(data){console.log(“data:”,data )''你还可以发布'console.log(error);'的结果吗?(我猜这是第一个错误,但以防万一) – mkaran

+1

$ http最可能[反序列化](https:// docs .angularjs.org/api/ng/service/$ http#default-transformations)JSON数据(这将是t他默认),所以d3.json已经获得一个对象,而不是一个字符串 – ccprog

+1

@ ccprog这绝对是一个问题,但我不明白在这一点上是为什么本地主机部分在第一个错误:http:// localhost:3000/[object%20Object]'。我的意思是这不是在代码中的任何地方构建的,'d3.json'从'oilService.getData()'输入'data'作为输入,所以必须有些腥意。 – mkaran

角$ HTTP媒体链接反序列化数据。要么不要调用d3.json,要么让它处理请求,不要调用$ http。

https://www.quandl.com/api/v1/datasets/CHRIS/ICE_B1.json收到的数据遵循另一种格式,而不是您期望的格式。他们是这样的:

{ 
    //... 
    "column_names": [ "Date","Open","High","Low","Settle","Change","Wave","Volume","Prev. Day Open Interest","EFP Volume","EFS Volume","Block Volume" ], 
    "data": [ 
    ["2017-06-28",46.25,47.47,46.25,47.31,0.66,46.85,158984.0,149270.0,2218.0,null,1379.0], 
    //... 
} 

为了得到你想要的东西,你需要引用

oilService.getData() 
    .then(function(response) { 
    var mapped_data = response.data.data.map(function(d) { 
     return { 
      date: parseTime(d[0]), 
      settle: d[4] 
     }; 
    }) 

    //... 

    svg.append("path") 
     .data([mapped_data]) 
     //etc. 
    }) 
+0

'data.data.map不是函数' – SudokuNinja

+0

我可以引用数据就好了,如果我像这样写'data.data.data.forEach(function(d){....})' 这也适用于:'data.data.data.map' 现在我唯一的问题是图不是显示除垂直y轴线之外的任何内容。 – SudokuNinja

+0

ah - Angular $ http也会将JSON对象封装在'.data'属性中。为了避免命名过于愚蠢,可能应该将callback参数称为'response',就像Angular doc一样。 – ccprog