为D3网络图表设置链接标签或工具提示

时间:2016-05-10 09:23:05

标签: d3.js label tooltip linklabel

这里我正在使用D3网络图表。我需要为链接添加标签或工具提示。在我的fiddle中,工具提示出现了,但我无法在其中显示文本。 (我需要将每个子节点的权重包括为链接标签)。我还尝试在链接中加入标签,但它根本没有出现。

这是我的代码:

var width = 500
height = 550;

var cluster = d3.layout.cluster()
.size([height - height * 0, width - width * 0.5]);

var diagonal = d3.svg.diagonal()
.projection(function(d) {
    return [d.y, d.x];
});

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.attr("style", "padding-left:5%")
.attr("pointer-events", "all")
.call(d3.behavior.zoom().on("zoom", redraw));

 // Define the div for the tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);

var vis = svg
.append("svg:g");

vis.append("svg:rect")
.attr("width", width)
.attr("height", height)
.attr("fill", 'white');

function redraw() {
   vis.attr("transform",
    "translate(" + d3.event.translate + ")" +
    " scale(" + d3.event.scale + ")");
 }

var root = {
  "name": "output",
  "children": [{
     "name": "sum",
     "children": [{
        "name": "Base",
        "children": [],
        "weight": 1.0000002576768052
    }, {
        "name": "H0",
        "children": [],
        "weight": 2.5767680512326025e-7
    }]
  }]
};

var nodes = cluster.nodes(root),
  links = cluster.links(nodes);

vis.append("svg:defs").selectAll("marker")
.data(["end"]) // Different link/path types can be defined here
.enter().append("svg:marker") // This section adds in the arrows
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");

var link = vis.selectAll(".link")
.data(links)
.enter().append("path")
.attr("class", "link")
.attr("marker-end", "url(#end)")
.attr("d", diagonal)
.on("mouseover", function(d) {
//console.log(d.children.weight);   
        div.transition()        
            .duration(200)      
            .style("opacity", .9);      
        div .html(d.children)   
            .style("left", (d3.event.pageX) + "px")     
            .style("top", (d3.event.pageY - 28) + "px");    
        })                  
    .on("mouseout", function(d) {       
        div.transition()        
            .duration(500)      
            .style("opacity", 0);   
    });


var node = vis.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
    return "translate(" + d.y + "," + d.x + ")";
})
.on("mouseover", mouseover)
.on("mouseout", mouseout);

node.append("circle")
.attr("r", 4.5)
.style("fill", "#3182bd");

node.append("svg:text")
.attr("dx", function(d) {
    return d.children ? -8 : 8;
})
.attr("dy", 3)
.style("text-anchor", function(d) {
    return d.children ? "end" : "start";
})
.style("fill", "#3182bd")
.text(function(d) {
    return d.name;
});

 linktext.enter().append("g").attr("class", "linklabelholder")
  .append("text")
  .attr("class", "linklabel")
  .style("font-size", "13px")
  .attr("x", "50")
  .attr("y", "-20")
  .attr("text-anchor", "start")
   .style("fill","#000")
  .append("textPath")
  .attr("xlink:href",function(d,i) { return "#linkId_" + i;})
    .text(function(d) { 
     return d.type; 
  });

 var text = svg.append("svg:g").selectAll("g")
   .data(nodes)
   .enter().append("svg:g");

 text.append("svg:text")
   .attr("x", "-1em")
   .attr("y", ".31em")
   .style("font-size", "13px")
   .text(function(d) { return d.name; });

function mouseover() {
  d3.select(this).select("circle").transition()
    .duration(750)
    .attr("r", 9)
  d3.select(this).select("text").transition()
    .duration(750)
    .style("stroke-width", ".5px")
    .style("font", "22.8px serif")
    .style("opacity", 1);
 }

function mouseout() {
  d3.select(this).select("circle").transition()
    .duration(750)
    .attr("r", 4.5)
  d3.select(this).select("text").transition()
    .duration(750)
    .style("font", "12px serif")
    .style("opacity", 0.8);
 }

 d3.select(self.frameElement).style("height", height + "px");

1 个答案:

答案 0 :(得分:2)

weight是节点的属性。所以你应该使用d.target.weight



var width = 500
height = 550;

var cluster = d3.layout.cluster()
  .size([height - height * 0, width - width * 0.5]);

var diagonal = d3.svg.diagonal()
  .projection(function(d) {
    return [d.y, d.x];
  });

var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height)
  .attr("style", "padding-left:5%")
  .attr("pointer-events", "all")
  .call(d3.behavior.zoom().on("zoom", redraw));

// Define the div for the tooltip
var div = d3.select("body").append("div")
  .attr("class", "tooltip")
  .style("opacity", 0);

var vis = svg
  .append("svg:g");

vis.append("svg:rect")
  .attr("width", width)
  .attr("height", height)
  .attr("fill", 'white');



