D3力布局应在单击节点时添加节点和链接
D3 force layout shall add nodes and links when clicking a node
我有一个正在工作的D3示例。我使用武力,一切都很好。但我有一个小问题。假设我有4个节点。只需查看此图片:https://i.stack.imgur.com/HwniH.png现在,当我点击节点"AKZO NV"时,我想获得:https://i.stack.imgur.com/85oBp.png使用旧节点和链接。
所以最后我想要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 + ")"; });
}
}
您只需要测试它是否不是对象。这就像一种魅力:
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});
}
});
我正在处理同一个问题,并得到了一个"解决方案"。它仍然是一个原型,但也许它对你有帮助。
每次鼠标点击节点都会调用一个函数并检测新节点。它们都保存在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();
}
最后一个问题是找到一种平滑的方法来弹出新节点。。。
相关文章:
- 如何判断何时将dom节点添加到文档中
- 仅首先需要使用jasmine从节点添加一个文件
- 如何将节点添加到子对象
- 手动将节点添加到JavaScript InfoVis Toolkit Force Directed Graph
- 有没有一种方法可以在javascript中为文本节点添加属性
- Node.js-JSON.parse-将节点添加到结果中
- Kendo TreeView-只向没有子节点的父节点添加删除图像图标
- 将节点添加到 KendoUI 树视图无法按预期工作
- 似乎无法将节点添加到剑道UI树视图
- 使用 javascript 将节点添加到 html 页面
- 如何将节点添加到文本区域的末尾
- 扩展 JS 6.无法将节点添加到树面板
- 在d3js Force Layout中向节点添加箭头和文本
- 在javascript中将节点添加到xml文件中
- ArcGIS Javascript API:向图形节点添加类
- 在查询中自动将节点添加到href,并取消默认值
- ExtJS 4.2.1,树,向节点添加子节点
- 在jquery中为一组节点添加一个父节点
- 向节点添加事件侦听器的函数不起作用
- Dynatree jquery插件向节点添加自定义属性