2013-12-19 2 views
4

d3.js에서 프로그래밍하는 방법을 알지 못합니다. 내 질문이 간단하거나 어리 석다는 것을 알고 있습니다. 이 시각화 http://bl.ocks.org/mbostock/1093130, 계층 구조의 마지막 개체 (오렌지 것들) 하이퍼 링크를 추가하여 수정하려고합니다. 누군가가 부모 요소를 클릭 할 때 이미 무언가가 벌어지고 있음을 이해합니다. 그러나 마지막 요소 인 어린이는 클릭에 대해 특정 동작을 수행하지 않는 것 같습니다. 거기에 하이퍼 링크를 추가 할 수 있습니까? ? 접을 수있는 포스 레이아웃의 자식 (d3.js 개체) 하이퍼 링크

은 index.html을

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style> 

.node circle { 
    cursor: pointer; 
    stroke: #3182bd; 
    stroke-width: 1.5px; 
} 

.node text { 
    font: 10px sans-serif; 
    pointer-events: none; 
    text-anchor: middle; 
} 

line.link { 
    fill: none; 
    stroke: #9ecae1; 
    stroke-width: 1.5px; 
} 

</style> 
<body> 
<script src="http://d3js.org/d3.v3.min.js"></script> 
<script> 

var width = 960, 
    height = 500, 
    root; 

var force = d3.layout.force() 
    .linkDistance(80) 
    .charge(-120) 
    .gravity(.05) 
    .size([width, height]) 
    .on("tick", tick); 

var svg = d3.select("body").append("svg") 
    .attr("width", width) 
    .attr("height", height); 

var link = svg.selectAll(".link"), 
    node = svg.selectAll(".node"); 

d3.json("graph.json", function(error, json) { 
    root = json; 
    update(); 
}); 

function update() { 
    var nodes = flatten(root), 
     links = d3.layout.tree().links(nodes); 

    // Restart the force layout. 
    force 
     .nodes(nodes) 
     .links(links) 
     .start(); 

    // Update links. 
    link = link.data(links, function(d) { return d.target.id; }); 

    link.exit().remove(); 

    link.enter().insert("line", ".node") 
     .attr("class", "link"); 

    // Update nodes. 
    node = node.data(nodes, function(d) { return d.id; }); 

    node.exit().remove(); 

    var nodeEnter = node.enter().append("g") 
     .attr("class", "node") 
     .on("click", click) 
     .call(force.drag); 

    nodeEnter.append("circle") 
     .attr("r", function(d) { return Math.sqrt(d.size)/10 || 4.5; }); 

    nodeEnter.append("text") 
     .attr("dy", ".35em") 
     .text(function(d) { return d.name; }); 

    node.select("circle") 
     .style("fill", color); 
} 

function tick() { 
    link.attr("x1", function(d) { return d.source.x; }) 
     .attr("y1", function(d) { return d.source.y; }) 
     .attr("x2", function(d) { return d.target.x; }) 
     .attr("y2", function(d) { return d.target.y; }); 

    node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); 
} 

function color(d) { 
    return d._children ? "#3182bd" // collapsed package 
     : d.children ? "#c6dbef" // expanded package 
     : "#fd8d3c"; // leaf node 
} 

// Toggle children on click. 
function click(d) { 
    if (d3.event.defaultPrevented) return; // ignore drag 
    if (d.children) { 
    d._children = d.children; 
    d.children = null; 
    } else { 
    d.children = d._children; 
    d._children = null; 
    } 
    update(); 
} 

// Returns a list of all nodes under the root. 
function flatten(root) { 
    var nodes = [], i = 0; 

    function recurse(node) { 
    if (node.children) node.children.forEach(recurse); 
    if (!node.id) node.id = ++i; 
    nodes.push(node); 
    } 

    recurse(root); 
    return nodes; 
} 

</script> 

입니다 그리고 이것은 JSON입니다 :

{ 
"name": "flare", 
"children": [ 
    { 
    "name": "analytics", 
    "children": [ 
    { 
    "name": "cluster", 
    "children": [ 
     {"name": "AgglomerativeCluster", "size": 3938}, 
     {"name": "CommunityStructure", "size": 3812}, 
     {"name": "HierarchicalCluster", "size": 6714}, 
     {"name": "MergeEdge", "size": 743} 
    ] 
    }, 
    { 
    "name": "graph", 
    "children": [ 
     {"name": "BetweennessCentrality", "size": 3534}, 
     {"name": "LinkDistance", "size": 5731}, 
     {"name": "MaxFlowMinCut", "size": 7840}, 
     {"name": "ShortestPaths", "size": 5914}, 
     {"name": "SpanningTree", "size": 3416} 
    ] 
    }, 
    { 
    "name": "optimization", 
    "children": [ 
     {"name": "AspectRatioBanker", "size": 7074} 
    ] 
    } 
    ] 
    } 
] 
} 

나는 "AspectRatioBanker는"예를 들어, www.aspectratiobanker.com에 데려다 수 싶습니다. 고맙습니다!

답변

6

두 가지 옵션이 있습니다.

  1. a tag in the SVG을 포함합니다.
  2. 클릭 핸들러에서 작업을 처리합니다. 더 의미 있고 사용자가 노드를 마우스 오른쪽 버튼으로 클릭에 대한 링크이라고보고 웹 주소를 복사 등 새 페이지에서 열 수 있기 때문에

은 첫 번째 옵션은, IMO, 더 나은 사용하는 것입니다

// Toggle children on click. 

var urlMap = { 
    'AspectRatioBanker': 'http://www.google.com' 
    // ... more name -> URL mappings 
}; 

function click(d) { 
    if (d3.event.defaultPrevented) return; // ignore drag 
    if (d.children) { 
    d._children = d.children; 
    d.children = null; 
    } else if (d._children) { 
    d.children = d._children; 
    d._children = null; 
    } else { 
    // This was a leaf node, so redirect. 
    window.location = urlMap[d.name]; 
    } 
    update(); 
} 
+0

감사 :

그러나, 두 번째는 프로그램에 대한 최소한의 변화를 요구한다! 나는 그것이 내가 질문을 표현한 방식 인 것을 알고있다. 나는 이미 대답을 가지고있다. 그러나 그 이름과 다른 URL에 객체를 연결하는 방법이 있는가? 예를 들어 AspectRadioBanker에서 google.com으로 전환한다고 가정 해 보겠습니다. – Ernesto

+0

@Ernesto URLmap 사전으로 답변을 업데이트했습니다. –

+1

대단히 감사합니다. 나는이 문제를 해결하고이 창을 사용하여 떠오르는 창을 팝업으로 표시하는 방법을 찾아 관리했다. ( window.open (d.url, 'popUpWindow', 'height = 600, width = 800, left = 10, top = 10, resizable = yes, scrollbars = no, toolbar = no, menubar = no, location = no, directories = no, status = yes '); } update(); } 나는 너무 자랑 스럽다. 왜냐하면 너무 길기 때문에 이름의 줄을 끊으려고하고있다. – Ernesto