function redraw() {
  vis.attr("transform",
    "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
}

var root = {
  "name": "output",
  "children": [{
    "name": "sum",
    "children": [{
      "name": "Base",
      "children": [],
      "weight": 1.0000002576768052
    }, {
      "name": "H0",
      "children": [],
      "weight": 2.5767680512326025e-7
    }]
  }]
};

var nodes = cluster.nodes(root),
  links = cluster.links(nodes);

vis.append("svg:defs").selectAll("marker")
  .data(["end"]) // Different link/path types can be defined here
  .enter().append("svg:marker") // This section adds in the arrows
  .attr("id", String)
  .attr("viewBox", "0 -5 10 10")
  .attr("refX", 15)
  .attr("refY", -1.5)
  .attr("markerWidth", 6)
  .attr("markerHeight", 6)
  .attr("orient", 180)
  .append("svg:path")
  .attr("d", "M0,-5L10,0L0,5");

var link = vis.selectAll(".link")
  .data(links)
  .enter().append("path")
  .attr("class", "link")
  .attr("marker-start", "url(#end)")
  .attr("d", diagonal)
  .attr("id",function(d,i){ return "edgepath"+i })
  .on("mouseover", function(d) {       
    div.transition()
      .duration(200)
      .style("opacity", .9);
    div.html(d.target.weight?d.target.weight:0)
      .style("left", (d3.event.pageX) + "px")
      .style("top", (d3.event.pageY - 28) + "px");
  })
  .on("mouseout", function(d) {
    div.transition()
      .duration(500)
      .style("opacity", 0);
  });

var edgelabels = vis.selectAll(".edgelabel")
  .data(links)
  .enter()
  .append('text')
  .style("pointer-events", "none")
  .attr({
    'class': 'edgelabel',
    'id': function(d, i) {
      return 'edgelabel' + i
    },
    'dx': 80,
    'dy': 0,
    'font-size': 10,
    'fill': '#aaa'
  });

edgelabels.append('textPath')
  .attr('xlink:href', function(d, i) {
    return '#edgepath' + i
  })
  .style("pointer-events", "none")
  .text(function(d, i) {
    return d.target.weight?d.target.weight:0;
  });

edgelabels.attr('transform', function(d, i) {
  if (d.target.x < d.source.x) {
    bbox = this.getBBox();
    tx = bbox.x + bbox.width / 2;
    ty = bbox.y + bbox.height / 2;
    return 'transform(' + tx + ' ' + ty + ')';
  } else {
    return 'rotate(0)';
  }
});


var node = vis.selectAll(".node")
  .data(nodes)
  .enter().append("g")
  .attr("class", "node")
  .attr("transform", function(d) {
    return "translate(" + d.y + "," + d.x + ")";
  })
  .on("mouseover", mouseover)
  .on("mouseout", mouseout);

node.append("circle")
  .attr("r", 4.5)
  .style("fill", "#3182bd");

node.append("svg:text")
  .attr("dx", function(d) {
    return d.children ? -8 : 8;
  })
  .attr("dy", 3)
  .style("text-anchor", function(d) {
    return d.children ? "end" : "start";
  })
  .style("fill", "#3182bd")
  .text(function(d) {
    return d.name;
  });


linktext.enter().append("g").attr("class", "linklabelholder")
  .append("text")
  .attr("class", "linklabel")
  .style("font-size", "13px")
  .attr("x", "50")
  .attr("y", "-20")
  .attr("text-anchor", "start")
  .style("fill", "#000")
  .append("textPath")
  .attr("xlink:href", function(d, i) {
    return "#linkId_" + i;
  })
  .text(function(d) {
    return d.type;
  });

var text = svg.append("svg:g").selectAll("g")
  .data(nodes)
  .enter().append("svg:g");

text.append("svg:text")
  .attr("x", "-1em")
  .attr("y", ".31em")
  .style("font-size", "13px")
  .text(function(d) {
    return d.name;
  });


function mouseover() {
  d3.select(this).select("circle").transition()
    .duration(750)
    .attr("r", 9)
  d3.select(this).select("text").transition()
    .duration(750)
    .style("stroke-width", ".5px")
    .style("font", "22.8px serif")
    .style("opacity", 1);
}

function mouseout() {
  d3.select(this).select("circle").transition()
    .duration(750)
    .attr("r", 4.5)
  d3.select(this).select("text").transition()
    .duration(750)
    .style("font", "12px serif")
    .style("opacity", 0.8);
}

d3.select(self.frameElement).style("height", height + "px");
&#13;
.link {
  fill: none;
  stroke: #ccc;
  opacity: 0.4;
  stroke-width: 1.5px;
}
.node circle {
  stroke: #fff;
  opacity: 0.8;
  stroke-width: 1.5px;
}
.node:not(:hover) .nodetext {
  display: none;
}
text {
  font: 12px serif;
  opacity: 0.8;
  pointer-events: none;
}
div.tooltip {
  position: absolute;
  text-align: center;
  width: 60px;
  height: 28px;
  color: black;
  padding: 2px;
  font: 12px sans-serif;
  background: lightsteelblue;
  border: 0px;
  border-radius: 8px;
  pointer-events: none;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
&#13;
&#13;