Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
492 views
in Technique[技术] by (71.8m points)

javascript - d3js arrowheads not showing

I have an example of force directed graph. And i want to show arrowheads, but no matter what i tried i can't see them.

Here is my javascript

    var nodes = {};

    // Compute the distinct nodes from the links.
    links.forEach(function(link) {
        link.source = nodes[link.source] || (nodes[link.source] = {
            name: link.source
        });
        link.target = nodes[link.target] || (nodes[link.target] = {
            name: link.target
        });
    });

    var width = 960,
        height = 500;

    var force = d3.layout.force()
        .nodes(d3.values(nodes))
        .links(links)
        .size([width, height])
        .linkDistance(100)
        .charge(-300)
        .on("tick", tick)
        .start();

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

    svg.append("svg:defs").selectAll("marker")
        .data(["arrow"])
        .enter().append("svg:marker")
        .attr("id", "arrow")
        .attr("viewBox","0 0 10 10")
        .attr("refX","20")
        .attr("refY","5")
        .attr("markerUnits","strokeWidth")
        .attr("markerWidth","9")
        .attr("markerHeight","5")
        .attr("orient","auto")
        .append("svg:path")
        .attr("d","M 0 0 L 10 5 L 0 10 z")
        .attr("fill", "#f0f0f0");

    var link = svg.append("svg:g").selectAll("line")
        .data(force.links())
        .enter().append("svg:line")
        .attr("class", "link")
        .attr("marker-mid", "url(#arrow)");

    var node = svg.append("svg:g").selectAll(".node")
        .data(force.nodes())
        .enter().append("g")
        .attr("class", "node")
        .call(force.drag);

    node.append("circle")
        .attr("r", 8);

    node.append("text")
        .attr("x", -22)
        .text(function(d) {
        return d.name;
    });

    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;
        });
        link.attr("marker-mid", "url(#arrow)");

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

And here is my jsfiddle

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

From the MDN docu on marker-mid:

The marker-mid defines the arrowhead or polymarker that shall be drawn at every vertex other than the first and last vertex of the given element or basic shape.

So the marker will be inserted at every vertex, but the start and end.

A simple line segment, however, has no other vertices, but its start and end. Thus there are no markers shown in your code.

If you change your marker-mid to, e.g., marker-end, you will see the arrow heads (although right now, they are not that pretty): fiddle.

Another way, would be to change the line-elements to path elements and add a additional vertex in the mid. This, however, would require some more sufficient code.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...