D3.js“导出”数据

时间:2013-08-05 18:07:37

标签: javascript django d3.js

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

1 个答案:

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