如何将带有上下文菜单的展开所有按钮添加到 d3.js 树

how to add expand all button with contextmenu to d3.js tree

var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function (d) {
    return "translate(" + source.x0 + "," + source.y0 + ")";
 })
.on("click", click).on("contextmenu", function (data, index) {          
      d3.event.preventDefault();
       // add context menu...
     });;

你可以在上面看到我的代码。我是 d3.js 的新手,我找不到如何在上下文菜单上添加“全部展开”按钮的方法。谢谢你的帮助.. P.S:我不能使用 Jquery。

使用 D3 实现上下文菜单相当容易。首先创建一个显示自定义菜单的全局变量var contextDiv;。然后将点击事件绑定到您的 svg 元素:

d3.select("svg").on("contextmenu", clickFunction);

并实现功能。

function clickFunction() {
    event.preventDefault();

    contextDiv = d3.select("body").append("div")
        .style("position", "absolute")
        .style("top", event.pageY + 1 + "px")
        .style("left", event.pageX + 1 + "px");
    var contextTable = contextDiv.append("table")
        .style("border", "solid 1px");

    contextTable.append("tr")
        .append("td").text("Expand All").attr("id", "citem1");
    contextTable.append("tr")
        .append("td").text("Item2").attr("id", "citem2");
    contextTable.append("tr")
        .append("td").text("Item3").attr("id", "citem3");
    contextTable.on("click", tableClick);
}

现在实现tableClick功能。

function tableClick(){
    var target = d3.event.target.id;
    contextDiv.remove();

    if (target == "citem1")
        expand(root);
}

最后是 expandAll 函数。请注意,root 变量必须定义为树的根。这是假设您的树基于 This 示例。

function expand(d) {
    if (d._children) {
        d.children = d._children;
        d.children.forEach(expand);
        d._children = null;
    } else if (d.children) {
        d.children.forEach(expand);
    }
}

如果您希望上下文菜单的行为与内置菜单完全一样,您还需要做很多事情,但这应该足以让您入门。此外,here 是一个内置此行为的 Fiddle。