我正在运行Django 1.5.1和Python 2.7,以及D3.js v3。
我创建了一个GUI,用户可以在D3.js可折叠缩进树中动态添加/删除节点(如此block,但有添加/删除按钮)。这一切在浏览器端都可以正常工作。
但是,我现在想通过Django / Python将用户的更改保存到我的数据库中。是否可以从d3“导出”我的数据并将其传递给Django视图?从documentation开始,似乎没有,或者至少我没有看到任何命令。我曾尝试使用Ajax进行简单的POST,但问题是d3.selectAll返回对象......这些对象稍微递归并导致浏览器的堆栈溢出。示例代码在这里:
var nodes = d3.selectAll('g.node');
var root_node = nodes[0][0].__data__;
var children = root_node.children;
$.ajax({
type: "POST",
url: "update_map/",
data: {
'children': children,
'bank': obj_bank_id
},
success: function( result ) {
if (result == true) {
lscache.set( 'canvas_clean', 'true' );
} else {
alert( 'Error in saving data' );
}
},
error: function( xhr, status, error ){
alert( error );
}
});
我看到的问题(使用Chrome的开发人员工具)是'children'本质上是无限长的 - 它是一个对象数组,但在每个对象中都是一个包含其所有子对象的“父”对象等。 ad inifinitum。下面是一个块:
Object {source: "", item_class: "root", name: "Topics", children: Array[76], x0: 0…}
children: Array[76]
0: Object
_children: Array[0]
bank: "objectivebank"
children: null
depth: 1
id: 2
item_class: "objective"
item_id: "objective"
name: "Antiderivative"
parent: Object
children: Array[76]
depth: 0
那么有没有办法使用内置的d3.js命令或其他方式获得没有d3元数据的所有节点的“平面”视图?我想要更干净的东西,但我只需要将东西保存在一个单独的对象中吗?谢谢!
答案 0 :(得分:1)
所以我在看到Scott Cameron与另一篇文章的链接之前解决了这个问题 - 使用过滤器的JSON.stringify似乎肯定会起作用并且具有与我所做的相同的功能。基本上我创建了d3.selectAll('g.node')的副本并按照metamit和Scott Cameron的建议手动完成了它。然后我删除了对父母的所有引用以及我不想要的其他d3.js元数据。然后我复制了根节点和中提琴 - 我的序列化树。
var nodes = $.extend(true, [], d3.selectAll('g.node'));
// Only need the 'root' nodes at depth 0, because it has all the children
// associated with it. Just strip out the unneeded metadata...
var remove_d3_metadata = function(node_data) {
// remove the d3 metadata
delete node_data.parent;
delete node_data.x;
delete node_data.x0;
delete node_data.y;
delete node_data.y0;
delete node_data.__proto__;
var grandchildren = node_data.children;
if (grandchildren != null) {
$.each( grandchildren, function(index, grandchild) {
remove_d3_metadata(grandchild);
});
}
};
nodes.each( function() {
var node_data = d3.select(this).datum();
if (node_data.depth == 0) {
var children = node_data.children;
if (children != null) {
$.each(children, function(index, child) {
remove_d3_metadata(child);
});
}
}
});
var root_node = nodes[0][0].__data__;