简体   繁体   中英

D3 Force Layout with text Label And Icon

Can somebody familiar with d3js.org. I am having problem showing a text label on the circles. If anyone has the experience of successfully implementing them I am willing to take a look at the solution.

Here's my code below:

<!DOCTYPE html>
<meta charset="utf-8"><style>
@import url(../style.css);


.link {
stroke: #000;
stroke-width: 1.5px;
}

.node {
fill: #000;
stroke: #fff;
stroke-width: 1.5px;
}

.node.a { fill: #1f77b4; }
.node.b { fill: #ff7f0e; }
.node.c { fill: #2ca02c; }
</style>
<body>
<a href="../index.html">cola.js home</a>
<h1>Continuous layout while graph is changing</h1>
<script src="../extern/d3.v3.js"></script>
<script src="../cola.min.js"></script>
<script>

var width = 960,
    height = 500;

var color = d3.scale.category10();

var nodes = [],
    links = [];

var force = cola.d3adaptor()
    .nodes(nodes)
    .links(links)
    .linkDistance(140)
    .size([width, height])
    .on("tick", tick);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

var node = svg.selectAll(".node"),
    link = svg.selectAll(".link");

// 1. Add three nodes and three links.
setTimeout(function () {
    var a = { id: "a", name: "A"  }, b = { id: "b", name: "B" }; //, c = { id: "c" }
    nodes.push(a, b);
    links.push({ source: a, target: b }, { source: a, target: b }); //, { source: b, target: c }
    start();
}, 0);

// 2. Remove node B and associated links.
setTimeout(function () {
    nodes.splice(1, 1); // remove b
    links.shift(); // remove a-b
    links.pop(); // remove b-c
    start();
}, 3000);

// Add node B back.
setTimeout(function () {
    var a = nodes[0], b = { id: "b", x: 0, y: 0 }, c = nodes[1];
    nodes.push(b);
    links.push({ source: a, target: b }, { source: c, target: b });
    start();
}, 6000);

function start() {
    link = link.data(force.links(), function (d) { return d.source.id + "-" + d.target.id; });
    // Initial end positions are at the source... that way when we add a new target node with transitions,
    // the edges appear to grow out of the source
    link.enter().insert("line", ".node").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.source.x; })
        .attr("y2", function (d) { return d.source.y; });
    link.exit().remove();

    node = node.data(force.nodes(), function (d) { return d.id; });
    node.enter().append("circle").attr("class", function (d) { return "node " + d.id; }).attr("r", 8);
    node.append("svg:text").attr("text-anchor", "middle")
    node.exit().remove();

    force.start();
}

function tick() {
    node.transition().attr("cx", function (d) { return d.x; })
        .attr("cy", function (d) { return d.y; })

    link.transition().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; });
}



</script>
</body>

Create a group element for each node which groups the circle and text.

  var nodeData = node.data(force.nodes(), function(d) {
    return d.id;
  });

  node = nodeData.enter().append("g");

  node.append("circle").attr("class", function(d) {
    return "node " + d.id;
  }).attr("r", 8);

  node.append("svg:text")
    .attr("text-anchor", "middle")
    .attr("dy", ".30em")
    .text(function(d) { 
      return d.name //The text content to be shown as label
    })

  nodeData.exit().remove();

Then update the group position in tick function.

function tick() {

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

  link.transition().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;
    });
}

Working Code Snippet:

 var width = 960, height = 500; var color = d3.scale.category10(); var nodes = [], links = []; var force = cola.d3adaptor() .nodes(nodes) .links(links) .linkDistance(140) .size([width, height]) .on("tick", tick); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var node = svg.selectAll(".node"), link = svg.selectAll(".link"); // 1. Add three nodes and three links. setTimeout(function() { var a = { id: "a", name: "A" }, b = { id: "b", name: "B" }; //, c = { id: "c" } nodes.push(a, b); links.push({ source: a, target: b }, { source: a, target: b }); //, { source: b, target: c } start(); }, 0); // 2. Remove node B and associated links. setTimeout(function() { nodes.splice(1, 1); // remove b links.shift(); // remove ab links.pop(); // remove bc start(); }, 3000); // Add node B back. setTimeout(function() { var a = nodes[0], b = { id: "b", x: 0, y: 0 }, c = nodes[1]; nodes.push(b); links.push({ source: a, target: b }, { source: c, target: b }); start(); }, 6000); function start() { link = link.data(force.links(), function(d) { return d.source.id + "-" + d.target.id; }); // Initial end positions are at the source... that way when we add a new target node with transitions, // the edges appear to grow out of the source link.enter().insert("line", ".node").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.source.x; }) .attr("y2", function(d) { return d.source.y; }); link.exit().remove(); var nodeData = node.data(force.nodes(), function(d) { return d.id; }); node = nodeData.enter().append("g"); node.append("circle").attr("class", function(d) { return "node " + d.id; }).attr("r", 8); node.append("svg:text") .attr("text-anchor", "middle") .attr("dy", ".30em") .text(function(d) { return d.name }) nodeData.exit().remove(); force.start(); } function tick() { node.transition().attr("transform", function(d) { return "translate(" + dx + "," + dy + ")"; }) link.transition().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; }); } 
 .link { stroke: #000; stroke-width: 1.5px; } .node { fill: #000; stroke: #fff; stroke-width: 1.5px; } .node.a { fill: #1f77b4; } .node.b { fill: #ff7f0e; } .node.c { fill: #2ca02c; } text { font-size: 10px; } 
 <script src="http://marvl.infotech.monash.edu/webcola/cola.v3.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM