D3JS传入JSON对象会返回错误

时间:2013-06-03 09:53:00

标签: javascript json d3.js

这是我的代码:

d3.json('../../dev/json/ajson.php', function (error, json) {
  if (error) return console.warn(error);

  megavalues = ["Meetings", "Development", "Management"];
  megadata = [213, 891, 121];

  var categoryGraph = d3.select('#graph-container').append('svg')
      .attr('width', graphWidth)
      .attr('height', graphHeight)
      .data(megadata)
      .append('svg:g')
      .attr('transform', 'translate(' + graphWidth / 2.085 + ',' + graphHeight / 2.085 + ')');

  var arc = d3.svg.arc()
      .outerRadius(graphRadius - 10)
      .innerRadius(graphRadius - 130);

  var pie = d3.layout.pie()
      .value(function(d){ return d });

  var categoryDataGraph = categoryGraph.selectAll('g.slice')
      .data(pie(megadata))
      .enter().append('svg:g')
      .attr('class', 'slice');

  categoryDataGraph.append('svg:path')
      .attr('fill', function(d, i){ return color(i); })
      .attr('d', arc);

  categoryDataGraph.append('text')
      .attr('transform', function(d) { return 'translate(' + arc.centroid(d) + ')' })
      .attr('dy', '.35em')
      .attr('text-anchor', 'middle')
      .text(function(d, i) { return megavalues[i]; });

结果如下:

http://cloud.erikhellman.com/eQHJ/5TmsqKWu

这是我的问题:

我目前正在使用2个数组(megavalues& megadata)绘制图形,但我想要做的是使用这个json对象将它绘制到categoryGraph上:

json.projectData.timeDistribution

看起来像这样:

Object {Meetings: 12, Planning: 1, Development: 21} 

但是,当我将对象作为数据传递时,未绘制图形和/或返回此错误:

Uncaught TypeError: Object #<Object> has no method 'map'

我花了5个小时阅读文档并在Google上寻求帮助。这是我第一次使用D3.js,这远远超过了我认为的JavaScript知识。在我发现的所有示例中,已经传递了仅由数字组成的数组,或者如果包含文本,则JSON看起来不同。但我相信即使我的JSON对象看起来像这样,对吧?

这是我的第一个问题,如果我能以任何方式改善问题或改进任何方面,请告诉我。 :)

1 个答案:

答案 0 :(得分:1)

这里的“秘密酱”是你如何访问传入的值。你尝试过的两个结构之间的区别是一个是数组(并且有效),而另一个是对象(并没有)。这是因为D3不会迭代对象(如错误消息所示)。

解决此问题的最简单方法是使用d3.entries将对象转换为数组并相应地更改访问器函数。也就是说,您的代码看起来像

var pie = d3.layout.pie()
  .value(function(d) { return d.value; });

var categoryDataGraph = categoryGraph.selectAll('g.slice')
  .data(pie(d3.entries(json.projectData.timeDistribution))
  .enter().append('svg:g')
  .attr('class', 'slice');

然后您还需要更改文本的创建方式:

categoryDataGraph.append('text')
  .attr('transform', function(d) { return 'translate(' + arc.centroid(d) + ')' })
  .attr('dy', '.35em')
  .attr('text-anchor', 'middle')
  .text(function(d, i) { return d3.keys(json.projectData.timeDistribution)[i]; });