如何将鼠标悬停属性添加到 d3 中节点上绘制的饼图?

How to add mouse hover properties to pie drawn on a node in d3?

我正在处理一个可视化,其中网络中的一些节点上有饼图,根据某些参数具有不同的半径和不同数量的切片。这是默认状态下的可视化效果:

当我将鼠标悬停在选定的节点上时,只有它的连接突出,其余的逐渐消失(不透明度降低)。虽然这与节点完美配合,但我无法将相同的设置应用于我的饼图弧线。如何淡化其他节点饼图中的线条,同时保持当前活动节点上的线条不变?

此图显示了悬停效果和饼图的问题:

如您所见,饼图内的线条不会消失,而节点会消失。 这是我目前正在使用的代码片段。

在其中创建节点和饼图切片(基于一些内部选择标准):

var outer = d3.select("#forcedLayoutGraph")
        .append("svg:svg")
        .attr("width", w)
        .attr("height", h)
        .attr("pointer-events", "all");

    var vis = outer
        .append('svg:g')
        .call(zoom);

    vis.append('svg:rect')
        .attr('width', w)
        .attr('height', h)
        .attr('fill', 'white');

    var n = nodes.length;

    var link = vis.selectAll("line.link")
        .data(links).enter()
        .append("svg:line")
        .attr("class", "link").style("stroke-width", function(d) { return Math.sqrt(d.value); });

    var colorCategory = {"1": "black", "2": "blue", "3": "red"};            // 1=root 2=blog 3=org
    var shapeCategory = {"1": "diamond", "2": "cross", "3": "circle"};      // 1=root 2=blog 3=org
    var colorDirectChild = {"1": "black", "2": "#8E44AD", "3": "#F1C40F"};      // 1=root 2=direct child of root 3=not direct child

    var node = vis.selectAll(".node")
        .data(nodes)
        .enter().append("g")
        .attr("class", "node")
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; })
        .call(force.drag);

    node.append("text")
        .text("");

    node.append("circle")
        .attr("r",  10)
        .style("fill", function(d) { return colorDirectChild[d.isDirectChild]; });

var r = 6;
        var x = 2;
            //fill=d3.scale.category(20);

        var donut = d3.layout.pie();
        var arc = d3.svg.arc().innerRadius(0).outerRadius(function(d) {
                        if(this.parentNode.parentNode.__data__.category == 3)
                            if(this.parentNode.parentNode.__data__.parentcount < 10)
                                value = 10; //divide by a factor x, also remove (+r)
                            else
                                value = (this.parentNode.parentNode.__data__.parentcount)/x + r;
                        else
                            value = 0;
                        return value;
                  });

        var arcs = node.selectAll("g.arc")
                       .data(function(d, i) {
                            var c=0; var groups = [];
                            for(c=0; c<d.parentcount; c++) {
                                groups.push(1.0/d.parentcount);
                            }
                            return donut(groups);
                        })
                        .enter().append("svg:g") 
                        .attr("class", "arc");

        arcs.append("svg:path")
            .attr("fill", "#F1C40F")
            .attr("stroke", "black")
            .attr("stroke-width", "1.25px")
            .attr("d", arc);

下面是控制节点悬停效果的代码:

node.on("mouseover", function(d){
       node.classed("node-active", function(o) {
            thisOpacity = isConnected(d, o) ? true : false;
            this.setAttribute('fill-opacity', thisOpacity);
            return thisOpacity;
        });

        node.classed("node-inactive", function(o) {
            thisOpacity = isConnected(d, o) ? false : true;
            this.setAttribute('fill-opacity', thisOpacity);
            return thisOpacity;
        });

        link.classed("link-active", function(o) {
            return o.source === d || o.target === d ? true : false;
        });



        var nodeText, nodeParentCnt; 
        d3.select(this).classed("node-inactive", false);
        d3.select(this).classed("node-active", true);

        d3.select("g.arc").attr("stroke-width","0.25px");
        d3.select(this).select("g.arc").attr("stroke-wdith","1.25px");

        d3.select(this).select("circle").transition()
            .duration(500)
            .attr("r", 20);
        d3.select(this).select("text")
            .attr("dx", 12)
            .attr("dy", ".35em")
            .text(function(d) { nodeText = d.label; nodeParentCnt = d.parentcount; return d.label; });
        d3.select("#nodeLabel").text(nodeText)
        d3.select(this).select("circle")
            .on("click", function(d){
                var win = window.open(d.label, '_blank');
                win.focus();
            });
        //console.log(nodeText);
        document.getElementById('nodeLabel').innerHTML = "URL: "+nodeText + "<br />" + "No. of Linking URLs: " + nodeParentCnt;
    })

    .on("mouseout", function(d){
        node.classed("node-active", false);
        link.classed("link-active", false); 
        node.classed("node-inactive", false);   

        d3.select(this).select("circle").transition()
            .duration(500)
            .attr("r", 10);
        d3.select(this).select("text")
            .text("");
        document.getElementById('nodeLabel').innerHTML = "Hover on a node!";
    });

这些是与节点关联的 CSS 属性和 link 类:

.node {
  stroke: #fff;
  stroke-width: 0.2px;
  fill-opacity: 1;
}

.node-active{
  stroke: #555;
  stroke-width: 1.5px;
  fill-opacity: 1;
}

.node-inactive{
  fill-opacity: 0.2;
}

.link {
  stroke: #fff;
  stroke-width: 0.5px;
  stroke-opacity: 0.2;
}

.link-active {
  stroke: #555;
  stroke-width: 2px;
  stroke-opacity: 1;
}

我希望此代码示例有助于了解我正在使用的内容。我怎样才能对馅饼应用类似的效果?它是否必须是鼠标事件的单独代码块,还是在节点代码中?我还在寻找 D3 的出路。

饼图使用 path 元素呈现,这些元素不受您为 .node-inactive class 设置的 fill-opacity 的影响。还需要设置stroke-opacity才能看到效果