D3:树形图中的超链接

sca*_*ing 4 javascript json hyperlink d3.js

我在超链接 Reingold-Tifold 树图中的子元素时遇到问题。该图是在 D3 中构建的,基于 Mike Bostock 使用的示例: http: //bl.ocks.org/mbostock/4339184

\n\n

我的代码和 JSON 文件的一部分如下。

\n\n

此时,图表工作正常 - 如果我单击父节点,它会展开以显示 JSON 文件中包含的一系列子节点。但是当我到达儿童级别时,我想让这个词成为超链接。我不明白该怎么做。

\n\n

我使用了之前的 SO 问题/答案 - d3.js 对象中的超链接- 来了解如何将 URL 添加到我的 JSON 数据(此时所有内容都只是链接到 Google.co.uk)。但我不明白如何将该 URL 链接到我的树形图,以便子节点成为超链接。

\n\n

你能让我知道我该怎么做吗?

\n\n

预先感谢您的任何帮助。(感谢@IH8,到目前为止您的帮助。)

\n\n

马特

\n\n
<html xmlns:xlink="http://www.w3.org/1999/xlink">\n<head><meta charset="utf-8">\n<style>\n\n.node {\n  cursor: pointer;\n}\n\n.node circle {\n  fill: #FF0000;\n  stroke: black;\n  stroke-width: 1.5px;\n}\n\n.node text {\n  font: 11px sans-serif;\n}\n\n.link {\n  fill: none;\n  stroke: #FF0000;\n\n  stroke-width: 1.5px;\n}\n\n</style>\n<style id="style-1-cropbar-clipper">/* Copyright 2014 Evernote Corporation. All rights reserved. */\n.en-markup-crop-options {\n    top: 18px !important;\n    left: 50% !important;\n    margin-left: -100px !important;\n    width: 200px !important;\n    border: 2px rgba(255,255,255,.38) solid !important;\n    border-radius: 4px !important;\n}\n\n.en-markup-crop-options div div:first-of-type {\n    margin-left: 0px !important;\n}\n</style></head><body>\n<script src="http://d3js.org/d3.v3.min.js"></script>\n<script>\n\nvar margin = {top: 20, right: 120, bottom: 20, left: 120},\n    width = 960 - margin.right - margin.left,\n    height = 800 - margin.top - margin.bottom;\n\nvar i = 0,\n    duration = 750,\n    root;\n\nvar tree = d3.layout.tree()\n    .size([height, width]);\n\nvar diagonal = d3.svg.diagonal()\n    .projection(function(d) { return [d.y, d.x]; });\n\nvar svg = d3.select("body").append("svg")\n    .attr("width", width + margin.right + margin.left)\n    .attr("height", height + margin.top + margin.bottom)\n  .append("g")\n    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");\n\nd3.json("/sites/default/files/tcs/D3/data/turbo.json", function(error, turbo) {\n  root = turbo;\n  root.x0 = height / 2;\n  root.y0 = 0;\n\n  function collapse(d) {\n    if (d.children) {\n      d._children = d.children;\n      d._children.forEach(collapse);\n      d.children = null;\n    }\n  }\n\n  root.children.forEach(collapse);\n  update(root);\n});\n\nd3.select(self.frameElement).style("height", "800px");\n\nfunction update(source) {\n\n  // Compute the new tree layout.\n  var nodes = tree.nodes(root).reverse(),\n      links = tree.links(nodes);\n\n  // Normalize for fixed-depth.\n  nodes.forEach(function(d) { d.y = d.depth * 180; });\n\n  // Update the nodes\xe2\x80\xa6\n  var node = svg.selectAll("g.node")\n      .data(nodes, function(d) { return d.id || (d.id = ++i); });\n\n  // Enter any new nodes at the parent\'s previous position.\n  var nodeEnter = node.enter().append("g")\n      .attr("class", "node")\n      .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })\n      .on("click", click);\n\n  nodeEnter.append("circle")\n      .attr("r", 1e-6)\n      .style("fill", function(d) { return d._children ? "red" : "#fff"; });\n\n\n  nodeEnter.each(function(d){\n    var thisNode = d3.select(this);\n    if (!d.children) {\n        thisNode.append("a")\n            .attr("xlink:href", function(d) { return d.url; })\n            .append("text")\n                .attr("x", 8)\n                .attr("dy", 3)\n                .attr("text-anchor", "start")\n                .text(function(d) { return d.name; });\n    } else {\n        thisNode.append("text")\n            .attr("x", -8)\n            .attr("dy", 3)\n            .attr("text-anchor", "end")\n            .text(function(d) { return d.name; });      \n    }\n});\n\n\n  // Transition nodes to their new position.\n  var nodeUpdate = node.transition()\n      .duration(duration)\n      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });\n\n  nodeUpdate.select("circle")\n      .attr("r", 4.5)\n      .style("fill", function(d) { return d._children ? "red" : "#fff"; });\n\n  nodeUpdate.select("text")\n      .style("fill-opacity", 1);\n\n  // Transition exiting nodes to the parent\'s new position.\n  var nodeExit = node.exit().transition()\n      .duration(duration)\n      .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })\n      .remove();\n\n  nodeExit.select("circle")\n      .attr("r", 1e-6);\n\n  nodeExit.select("text")\n      .style("fill-opacity", 1e-6);\n\n  // Update the links\xe2\x80\xa6\n  var link = svg.selectAll("path.link")\n      .data(links, function(d) { return d.target.id; });\n\n  // Enter any new links at the parent\'s previous position.\n  link.enter().insert("path", "g")\n      .attr("class", "link")\n      .attr("d", function(d) {\n        var o = {x: source.x0, y: source.y0};\n        return diagonal({source: o, target: o});\n      });\n\n  // Transition links to their new position.\n  link.transition()\n      .duration(duration)\n      .attr("d", diagonal);\n\n  // Transition exiting nodes to the parent\'s new position.\n  link.exit().transition()\n      .duration(duration)\n      .attr("d", function(d) {\n        var o = {x: source.x, y: source.y};\n        return diagonal({source: o, target: o});\n      })\n      .remove();\n\n  // Stash the old positions for transition.\n  nodes.forEach(function(d) {\n    d.x0 = d.x;\n    d.y0 = d.y;\n  });\n}\n\n// Toggle children on click.\nfunction click(d) {\n  if (d.children) {\n    d._children = d.children;\n    d.children = null;\n  } else {\n    d.children = d._children;\n    d._children = null;\n  }\n  update(d);\n}\n\n</script>\n</body>\n</html>\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的 JSON 文件的一部分:

\n\n
{\n "name": "turbo",\n\n\n "children": [\n  {\n\n   "name": "Level 1",\n   "children": [\n\n    {\n     "name": "Google",\n     "children": [\n      {"name": "Website", "size": 3938, "URL":"http://www.google.co.uk"},\n      {"name": "CommunityStructure", "size": 3812, "URL":"http://www.google.co.uk"},\n      {"name": "HierarchicalCluster", "size": 6714, "URL":"http://www.google.co.uk"},\n      {"name": "MergeEdge", "size": 743, "URL":"http://www.google.co.uk"}\n     ]\n    },\n\n    {\n     "name": "graph",\n     "children": [\n      {"name": "BetweennessCentrality", "size": 3534, "URL":"http://www.google.co.uk"},\n      {"name": "LinkDistance", "size": 5731, "URL":"http://www.google.co.uk"},\n      {"name": "MaxFlowMinCut", "size": 7840, "URL":"http://www.google.co.uk"},\n      {"name": "ShortestPaths", "size": 5914, "URL":"http://www.google.co.uk"},\n      {"name": "SpanningTree", "size": 3416, "URL":"http://www.google.co.uk"}\n     ]\n    },\n    {\n     "name": "optimization",\n     "children": [\n      {"name": "AspectRatioBanker", "size": 7074, "URL":"http://www.google.co.uk"}\n     ]\n    }\n   ]\n  }, \n. . . \n
Run Code Online (Sandbox Code Playgroud)\n

iH8*_*iH8 5

似乎您在创建数据集 url 属性时犯了一个小错误,或者您应该调整用于将 xlink:href 属性添加到 a 元素的代码。您正在呼叫:

.attr("xlink:href", function(d) { return d.url; })
Run Code Online (Sandbox Code Playgroud)

但在您的数据集中,属性定义如下:

"URL": "http://www.google.co.uk"
Run Code Online (Sandbox Code Playgroud)

这些不匹配,您应该将代码更改为:

.attr("xlink:href", function(d) { return d.URL; })
Run Code Online (Sandbox Code Playgroud)

或者你的数据集是这样的:

 "url": "http://www.google.co.uk"
Run Code Online (Sandbox Code Playgroud)

请记住,JSON 属性的名称区分大小写。