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对象看起来像这样,对吧?
这是我的第一个问题,如果我能以任何方式改善问题或改进任何方面,请告诉我。 :)
答案 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]; });