2014-09-25 209 views
0

我有一个工作的D3示例。我使用武力,一切正常。但我有一个小问题。假设我有4个节点。看到这张图片:http://i.imgur.com/J0P4I0n.png,现在当我点击节点“AKZO NV”时,我想得到:http://i.imgur.com/fGXVGMd.png与旧的节点和链接。D3强制布局应在点击节点时添加节点和链接

所以最后我想有7个节点。并且“AKZO NV”将被重点关注。所有节点仍然有它们的联系,“AKZO NV”应该有两个。我想你现在知道我想要什么。

所以我已经有了这段代码。像魅力一样工作,但没有正确添加新的节点和链接。我认为这些命令的顺序存在一个小问题。

任何想法,欢迎:

var alreadyThere = false; 
var nodeCircles = {}; 
var svg, link, node; 
var force = d3.layout.force(); 
var nodes, links; 
var width = 700, height = 400; 
var boxIDName = "#main-rightinfo"; 
var JSONFORMERGING; 

function createRealGraph(jsonData){ 
    //console.log(jsonData); 
    if (alreadyThere == false){ 
     JSONFORMERGING=jsonData; 
     initializeGraph(jsonData); 
    }else{ 
     update(JSONFORMERGING.concat(jsonData)); 
    } 
    alreadyThere = true; 
} 
function update(jsonData) { 
    console.log(jsonData); 
    jsonData.forEach(function(link) { 
     link.source = nodeCircles[link.source] || (nodeCircles[link.source] = {name: link.sourceName, ID: link.source, class: link.sourceClass}); 
     link.target = nodeCircles[link.target] || (nodeCircles[link.target] = {name: link.targetName, ID: link.target, class: link.targetClass}); 
    }); 

    link = link.data(links); 
    link.enter().insert("line") 
     .attr("class", "link"); 

    node = node.data(nodes); 
    node.enter().append("g") 
     .attr("class", "node") 
     .attr("r", 5) 
     .call(force.drag); 

    force 
     .nodes(d3.values(nodeCircles)) 
     .links(jsonData) 
     .start(); 
    nodes = force.nodes(); 
    links = force.links(); 
} 
function initializeGraph(jsonData){ 
    jsonData.forEach(function(link) { 
     link.source = nodeCircles[link.source] || (nodeCircles[link.source] = {name: link.sourceName, ID: link.source, class: link.sourceClass}); 
     link.target = nodeCircles[link.target] || (nodeCircles[link.target] = {name: link.targetName, ID: link.target, class: link.targetClass}); 
    }); 

    force 
     .nodes(d3.values(nodeCircles)) 
     .links(jsonData) 
     .size([width, height]) 
     .linkDistance(60) 
     .charge(-200) 
     .on("tick", tick) 
     .start(); 

    nodes = force.nodes(); 
    links = force.links(); 

    svg = d3.select("#main-right") 
     .append("svg") 
     .attr("width", width) 
     .attr("height", height); 
    svg 
     .append("svg:defs").selectAll("marker") 
     .data(["end"]) 
     .enter().append("svg:marker") 
     .attr("id", String) 
     .attr("viewBox", "0 -5 10 10") 
     .attr("refX", 27) 
     .attr("refY", -0.5) 
     .attr("markerWidth", 6) 
     .attr("markerHeight", 6) 
     .attr("orient", "auto") 
     .append("svg:path") 
     .attr("d", "M0,-5L10,0L0,5") 
     .attr('fill', '#00b'); 

    link = svg.selectAll(".link") 
     .data(links) 
     .enter().append("line") 
     .attr("class", "link") 
     .attr("marker-end", "url(#end)"); 

    node = svg.selectAll(".node") 
     .data(nodes) 
     .enter().append("g") 
     .attr("class", "node") 
     .on("mouseover", mouseover) 
     .on("mouseout", mouseout) 
     .on("click", function(d) {click(d);}) 
     .on("dblclick", function(d) {dblclick(d);}) 
     .call(force.drag); 
    node 
     .append("image") 
     .attr("xlink:href", function(d) {if (d.class == "Person") {return "pics/node_person.png";} else {return "pics/node_appln.png";} }) 
     .attr("x", -20) 
     .attr("y", -20) 
     .attr("width", 40) 
     .attr("height", 40); 
    node 
     .append("text") 
     .attr("x", 19) 
     .attr("dy", ".25em") 
     .text(function(d) {return d.name; }); 

    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 + ")"; }); 
    } 
} 
+0

