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

D3.js - Cannot set node labels after node click?

本文关键字:节点 设置 标签 js- 单击 D3      更新时间:2023-09-26

我采用了http://jsbin.com/omokap/8/edit?html,css,js,输出。

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

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

我的问题是无法为节点设置标签
更具体地说,在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中建议使用这种类型的节点标签设置器,力图无法显示节点的文本/标签。

你知道我为什么会出现这个错误以及如何修复它吗?

谷歌暗示这可能与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;
}

您只需将html元素附加到选定的html元素中(这样浏览器就知道在DOM中的哪个位置进行附加)。

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

改为写入:node.append("text")….