gpt4 book ai didi

javascript - d3.js 中的过渡 TreeMap

转载 作者:行者123 更新时间:2023-11-29 22:09:36 25 4
gpt4 key购买 nike

我正在从包含 1955 年到 2012 年选定国家/地区的 GDP 的谷歌电子表格加载数据。我想从中绘制一个树状图。到目前为止一切顺利。

我已经通过内部链接加载数据并将其格式化为 d3 可以处理的对象,然后在屏幕上绘制布局 - 一切都很好。我以 Mike Bostock 教程为基础,网址为 http://bl.ocks.org/mbostock/4063582。 .

当我尝试从 1955 年到 2010 年的一组数据转换时,问题就来了。我确信我用来生成树状图布局的函数正在运行,因为初始显示是正确的。我将一个日期传递给它,它会创建 TreeMap 结构。

但是,当我触发更改时,似乎会发生转换,并且各个方 block 的大小也会发生变化。但是当我检查它们时,我意识到它们都是错误的,而且我似乎将新的值(value)集映射到了错误的国家。

新结构看起来是正确的,但所有的名字都是错误的。所以我得到了像塞浦路斯这样的东西,它在 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));

最佳答案

非常感谢我的同事 Tom Pearson。问题在于数据绑定(bind)到页面上的项目的位置。当您重新绘制树形图时,因为数据未绑定(bind)到具有唯一标识符(如对象名称)的 div,它会将数据重新映射到列表的第一项。这意味着像中国这样的东西得到了比利时的信息。简单的解决方案如下代替

.data(treemap.nodes)

使用

 .data(treemap.nodes,function(d){
return d.name;
})

原始 drawd3 函数中有两个 this 实例,它们在 changed3 函数中。希望能帮助任何遇到类似问题的人

关于javascript - d3.js 中的过渡 TreeMap ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18760437/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com