我正在从谷歌电子表格加载数据,其中包含1955年至2012年所选国家/地区的国内生产总值。从此我想绘制一个树形图。到目前为止一切都很好。
我已经通过内部链接加载数据并格式化为d3可以处理的对象,然后在屏幕上绘制布局 - 一切都很好。我的基础是http://bl.ocks.org/mbostock/4063582的Mike Bostock教程。
当我尝试从1955年到2010年的一组数据转换时出现问题。我确信我用来生成树形图布局的函数正在工作,因为初始显示是正确的。我传递了一个日期,它创建了树形图结构。
然而,当我触发更改时,似乎会发生转换,并且各个方块会改变大小。但是当我检查它们时,我意识到它们都是错的,我似乎已将新的价值集映射到错误的国家。
新闻结构看起来视觉上正确,但所有名称都是错误的。所以我得到了塞浦路斯在2012年拥有最大GDP的东西。就好像我有一个按字母顺序排列的列表,它有一个数量级的另一组值,而不是说美国的新值被映射到旧的价值。
在这里四处走动,因为我仍然对d3很新,所以所有的帮助都感激不尽。
代码如下所示:
/*global app:true JST:true d3:true*/
(function (window, $) {
'use strict';
var menuItems = [];
var menuType='measure';
var checboxItems= ['advanced','emerging'];
var ddID = '0';
var model=[];
var yearValue="2012"
var group="gdp";
var treeStruc={
name:[],
children:[]
}
var margin = {top: 25, right: 5, bottom: 5, left: 5},
width = 965 - margin.left - margin.right,
height = 650 - margin.top - margin.bottom;
var color = d3.scale.category10();
app.spreadsheet.get(function (data) {
// TODO: process the data
menuItems = data.measures
//console.log(data);
//console.log('menuItems', menuItems);
//crete dropdown and use toggle to swich display on and off
$('#dropDown').click(function () {
$('ul.ddMenuList').toggle();
});
//populate the dropdown menu
for (var k = 0; k <menuItems.length; k++) {
$('#ddList').append('<li id="dd_' + k + '"><a href="#">'+menuItems[k].menulist +'</li>');
};
//add functionality to dropDown menu
$('#ddList li').bind('click', function () {
ddID = this.id.split('_')[1];
var text = $(this).text();
//console.log ("ID=",ddID);
//console.log (text, "Measure=",menuItems[ddID].type);
$('#ddTitle').empty();
$('#ddTitle').append(text);
createCheckboxes()
});
function createCheckboxes() {
//decide which check boxes to populate
if (menuItems[ddID].type==="measure") {
group=menuItems[ddID].type
checboxItems=[];
$.each(menuItems, function (i) {
if (menuItems[i].type==="group"){
checboxItems.push (menuItems[i].checkbox);
}
//console.log (checboxItems);
});
}
else {
group=menuItems[ddID].type
checboxItems=[];
$.each(menuItems, function (i) {
if (menuItems[i].type==="measure"){
checboxItems.push (menuItems[i].checkbox);
}
//console.log (checboxItems);
});
}
//Populate the check boxes
console.log ("Populating check boxes");
$('#cbHolder').empty();
$('#cbHolder').append('<form>');
$.each(checboxItems, function (i) {
$('#cbHolder').append('<input type="checkbox" id="cb_'+i+'">'+checboxItems[i]);
$('#cbHolder').append('</form>');
//console.log ("checkboxItems",checboxItems[i]);
});
changed3 ()
}
//creates an object containing just the advanced countries
treeStruc={name:[],children:[]};
console.log ("group=",group);
$.each(checboxItems, function (k) {
console.log("Parent",checboxItems[k])
model=jQuery.grep(data.stats,function(e,i){return e[checboxItems[k]];});
console.log('model', model);
treeStruc.children.push({"name":checboxItems[k],"children":[]});
//Construct the children of 1 big group to be completed to be updated for each sheet
$.each(model, function (i) {
treeStruc.children[k].children.push({'name':model[i].countryname,'size':model[i] [group]});
});
});
console.log('treeStruc', treeStruc)
Handlebars.createOptionsHelper(data.options);
drawd3 ();
});
function generateTreemapLayout(filter){
return d3.layout.treemap()
.size([width, height])
.sticky(true)
.value(function(d) {
if(d.size[filter] < 0){
return 0;
}
return d.size[filter];
});
}
function drawd3() {
console.log ("function drawd3");
var treemap = generateTreemapLayout('y'+yearValue)
var div = d3.select("#d3Object").append("div")
.style("position", "relative")
.style("width", (width + margin.left + margin.right) + "px")
.style("height", (height + margin.top + margin.bottom) + "px")
.style("left", margin.left + "px")
.style("top", margin.top + "px");
var node = div.datum(treeStruc).selectAll(".node")
.data(treemap.nodes)
.enter().append("div")
.attr("class", "node")
.call(position)
.attr("id",function(d){
return d.name;
})
.style("background", function(d) { return d.children ? color(d.name) : null; })
.text(function(d) { return d.children ? null : d.name; });
};
function position() {
this.style("left", function(d) { return d.x + "px"; })
.style("top", function(d) { return d.y + "px"; })
.style("width", function(d) { return Math.max(0, d.dx - 1) + "px"; })
.style("height", function(d) { return Math.max(0, d.dy - 1) + "px"; });
}
function changed3() {
console.log ("function changed3");
//make a new treemap layout
var treemap = generateTreemapLayout('y'+1955);
console.log('treeStruc',treeStruc);
//redraw the treemap using transition instead of enter
var node = d3.select("#d3Object")
.datum(treeStruc).selectAll(".node")
.data(treemap.nodes)
.transition()
.duration(1500)
.call(position)
}
}(this, jQuery));
答案 0 :(得分:2)
非常感谢我的工作同事Tom Pearson。问题在于数据绑定到页面上的项目的位置。当您重新绘制树形图时,因为数据未使用像对象名称这样的标识符绑定到div,它会将数据映射到列表中的第一个项目。这意味着像中国这样的东西可以获得比利时的信息。简单的解决方案如下而不是
.data(treemap.nodes)
使用
.data(treemap.nodes,function(d){
return d.name;
})
这是原始drawd3函数中的两个实例,它们在changed3函数中。希望能帮助任何人坚持使用类似的东西