2014-11-22 3 views
2

У меня возникли проблемы с гиперссылкой дочерних элементов в графе дерева Рейнгольд-Тифолд. График построен в D3 и основан на примере, который использует Mike Bostock: http://bl.ocks.org/mbostock/4339184D3: Гиперссылки в древовидной структуре

Мой код и сегмент моего файла JSON находятся ниже.

На этом этапе график отлично работает - если я нажимаю на родительский узел, он расширяется, чтобы показать серию дочерних узлов, которые содержатся в моем файле JSON. Но когда я добираюсь до уровня ребенка, я хочу сделать слово гиперссылкой. Я не понимаю, как это сделать.

Я использовал предыдущий вопрос/ответ - Hyperlinks in d3.js objects - чтобы понять, как добавить URL-адрес в мои данные JSON (на данный момент все просто связано с Google.co.uk). Но я не понимаю, как связать этот URL с моим деревом, чтобы дочерние узлы стали гиперссылками.

Можете ли вы сообщить мне, как я могу это сделать?

Благодарим вас за любую помощь. (И спасибо, @ IH8, за вашу помощь до сих пор.)

Matt

<html xmlns:xlink="http://www.w3.org/1999/xlink"> 
<head><meta charset="utf-8"> 
<style> 

.node { 
    cursor: pointer; 
} 

.node circle { 
    fill: #FF0000; 
    stroke: black; 
    stroke-width: 1.5px; 
} 

.node text { 
    font: 11px sans-serif; 
} 

.link { 
    fill: none; 
    stroke: #FF0000; 

    stroke-width: 1.5px; 
} 

</style> 
<style id="style-1-cropbar-clipper">/* Copyright 2014 Evernote Corporation. All rights reserved. */ 
.en-markup-crop-options { 
    top: 18px !important; 
    left: 50% !important; 
    margin-left: -100px !important; 
    width: 200px !important; 
    border: 2px rgba(255,255,255,.38) solid !important; 
    border-radius: 4px !important; 
} 

.en-markup-crop-options div div:first-of-type { 
    margin-left: 0px !important; 
} 
</style></head><body> 
<script src="http://d3js.org/d3.v3.min.js"></script> 
<script> 

var margin = {top: 20, right: 120, bottom: 20, left: 120}, 
    width = 960 - margin.right - margin.left, 
    height = 800 - margin.top - margin.bottom; 

var i = 0, 
    duration = 750, 
    root; 

var tree = d3.layout.tree() 
    .size([height, width]); 

var diagonal = d3.svg.diagonal() 
    .projection(function(d) { return [d.y, d.x]; }); 

var svg = d3.select("body").append("svg") 
    .attr("width", width + margin.right + margin.left) 
    .attr("height", height + margin.top + margin.bottom) 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

d3.json("/sites/default/files/tcs/D3/data/turbo.json", function(error, turbo) { 
    root = turbo; 
    root.x0 = height/2; 
    root.y0 = 0; 

    function collapse(d) { 
    if (d.children) { 
     d._children = d.children; 
     d._children.forEach(collapse); 
     d.children = null; 
    } 
    } 

    root.children.forEach(collapse); 
    update(root); 
}); 

d3.select(self.frameElement).style("height", "800px"); 

function update(source) { 

    // Compute the new tree layout. 
    var nodes = tree.nodes(root).reverse(), 
     links = tree.links(nodes); 

    // Normalize for fixed-depth. 
    nodes.forEach(function(d) { d.y = d.depth * 180; }); 

    // Update the nodes… 
    var node = svg.selectAll("g.node") 
     .data(nodes, function(d) { return d.id || (d.id = ++i); }); 

    // Enter any new nodes at the parent's previous position. 
    var nodeEnter = node.enter().append("g") 
     .attr("class", "node") 
     .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }) 
     .on("click", click); 

    nodeEnter.append("circle") 
     .attr("r", 1e-6) 
     .style("fill", function(d) { return d._children ? "red" : "#fff"; }); 


    nodeEnter.each(function(d){ 
    var thisNode = d3.select(this); 
    if (!d.children) { 
     thisNode.append("a") 
      .attr("xlink:href", function(d) { return d.url; }) 
      .append("text") 
       .attr("x", 8) 
       .attr("dy", 3) 
       .attr("text-anchor", "start") 
       .text(function(d) { return d.name; }); 
    } else { 
     thisNode.append("text") 
      .attr("x", -8) 
      .attr("dy", 3) 
      .attr("text-anchor", "end") 
      .text(function(d) { return d.name; });  
    } 
}); 


    // Transition nodes to their new position. 
    var nodeUpdate = node.transition() 
     .duration(duration) 
     .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }); 

    nodeUpdate.select("circle") 
     .attr("r", 4.5) 
     .style("fill", function(d) { return d._children ? "red" : "#fff"; }); 

    nodeUpdate.select("text") 
     .style("fill-opacity", 1); 

    // Transition exiting nodes to the parent's new position. 
    var nodeExit = node.exit().transition() 
     .duration(duration) 
     .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; }) 
     .remove(); 

    nodeExit.select("circle") 
     .attr("r", 1e-6); 

    nodeExit.select("text") 
     .style("fill-opacity", 1e-6); 

    // Update the links… 
    var link = svg.selectAll("path.link") 
     .data(links, function(d) { return d.target.id; }); 

    // Enter any new links at the parent's previous position. 
    link.enter().insert("path", "g") 
     .attr("class", "link") 
     .attr("d", function(d) { 
     var o = {x: source.x0, y: source.y0}; 
     return diagonal({source: o, target: o}); 
     }); 

    // Transition links to their new position. 
    link.transition() 
     .duration(duration) 
     .attr("d", diagonal); 

    // Transition exiting nodes to the parent's new position. 
    link.exit().transition() 
     .duration(duration) 
     .attr("d", function(d) { 
     var o = {x: source.x, y: source.y}; 
     return diagonal({source: o, target: o}); 
     }) 
     .remove(); 

    // Stash the old positions for transition. 
    nodes.forEach(function(d) { 
    d.x0 = d.x; 
    d.y0 = d.y; 
    }); 
} 

// Toggle children on click. 
function click(d) { 
    if (d.children) { 
    d._children = d.children; 
    d.children = null; 
    } else { 
    d.children = d._children; 
    d._children = null; 
    } 
    update(d); 
} 

</script> 
</body> 
</html> 

Часть моего JSON файла:

{ 
"name": "turbo", 


"children": [ 
    { 

    "name": "Level 1", 
    "children": [ 

    { 
    "name": "Google", 
    "children": [ 
     {"name": "Website", "size": 3938, "URL":"http://www.google.co.uk"}, 
     {"name": "CommunityStructure", "size": 3812, "URL":"http://www.google.co.uk"}, 
     {"name": "HierarchicalCluster", "size": 6714, "URL":"http://www.google.co.uk"}, 
     {"name": "MergeEdge", "size": 743, "URL":"http://www.google.co.uk"} 
    ] 
    }, 

    { 
    "name": "graph", 
    "children": [ 
     {"name": "BetweennessCentrality", "size": 3534, "URL":"http://www.google.co.uk"}, 
     {"name": "LinkDistance", "size": 5731, "URL":"http://www.google.co.uk"}, 
     {"name": "MaxFlowMinCut", "size": 7840, "URL":"http://www.google.co.uk"}, 
     {"name": "ShortestPaths", "size": 5914, "URL":"http://www.google.co.uk"}, 
     {"name": "SpanningTree", "size": 3416, "URL":"http://www.google.co.uk"} 
    ] 
    }, 
    { 
    "name": "optimization", 
    "children": [ 
     {"name": "AspectRatioBanker", "size": 7074, "URL":"http://www.google.co.uk"} 
    ] 
    } 
    ] 
    }, 
. . . 

ответ

4

Кажется, вы сделали небольшую ошибку при создании ваш атрибут url набора данных, или вы должны адаптировать код, который вы используете, чтобы добавить атрибут xlink: href к элементу. Вы звоните:

.attr("xlink:href", function(d) { return d.url; }) 

Но в наборе данных атрибут определяется следующим образом:

"URL": "http://www.google.co.uk" 

Те не совпадают, вы должны изменить свой код на этот:

.attr("xlink:href", function(d) { return d.URL; }) 

Или ваш набор данных к этому:

"url": "http://www.google.co.uk" 

Помните, что имена свойств JSON чувствительны к регистру.

+0

Это была огромная помощь. Теперь работает. Спасибо! – scaffolding

Смежные вопросы