Javascript D3.js“;“出口”;数据

Javascript D3.js“;“出口”;数据,javascript,django,d3.js,Javascript,Django,D3.js,我正在运行Django 1.5.1和Python 2.7,以及D3.js v3 我创建了一个GUI,用户可以在其中动态添加/删除D3.js可折叠缩进树中的节点(如下所示,但带有添加/删除按钮)。这一切都可以在浏览器端正常工作 但是,我现在希望通过Django/Python将用户的更改保存到我的数据库中。是否可以从d3“导出”我的数据并将其传递给Django视图?从屏幕上看,似乎没有,或者至少我没有看到任何命令。我试着用Ajax写一篇简单的博文,但问题是d3.selectAll返回对象……这些对象

我正在运行Django 1.5.1和Python 2.7,以及D3.js v3

我创建了一个GUI,用户可以在其中动态添加/删除D3.js可折叠缩进树中的节点(如下所示,但带有添加/删除按钮)。这一切都可以在浏览器端正常工作

但是,我现在希望通过Django/Python将用户的更改保存到我的数据库中。是否可以从d3“导出”我的数据并将其传递给Django视图?从屏幕上看,似乎没有,或者至少我没有看到任何命令。我试着用Ajax写一篇简单的博文,但问题是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的开发工具)是“子对象”本质上是无限长的——它是一个对象数组,但每个对象中都有一个“父”对象,包括它的所有子对象,等等。下面是一个区块:

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元数据的节点的“平面”视图?我想要更干净的东西,但我是否只需要将东西保存在一个单独的对象中?谢谢

因此,在看到Scott Cameron链接到另一篇文章之前,我解决了这个问题。带过滤器的stringify似乎肯定会工作,并具有与我相同的功能。基本上,我创建了一个d3.selectAll('g.node')的副本,并按照meetamit和Scott Cameron的建议手动遍历了它。然后我删除了所有对parent的引用,以及我不想要的其他d3.js元数据。然后,我复制了根节点和viola——我的序列化树

        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__;

在我看来,您必须“手动”构造对象,方法是初始化一个空白对象,然后在构建必要的树时在子对象(及其子对象)上循环。不过应该没那么难。如果您还没有了解d3方法,那么需要注意的是
。选择的每个
方法,这可能是您希望用来循环子对象并收集其数据或html字符串的方法。此外,这可能很方便:在
的处理程序中,每个
循环都可以调用
d3.select(this).datum()
来获取与给定子元素关联的数据。您要处理多少个节点?您似乎不太可能使用浏览器可能看到的大量节点使调用堆栈溢出。我想知道你是否在某处有一个循环引用?@ScottCameron,所以只有77个节点(root+76个子节点)。但您可以从我的对象片段中看到,父对象(及其子对象)嵌入到每个子对象中。这种情况会无限延续下去——在Firebug或Chrome中,我可以继续深入挖掘,层次永远不会结束。每个子对象(底部第二行)也有一个包含76个子对象的父对象,每个子对象都有一个包含76个子对象的父对象,等等。这似乎是d3.js数据节点的固有特性?@meetamit,谢谢你的提示,这将引导我走向正确的方向!你是对的——这其实很简单……树已经在根节点中构建好了,我只需要循环遍历并从每个子节点中删除“parent”属性来删除递归性。请注意,这个属性是由d3.js自动添加的,不是我添加的。哦,我现在明白了。通过jQuery.ajax序列化对象是有问题的,因为它遍历整个对象。我不确定jQuery在内部使用什么进行序列化。通过将“dataType”设置为“json”,您可能会取得一些进展。但更可能的是,您需要序列化自己。可以使用JSON.stringify将对象转换为字符串。stringify使用第二个参数来指定当它碰到它已经看到的对象时会发生什么。这里有一个相关的SO问题,有更多细节:。