3

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

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

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

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

4

1 回答 1

2

所以我在看到 Scott Cameron 的链接到另一个帖子之前解决了这个问题——带有过滤器的 JSON.stringify 似乎它肯定会工作并且具有与我所做的相同的功能。基本上,我创建了 d3.selectAll('g.node') 的副本并手动浏览它,正如 meetamit 和 Scott Cameron 所建议的那样。然后我删除了所有对 parent 的引用以及我不想要的其他 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__;
于 2013-08-07T00:54:47.440 回答