Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is d3 edge labeling possible?

Tags:

html

svg

d3.js

Is it possible to have edge labels in a graph using d3? I've looked over the examples and some of the documentation, and I can see where node labeling is possible, but edge labeling is not explicitly mentioned anywhere (that I can find).

like image 818
Josh Bradley Avatar asked Jun 11 '12 17:06

Josh Bradley


3 Answers

Following other peoples examples I

  • add a path alongside every edge,
  • add text to the edges
  • bind that text to a textpath which is referencing the path along the edge

This example is using the above ideas: http://bl.ocks.org/jhb/5955887

like image 120
Joerg Baach Avatar answered Nov 04 '22 06:11

Joerg Baach


The short answer is "yes", but there's no explicit support for it. You'll have to determine the position of the label yourself. One way of doing this would be to attach the label to the start node and translate it by half the distance to the target node, plus some offset to prevent it overlapping the line. For more elaborate edges (e.g. curves) it would be more difficult.

like image 2
Lars Kotthoff Avatar answered Nov 04 '22 06:11

Lars Kotthoff


I tried the text on a path option, but it is quite involved and didn't result in the appearance I wanted. Unfortunately, I didn't check it into the local git repository. This comes from my Eclipse history (thanks Eclipse developers). You'll have to change this code snippet to your own data structure, but I'll hope it is of some help. In particular, notice the adding of the id value to the lines selection and then reusing it in the percentages selection by using the xlink:href attribute. Also, I appended a tspan in the textpath to move the text down by a couple of pixels so it appears over the path instead of on it.

        function drawLines(links) {
        var diagonal = d3.svg.diagonal();
        var format = d3.format(".1%");
        var linkKey = function(l) {return l.target.key; };
        var lines = linesGroup.selectAll("path").data(links, linkKey);
        lines.enter()
            .append("path")
            .on("mouseover", select)
            .on("mouseout", unselect)
            .attr("d", diagonal)
            .attr("id", function (l) { return "interaction-path-target-" + l.target.key; })
            .style("stroke-width", 0.000001);
        lines.exit()
            .transition().duration(500)
            .style("stroke-width", 0.000001)
            .remove();

        lines.transition()
            .delay( function(d, i) { return i * 100; })
            .duration(500)
            .style("stroke-width", function(d) { return d.weight == 0 ? 0.000001 : d.weight / 1000; })
            .attr("d", diagonal);

        var percentages = linesGroup.selectAll("text").data(links, linkKey);
        percentages.enter()
            .append("text")
            .attr("opacity", 1)
            .append("svg:textPath")
            .attr("startOffset", "70%")
            .attr("xlink:href", 
                    function(l) { 
                        return "#interaction-path-target-" + l.target.key; 
                    })
            .append("svg:tspan")
            .attr("dy", 3)
            .attr("class", "percentageText")
        percentages.exit()
            .transition().duration(500)
            .attr("opacity", 0)
            .remove();
        percentages
            .transition()
            .delay( function(d, i) { return i * 100; })
            .duration(500)
            .attr("opacity", 1);

        percentages.select(".percentageText").text(function(d) {
                var newvalue = d.weight ?
                    d.incomming ? percentageIn(d.weight) : percentageOut(d.weight) : 0;
                return format(newvalue);
            });
    }
like image 1
Dibbeke Avatar answered Nov 04 '22 05:11

Dibbeke