不知道我是否明白你想要什么。您的两张图片显示相同数量的节点 - 您想在哪里添加新节点以及如何添加节点? – 2014-09-25 17:30:05

+0

那么你是对的,节点的数量是相同的。但正如我所说,我想将第二张照片添加到第一张照片。在第一个文件是来源。但在第一个人是谁的重点。但是我不想在这里丢失像这样的文档。那么如果说还不清楚。我做了另一张照片。 – kwoxer 2014-09-25 17:42:08

+0

仍然不知道你想要什么 - 复制所有节点? – 2014-09-25 17:52:24

回答

1

你只需要测试,如果它不是一个对象。这就像一个魅力:

jsonData.forEach(function(link) { 
     if (typeof(link.source) != "object"){ 
      link.source = nodeCircles[link.source] || (nodeCircles[link.source] = {name: link.sourceName, ID: link.source, class: link.sourceClass}); 
     } 
     if (typeof(link.target) != "object"){ 
      link.target = nodeCircles[link.target] || (nodeCircles[link.target] = {name: link.targetName, ID: link.target, class: link.targetClass}); 
     } 
    }); 
0

我正在解决同一个问题,并得到了“解决方案”。它仍然是一个原型,但也许它可以帮助你。

每个鼠标点击一个节点调用一个函数并检测新节点。它们全部保存在nodes中且全部处于活动状态,这意味着显示器上的所有节点都在activeNodes中。属于从根节点到点击路径的所有节点都存储在pathNodes中。结果是,只有活动路径被显示,包括点击的子节点。

希望能够清楚地解释。对于一个更好的了解,请抬头看看源代码:http://github.com/nextlevelshit/d3_nested_nodes

为某事与查出来玩:http://dailysh.it/github/d3_nested_nodes/

这里我的代码片段:

/** 
 
* Triggering mouse click start 
 
*/ 
 

 
function mousedown() { 
 

 
    if (mousedown_node !== null) { 
 

 
    var pathNodes = findPathNodesTo(mousedown_node); 
 

 
    var point = d3.mouse(this), 
 
     node = { 
 
     id: nodes.length, 
 
     parent: mousedown_node.id 
 
     }; 
 
    node.x = point[0]; 
 
    node.y = point[1]; 
 

 
    var newNodes = findNodesbyParentId(mousedown_node.id), 
 
     startingPoint = { 
 
     x: mousedown_node.x, 
 
     y: mousedown_node.y 
 
     }; 
 

 
    for (var i = 0; i < pathNodes.length; i++) { 
 
     newNodes.push(pathNodes[i]); 
 
     pathNodes[i].path = true; 
 
    } 
 

 
    var removeNodes = activeNodes.diff(newNodes); 
 
    var addNodes = newNodes.diff(pathNodes).diff(activeNodes); 
 

 
    for (var i = 0; i < removeNodes.length; i++) { 
 
     removeNode(removeNodes[i].id); 
 
    } 
 

 
    for (var i = 0; i < addNodes.length; i++) { 
 
     addNodes[i].x = startingPoint.x; 
 
     addNodes[i].y = startingPoint.y; 
 
     activeNodes.push(addNodes[i]); 
 
     activeLinks.push({source: findNode(addNodes[i].parent), target: findNode(addNodes[i].id)}); 
 
    } 
 

 
     // TODO: Find a smoother way do delay popping out new nodes 
 
    }); 
 

 
    } 
 

 
    restart(); 
 
}

的最后一个问题是找到一个平滑的方式来弹出新的节点...