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

时间:2015-05-05 14:06:27

标签: javascript css d3.js hover

我正在使用可视化,其中网络中的某些节点上有一些饼图,它们具有不同的半径和基于某些参数的不同数量的切片。这是可视化在默认状态下的样子:

snapshot of the visualization

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

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

snapshot of hover effect on visualization

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

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

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属性:

.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中找出自己的出路。

1 个答案:

答案 0 :(得分:0)

使用path元素呈现饼图,这些元素不会受fill-opacity.node-inactive类的stroke-opacity影响。您还需要设置{{1}}以查看效果。