如何将D3节点标签文本读入div / paragraph元素?

时间:2015-04-21 13:34:51

标签: javascript d3.js

我在D3中使用标记为图形布局的力,我的项目要求之一是与每个节点关联的文本应显示在div / p元素中,该元素占据网页上的固定位置而不是显示直接与相关节点相邻(当前它在鼠标悬停时激活)。因此,每当用户在任何节点上盘旋时,相应的文本都应显示在div标签中,而不是显示在图表中的节点旁边。

以下代码段显示了我目前如何处理节点和标签:

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("");

force.on("tick", function() {
        nodes[0].x = w / 2;
        nodes[0].y = h / 2;

        link.attr("x1", function(d) { return d.source.x; })
            .attr("y1", function(d) { return d.source.y; })
            .attr("x2", function(d) { return d.target.x; })
            .attr("y2", function(d) { return d.target.y; });

        node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

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

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

        d3.select(this).classed("node-active", true);
        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) { return d.label; });
        d3.select(this).select("circle")
            .on("click", function(d){
                var win = window.open(d.label, '_blank');
                win.focus();
            });
    })

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

        d3.select(this).select("circle").transition()
            .duration(750)
            .attr("r", 10);
        d3.select(this).select("text")
            .text("");
    });

我有一个id ='nodeLabel'的div标签,用于打印节点的标签。我希望附加的代码有所帮助。我尝试使用document.getElementById('nodeLabel')设置它的值,但我不确定这是正确的方法还是这行代码会去哪里?

如何达到预期效果?

3 个答案:

答案 0 :(得分:1)

在鼠标悬停处理程序中,只需添加如下内容:

$("#nodeLabel").text(d.label);

以您的代码为基础,这将导致:

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

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

    d3.select(this).classed("node-active", true);
    d3.select(this).select("circle").transition()
        .duration(500)
        .attr("r", 20);
    d3.select(this).select("circle")
        .on("click", function(d){
            var win = window.open(d.label, '_blank');
            win.focus();
        });

    $("#nodeLabel").text(d.label);
})

答案 1 :(得分:0)

我可能会通过

来解决这个问题
  1. 在开始时,当您创建节点时,您调用.each()并向其传递一个函数,该函数将每个节点的成员变量设置为您要显示的值。
  2. onClick处理程序中,您可以通过d3.select(this)获取发生事件的元素,因此我将从中获取您在步骤1中存储的值并设置div'相应的文字。这将是d3.select("#nodeLabel").text(nodeText)

答案 2 :(得分:0)

好的,我找到了办法。

我将d.label的值存储到变量中,然后简单地设置' p'的内部HTML。 mouseOver句柄中的标记。

这是更新的代码段:

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

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

        var nodeText; 
        d3.select(this).classed("node-active", true);
        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; 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 = "Node selected: "+nodeText;
    })

如果有更简单/更好的解决方案,我肯定还是希望听到它并学习!