How to re-render an SVG in d3?-Collection of common programming errors
I am adapting the d3 example calendar located here: http://bl.ocks.org/4063318
and I’m trying to make it so that each day in the calendar is hyperlinked.
To do so, I added an anchor tag around each “rect”, like so:
var rect = svg.selectAll(".day")
.data(function(d) { return d3.time.days(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
.enter()
.append("a") //my new line of code
.attr("xlink:href", "http://stackoverflow.com") //my new line of code
.append("rect")
.attr("class", "day")
.attr("width", cellSize)
.attr("height", cellSize)
.attr("x", function(d) { return week(d) * cellSize; })
.attr("y", function(d) { return day(d) * cellSize; })
.datum(format);
This will link each rect to this website. However, I want the link to be data dependent. So, instead of the line above:
.attr("xlink:href", "http://stackoverflow.com") //my new line of code
I use:
.attr("class", "rectAnchor")
I do this so that I can select the rectAnchor and then access their rect child, then set the xlink:href attribute, like so, in the following code:
d3.csv("dji.csv", function(error, csv) {
var data = d3.nest()
.key(function(d) { return d.Date; })
.rollup(function(d) { return (d[0].Close - d[0].Open) / d[0].Open; })
.map(csv);
rect.filter(function(d) { return d in data; })
.attr("class", function(d) { return "day " + color(data[d]); })
.attr("dyanmiclinktext", function(d) { return data[d]; }) //my new line of code
.select("title")
.text(function(d) { return d + ": " + percent(data[d]); });
$(".rectAnchor") //my new line
.attr("xlink:href", function(){ //my new line
return "http:/127.0.0.1/subdir/" + $(this).children("rect").attr("dynamiclinktext"); //my new line
});
});
Now, when I do that, there are no working hyperlinks and another two undesirable things happen: First, the link inside the anchor tag says xlink:href”URL” instead of href:”URL” . Secondly, if I change the line .attr(“xlink:href”, function(){ to .attr(“href”, function(){ , it still doesn’t work. So, I’m wondering, is this because the svg has already been rendered and I need to re-render it with these new and improved anchor tags? Or is there something else I’m missing? Any help is appreciated. Thanks!
addendum:
$(".rectAnchor").attr("xlink:href", "http:/127.0.0.1/subdir/" + $(this).children("rect").attr("finer"));
generates:
2012-03-13: group1
(Notice the undefined and the ‘xlink:href’ instead of just ‘href’)
$(".rectAnchor").attr("xlink:href", function(d) { return "http:/127.0.0.1/subdir/" + $(this).children("rect").attr("finer");});
generates:
2012-03-05: group2
Neither are hyperlinked in the displayed svg (i.e. mouse pointer exhibits no difference and clicking does nothing.) I also changed ‘xlink:href’ to ‘href’ in the 2 cases. this outputted the same as above, but with the ‘xlink:’ missing. However, as before, nothing was hyperlinked. Thanks.
-
Where you’re using
$(".rectAnchor")
, you’re now in jQuery world – not d3 world.The
attr()
function in jQuery doesn’t work with functions, the way d3’sattr()
.You need simply:
$(".rectAnchor").attr( "xlink:href", "http:/127.0.0.1/subdir/" + $(this).children("rect").attr("dynamiclinktext") );
Assuming there are no other issues, this should work.
EDIT:
Actually, I didn’t notice
$(".rectAnchor")
yields multiple elements. You need a hybrid of your previous attempt and my suggestion above:$(".rectAnchor").each(function(i, element) { var $el = $(element);// $(this) would work too $el.attr("xlink:href", "http://127.0.0.1/subdir/" + $el.children("rect").attr("dynamiclinktext")); });
Note that where you have
http:/127...
you actually needhttp://127....
(i.e. you’re missing a slash).Finally, are you sure that wrapping SVG elements with tags actually works for making them links? It may, but I’ve never tried it. If you’re not sure, you should try it out as a standalone test (in, say, jsFiddle) with manually generated SVG (i.e. no javascript).
Originally posted 2013-11-19 13:18:42.