D3.js - 节点点击后无法设置节点标签?

时间:2015-03-18 10:54:32

标签: javascript html css d3.js

我通过采用http://jsbin.com/omokap/8/edit?html,css,js,output中的想法在D3.js中实现了一个简单的网络可视化应用。

此应用程序从html页面中的textarea读取节点名称(以换行符分隔),然后构建一个所有节点相互连接的网络。

我的所有代码都包含在此消息的末尾。

我的问题是我无法为节点设置标签 更具体地说,我在Web浏览器上加载D3jNetVis.html时收到以下错误消息。

Uncaught TypeError: D3jNetVis.js:64
undefined is not a function

当我尝试在以下代码段中为节点设置标签时会发生此错误:

dataSet.nodes.append("text")
    .attr("x", 12)
    .attr("dy", ".35em")
    .text(function(d) { return d.name; });

D3.js, force-graph, cannot display text/label of nodes中建议使用此类节点标签设置器。

为什么我会收到此错误以及如何修复错误?

谷歌暗示这可能与html页面中js文件的导入顺序有关,但一直在尝试各种组合而没有成功。

谢谢,
Erno Lindfors

D3jNetVis.html:

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8 />
        <title>Network Visualization Example - d3js</title>
        <link rel="stylesheet" type="text/css" href="D3jNetVis.css">
    </head>
    <body>
        <table>
            <tr><td><div id="svgContent"></div></td></tr>
            <tr><th align="left">Give node ids</th></tr>
            <tr><td><textarea id="nodeIds" cols=5 rows=20></textarea></td></tr>
            <tr><td><button type="button" onclick="constNet()">Construct Network</button></td></tr>
        </table>
        <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
        <script src="D3jNetVis.js" charset="utf-8"></script>
    </body>
</html>

D3jNetVis.js:

function constNet() {
    var textArea = document.getElementById("nodeIds");
    var nodeIdsArray = document.getElementById("nodeIds").value.split("\n");
    var w = 500,
    h = 500;
    var svg = d3.select("#svgContent")
        .append("svg")
        .attr("width", w)
        .attr("height", h)
        .attr('preserveAspectRatio', 'xMinYMin slice') 
        .append('g');

    var nodesArray = [];
    for (var i = 0; i < nodeIdsArray.length; i++) {
        var nodeId = nodeIdsArray[i];
        var newNode = {name: "Node" + nodeId, id:nodeId, fixed:false};
        nodesArray[nodesArray.length] = newNode;
    }
    var edgesArray = [];
    for (var i = 0; i < nodeIdsArray.length-1; i++) {
        var sNodeId = nodeIdsArray[i];
        for (var j = i+1; j < nodeIdsArray.length; j++) {
            var tNodeId = nodeIdsArray[j];
            edgesArray[edgesArray.length] = {source:sNodeId-1, target:tNodeId-1}; 
        }
    }
    var dataSet = {
        nodes: nodesArray,
        edges: edgesArray
    };
    var force = self.force = d3.layout.force()
        .nodes(dataSet.nodes)
        .links(dataSet.edges)
        .gravity(0.05)
        .distance(100)
        .charge(-100)
        .size([w,h])
        .start();

    var link = svg.selectAll(".link")
        .data(dataSet.edges)
        .enter().append("line")
        .attr("class", "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; });

    var node_drag = d3.behavior.drag()
        .on("dragstart", dragstart)
        .on("drag", dragmove)
        .on("dragend", dragend);

    var node = svg.selectAll("circle")
        .data(dataSet.nodes)
        .enter().append("circle")
        .attr("class", "node")
        .attr("r", 4.5)
        .call(node_drag);

    /*
    The "Uncaught TypeError" happens in the next line.
     */
    dataSet.nodes.append("text")
        .attr("x", 12)
        .attr("dy", ".35em")
        .text(function(d) { return d.name; });


    function dragstart(d, i) {
        force.stop(); // stops the force auto positioning before you start dragging
    }

    function dragmove(d, i) {
        d.px += d3.event.dx;
        d.py += d3.event.dy;
        d.x += d3.event.dx;
        d.y += d3.event.dy; 
        tick(); 
    }

    function dragend(d, i) {
        d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
        tick();
        force.resume();
    }  
    force.on("tick", tick);

    function tick() {
        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("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; });
    }
}

D3jNetVis.css:

line{
    stroke: #cccccc;
    stroke-width: 1;
}
circle{
  fill: blue;
}

1 个答案:

答案 0 :(得分:0)

您可以将html元素附加到选定的html元素(以便浏览器知道在DOM中添加的位置)。

dataSet.nodes不是html元素的选择,这就是您收到错误消息的原因。

改为: node.append( “文本”).....