Javascript d3js Force Directed Graph-单击节点以弹出从JSON读取的信息框
我一直在使用D3js,但对D3js和Javascript还是新手 我希望能够单击节点和页面上的infobox弹出窗口,并打印有关该节点的一些信息(来自JSON) 我的json文件示例:Javascript d3js Force Directed Graph-单击节点以弹出从JSON读取的信息框,javascript,d3.js,force-layout,d3-force-directed,Javascript,D3.js,Force Layout,D3 Force Directed,我一直在使用D3js,但对D3js和Javascript还是新手 我希望能够单击节点和页面上的infobox弹出窗口,并打印有关该节点的一些信息(来自JSON) 我的json文件示例: {"directed": false, "graph": {}, "nodes": [{"id": 0, "name":"Ant" , "info":"Small Animal"}, {"id": 1 , "name":"Apple" , "info":"Fruit"}, {"id": 2 , "name"
{"directed": false, "graph": {},
"nodes": [{"id": 0, "name":"Ant" , "info":"Small Animal"},
{"id": 1 , "name":"Apple" , "info":"Fruit"},
{"id": 2 , "name":"Bat" , "info":"Fly Animal"},
{"id": 3 , "name":"Boat" , "info":"Vehicle"},
{"id": 4 , "name":"Banana" , "info":"Long cute Fruit"},
{"id": 5 , "name":"Cat" , "info":"Best Animal"}],
"links": [{"source": 0, "target": 0 , "weight":1}, {"source": 0, "target": 2, "weight": 0.3},
{"source": 0, "target": 5, "weight":0.8}, {"source": 1, "target": 1, "weight":1},
{"source": 1, "target": 4, "weight":0.5}, {"source": 2, "target": 2, "weight":1},
{"source": 3, "target": 3, "weight":1}, {"source": 4, "target": 4, "weight":1},
{"source": 5, "target": 5, "weight":1}],
"multigraph": false}
所以当我点击一个节点时。它应该弹出如下内容:
Name: Ant
Info: Small Animal
Connected to: Bat with 0.3 weight , Cat with 0.8 weight
我的图形代码与我上面链接的力定向示例非常相似。您可以使用
.on('click',function(d){})在节点上添加click事件代码>
例如:
node.on("click", function(d){
console.log(d);
// here you can access data of node using d.key
alert("You clicked on node " + d.name);
});
下面是一个快速实现,它使用SVG构建您的“信息盒”:
var tip;
node.on("click", function(d){
if (tip) tip.remove();
tip = svg.append("g")
.attr("transform", "translate(" + d.x + "," + d.y + ")");
var rect = tip.append("rect")
.style("fill", "white")
.style("stroke", "steelblue");
tip.append("text")
.text("Name: " + d.name)
.attr("dy", "1em")
.attr("x", 5);
tip.append("text")
.text("Info: " + d.info)
.attr("dy", "2em")
.attr("x", 5);
var con = graph.links
.filter(function(d1){
return d1.source.id === d.id;
})
.map(function(d1){
return d1.target.name + " with weight " + d1.weight;
})
tip.append("text")
.text("Connected to: " + con.join(","))
.attr("dy", "3em")
.attr("x", 5);
var bbox = tip.node().getBBox();
rect.attr("width", bbox.width + 5)
.attr("height", bbox.height + 5)
});
运行代码:
.连接线{
行程:#999;
笔划不透明度:0.6;
}
.节点圆{
冲程:#fff;
笔划宽度:1.5px;
}
正文{
字体系列:无衬线;
}
var svg=d3。选择(“svg”),
宽度=+svg.attr(“宽度”),
高度=+svg.attr(“高度”);
var color=d3.scaleOrdinal(d3.schemeCategory 20);
var simulation=d3.forceSimulation()
.force(“link”,d3.forceLink().id(函数(d){return d.id;}))
.force(“电荷”,d3.forceManyBody())
.力(“中心”,d3.力中心(宽度/2,高度/2));
d3.json(“https://jsonblob.com/api/15daa79f-7573-11e8-b9d7-1b0997147957,函数(错误,图形){
如果(错误)抛出错误;
link=svg.append(“g”)
.attr(“类”、“链接”)
.selectAll(“行”)
.数据(图表.链接)
.enter().append(“行”)
.attr(“笔划宽度”,函数(d){返回d.weight*3;});
var node=svg.append(“g”)
.attr(“类”、“节点”)
.selectAll(“圆圈”)
.数据(图.节点)
.enter().append(“圆”)
.attr(“r”,5)
.attr(“fill”,函数(d){返回颜色(d.group);})
.call(d3.drag()
.on(“开始”,拖动开始)
.打开(“拖动”,拖动)
。在(“结束”,dragended));
var-tip;
打开(“单击”,函数(){
如果(tip)tip.remove();
});
节点上(“单击”,功能(d){
d3.event.stopPropagation();
如果(tip)tip.remove();
tip=svg.append(“g”)
.attr(“转换”、“转换”(+d.x+)、“+d.y+”);
var rect=tip.append(“rect”)
.样式(“填充”、“白色”)
.风格(“笔划”、“钢蓝”);
提示:追加(“文本”)
.text(“名称:”+d.Name)
.attr(“dy”、“1em”)
.attr(“x”,5);
提示:追加(“文本”)
.text(“信息:+d.Info”)
.attr(“dy”,“2em”)
.attr(“x”,5);
var con=graph.links
.过滤器(功能(d1){
返回d1.source.id==d.id;
})
.地图(功能(d1){
返回d1.target.name+“带权重”+d1.weight;
})
提示:追加(“文本”)
.text(“连接到:”+con.join(“,”))
.attr(“dy”、“3em”)
.attr(“x”,5);
var bbox=tip.node().getBBox();
矩形属性(“宽度”,bbox.width+5)
.attr(“高度”,bbox.height+5)
});
模拟
.nodes(图.nodes)
。在(勾选)上;
模拟力(“链接”)
.links(图形链接);
函数勾选(){
链接
.attr(“x1”,函数(d){返回d.source.x;})
.attr(“y1”,函数(d){返回d.source.y;})
.attr(“x2”,函数(d){返回d.target.x;})
.attr(“y2”,函数(d){返回d.target.y;});
节点
.attr(“cx”,函数(d){return d.x;})
.attr(“cy”,函数(d){返回d.y;});
}
});
函数dragstarted(d){
如果(!d3.event.active)simulation.alphaTarget(0.3.restart();
d、 fx=d.x;
d、 fy=d.y;
}
函数(d){
d、 fx=d3.event.x;
d、 fy=d3.event.y;
}
函数d(d){
如果(!d3.event.active)simulation.alphaTarget(0);
d、 fx=null;
d、 fy=null;
}
非常感谢您。它看起来真的很好,但当信息显示时,没有办法删除它(除了单击其他节点)。点击空白时信息框会消失吗?谢谢你的帮助@马克:当我在chrome中运行这个程序时,我得到一个错误:{“消息”:“Uncaught[object ProgressEvent]”,“filename”:“lineno”:46,“colno”:14}@SethRobertson,已修复。@Mark:fixed?我和Seth Robertson犯了同样的错误