【问题标题】:Inserting nodes into D3 pack layout (pagination on zoom)将节点插入 D3 包布局(缩放时分页)
【发布时间】:2015-06-05 21:34:01
【问题描述】:

当 D3.js 包布局已经创建并显示在 SVG 元素中时,如何向它添加其他节点?重新计算整个 pack 是一种选择,但我希望插入更加无缝。

我正在寻找的是一个pack().addNode() 函数,它允许我将额外的子节点插入到现有的叶节点中。当用户放大到该叶节点时,叶节点应该变成父节点并将插入的节点显示为其子节点。

请看at my fiddle here。名为subnode_jane 的节点应该接收subnode_subnodes 中的子节点作为它的新子节点。

var subnode_subnodes = [{
    "name": "JanesDaughter",
    "size": 1030
}, {
    "name": "JanesSon",
    "size": 12000
}];

function zoom(d) {
    var focus0 = focus;
    focus = d;

    if (d.name === "subnode_jane") {
        alert("Oh I see subnode_jane has unpaginated children; insert them now!");
    }

/* ... */
}

可选:这样做时,如果原始节点的整体外观保持不变,那就太好了。谢谢!

相关:update a layout.pack in d3.js

【问题讨论】:

标签: d3.js insert nodes


【解决方案1】:

Please find my workaround solution here。 (解决方法,因为我无法编写 D3 包布局的扩展函数)

我的解决方案是创建第二个“虚拟”包并使用其圆坐标集成到原始包中。为我工作。

// hard-coded function
var virtualNodesByParentNode = function (d3NodeParentElement, nodeChildrenElementArray) {
    root.children[0].children[0].children = subnode_subnodes;
    // we need to do this because otherwise, the parent node object will be changed
    var d3NodeParentElementClone = clone(d3NodeParentElement);
    var pack = d3.layout.pack()
        .padding(2)
         // -1 is important to avoid edge overlap
        .size([d3NodeParentElementClone.r * 2 - 1, d3NodeParentElementClone.r * 2 - 1])
        .value(function (d) {
    return d.size;
        });
    d3NodeParentElementClone.children = nodeChildrenElementArray;
    var nodes = pack.nodes(d3NodeParentElementClone)
    // absolute x,y coordinates calculation
    var curChildnode;
    for (var i = 1; i < nodes.length; i++) {
        curChildnode = nodes[i];
        curChildnode.x = curChildnode.x - nodes[0].x + d3NodeParentElement.x;
        curChildnode.y = curChildnode.y - nodes[0].y + d3NodeParentElement.y;
        curChildnode.depth = d3NodeParentElement.depth + 1;
        curChildnode.parent = d3NodeParentElement;
    }
    nodes.splice(0, 1);
    return nodes;
};

zoom 函数中的 if 条件:

if (d.name === "subnode_jane" && done === 0) {
    done = 1;
    var virtualNodes = virtualNodesByParentNode(d, subnode_subnodes);
    d.children = virtualNodes;
    // http://stackoverflow.com/a/5081471/2381339
    nodes.push.apply(nodes, virtualNodes);
    circle = svg.selectAll("circle")
        .data(nodes)
        .enter().append("circle")
        .attr("class", function (d) {
        return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root";
    })
        .style("fill", function (d) {
        return "red";
    })
        .on("click", function (d) {
        if (focus !== d) zoom(d), d3.event.stopPropagation();
    });
    text.remove();
    text = svg.selectAll("text")
        .data(nodes)
        .enter().append("text")
        .attr("class", "label")
        .style("fill-opacity", function (d) {
        return d.parent === root ? 1 : 0;
    })
        .style("display", function (d) {
        return d.parent === root ? null : "none";
    })
        .text(function (d) {
        return d.name;
    });
    circle = svg.selectAll("circle");
    node = svg.selectAll("circle,text");
    // zoom to current focus again (do the transformation of the updated elements)
    zoomTo(view);
    return zoom(d);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-20
    • 2013-09-07
    • 2014-02-09
    • 2013-08-28
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多