forceレイアウトのノードにリンクが追加されない
<!DOCTYPE html>
<html lang="ja">
<style>
svg {
border: solid 1px;
}
</style>
<head>
<meta charset="utf-8">
<title>D3.js(Force Layout)の練習</title>
</head>
<body>
<script src="http://d3js.org/d3.v3.js" charset="utf-8"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script>
var w = 800;
var h = 800;
var nodes = [];
var links = [];
var xlink = [];
var link2 = [];
var url = "https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/hatena/b/hotentry&num=-1";
var proxy_url = "http://allow-any-origin.appspot.com/" + encodeURIComponent(url);
function for_each(array, func) {
Array.prototype.forEach.call(array, func);
}
function get_html(callback) {
var hatena_hotentry_url = "http://b.hatena.ne.jp/hotentry";
hatena_hotentry_url = "http://allow-any-origin.appspot.com/" + encodeURIComponent(hatena_hotentry_url);
/*// var hatena_hotentry_url = "./hatena_hotentry.html" */
var req = new XMLHttpRequest();
req.open("GET", hatena_hotentry_url);
req.onreadystatechange = function() {
if (req.readyState === 4 && req.status === 200) {
callback(req.responseText);
req = undefined;
}
};
req.send(null);
}
function html_to_relation(html) {
var doc = new DOMParser().parseFromString(html, "text/html");
var error_tags = doc.getElementsByTagName("parsererror");
if (error_tags.length) {
console.log("error: ", error_tags);
return [
["Parse error", "Maybe HTML is broken"]
];
}
var relation = [];
/*// [["name", ...], ...]
*/
var entry_elms = doc.querySelectorAll(
"[data-track-section='default'] .entry-contents");
for_each(entry_elms, function(entry_elm) {
var entry_link_elm = entry_elm.querySelector(".entry-link");
if (!entry_link_elm) {
return;
}
var name_array = [];
relation.push(name_array);
name_array.push(entry_link_elm.title);
console.log(entry_link_elm.href)
var entry_meta_elm = entry_elm.nextElementSibling;
if (!entry_meta_elm) {
return;
}
for_each(entry_meta_elm.querySelectorAll("a.tag"), function(tag_elm) {
name_array.push(tag_elm.textContent);
name_array.push(entry_link_elm.href);
});
});
return relation;
}
function relation_view(relation) {
/*document.getElementById("view").textContent
= JSON.stringify(relation, undefined, 2);
*/
d3.json(proxy_url, function(error, json) {
if (error) {
return console.warn(error);
}
var feeds = json.responseData.feed;
for (var x = 0; x < feeds.entries.length; x++) {
var href = {
"url": feeds.entries[x].link
};
xlink.push(href);
};
});
for (var i = 0; i < relation.length; i++) {
if (i + 1 < relation.length) {
var num = {
"source": i,
"target": +(i + 1)
};
} else {
var num = {
"source": i,
"target": 0
};
}
var list = {
"label": relation[i][0],
"url": relation[i][6]
};
nodes.push(list);
links.push(num);
}
console.log(nodes)
var force = d3.layout.force()
.nodes(nodes)
.links(links)
.size([w, h])
.linkStrength(0.1)
.friction(0.9)
.distance(200)
.charge(-30)
.gravity(0.1)
.theta(0.8)
.alpha(0.1)
.start();
/*console.log(nodes)*/
var svg = d3.select("body").append("svg").attr({
width: w,
height: h
});
var link = svg.selectAll("line")
.data(links)
.enter()
.append("line")
.style({
stroke: "#ccc",
"stroke-width": 1
});
var node = svg.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr({
r: 20,
opacity: 0.5
})
.attr("xlink:href", function(d) {
return d.url;
})
.style({
fill: "red"
})
.call(force.drag);
var label = svg.selectAll('text')
.data(nodes)
.enter()
.append('text')
.attr({
"text-anchor": "middle",
"fill": "black"
})
.style({
"font-size": 11
})
.text(function(d) {
return d.label;
});
force.on("tick", function() {
link.attr({
x1: function(d) {
return d.source.x;
},
y1: function(d) {
return d.source.y;
},
x2: function(d) {
return d.target.x;
},
y2: function(d) {
return d.target.y;
}
});
node.attr({
cx: function(d) {
return d.x;
},
cy: function(d) {
return d.y;
}
});
label.attr({
x: function(d) {
return d.x;
},
y: function(d) {
return d.y
}
});
})
}
get_html(function(html) {
relation_view(html_to_relation(html));
});
</script>
</body>
</html>
上記のようなソースでforceレイアウトを描画しています。
node配列の中にlabelとurlを準備し、こちら( http://bl.ocks.org/tag1216/76e6bba3fd1784eba83c )を参考にさせて頂きリンクを貼れるようにしようとしましたが、上手く動作しません。
どのように訂正すればノードをクリックすればリンク先に正しく飛ぶのでしょうか?
お力添えよろしくお願いいたします。