Reputation: 3829
I created a marker to show at the end of the line element. But my problem is that when the marker tag is generated dynamically it is not displayed at the end of the line.
What I do is that firstly I append svg to the html body.
var svg = d3.select('body').append("svg").attr("width", 300).attr("height", 300).attr("id", "cloud");
then I append marker to the svg.
$('svg').append('<defs><marker id="arrow" viewbox="0 -5 10 10" refX="18" refY="0"markerWidth="6" markerHeight="6" orient="auto"><path d="M0,-5L10,0L0,5Z"></marker> </defs>');
Then I append line to the svg with attribute marker-end pointing to svg marker element.
svg.append("g").selectAll("line.link")
.data(force.links())
.enter().append("line")
.attr("class", "link")
.attr("marker-end", "url(#arrow)");
The marker is not displayed at the line end. Here is the link of that code in jsfiddle http://jsfiddle.net/2NJ25/2/
But when I remove the dynamic append using jquery and I define the marker tag inside the html like the code below it works here is the link that http://jsfiddle.net/AqK4L/4/
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Cloud</title>
<script type="text/javascript" src="d3.v2.js"></script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
</head>
<body>
<svg id="cloud" width="800" height="600">
<defs>
<marker id="arrow" viewbox="0 -5 10 10" refX="18" refY="0"
markerWidth="6" markerHeight="6" orient="auto">
<path d="M0,-5L10,0L0,5Z">
</marker>
</defs>
</svg>
<link href="cloud.css" rel="stylesheet" type="text/css" />
<script src="cloud.js" type="text/javascript"></script>
</body>
</html>
What is the problem when I generated the marker tag dynamically. Why the marker is not displayed? I want to generate the marker tag dynamically. How to do this?
Upvotes: 1
Views: 2344
Reputation: 11
Some code added. Check out my update
1)
var texts = svg.selectAll(".label")
.data(force.nodes())
.enter()
.append("text")
.attr("class", "label")
.attr("fill", "black")
.text(function(d) { return d.name; })
.call(force.drag);
2)
texts.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
css
.node, .label {
cursor:pointer;
}
Upvotes: 0
Reputation: 109242
The problem is that by adding the SVG elements as text using jquery, they are getting interpreted in the wrong namespace. That is, there are no defs
, marker
, etc elements in HTML and therefore they don't do anything. These elements are only valid in the SVG namespace, which you don't specify when adding them dynamically. When they are specified statically, the namespace is obvious from the context.
There are several ways to fix this. You could explicitly create the nodes with the correct namespace and add them at the appropriate location. An easier solution however is to use D3 to add those elements, which will take care of the namespace issues for you. The code would be a bit more verbose, but straightforward.
svg.append("defs").append("marker")
.attr("id", "arrow")
.attr("viewbox", "0 -5 10 10")
.attr("refX", 18)
.attr("refY", 0)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5");
Updated jsfiddle here.
Upvotes: 3