D3.js 实现这种图形需要哪些概念和技术
我想画一幅动态的视觉效果图,展示某些功能块是如何相互作用的。我很难定义我需要什么样的图形,以及什么(如果有的话)d3布局函数最适合开始使用。我甚至不确定我的示例是否属于图形的定义范围 总体思路是将一组函数及其输入和输出可视化。它以一组输入开始,以一组输出结束。中间有几个函数,每个函数接受输入并生成一个或多个输出。每个输出可作为一个或多个功能的输入。因此,每条边/线表示一个输出被传输到一个函数作为输入(并且是单向的)D3.js 实现这种图形需要哪些概念和技术,d3.js,graph-theory,D3.js,Graph Theory,我想画一幅动态的视觉效果图,展示某些功能块是如何相互作用的。我很难定义我需要什么样的图形,以及什么(如果有的话)d3布局函数最适合开始使用。我甚至不确定我的示例是否属于图形的定义范围 总体思路是将一组函数及其输入和输出可视化。它以一组输入开始,以一组输出结束。中间有几个函数,每个函数接受输入并生成一个或多个输出。每个输出可作为一个或多个功能的输入。因此,每条边/线表示一个输出被传输到一个函数作为输入(并且是单向的) 我不是在寻找代码中的答案,而是要了解我需要从哪些概念开始。图像可能有问题,无法
我不是在寻找代码中的答案,而是要了解我需要从哪些概念开始。图像可能有问题,无法从字面上理解,但我无法指出具体内容。对不起,我英语不好,我会说西班牙语。。。 我也在寻找类似的东西,我已经实现了这一点,但我错过了:
- 将节点圆转换为矩形
- 向每个节点和每个链接添加文本标签
- 一旦所有的东西都组织好了,它们就会保持在一个固定的位置上
- 捕获单击每个节点和/或链接以触发另一个应用程序
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: black ;
stroke-width: 0px;
}
</style>
<svg width="1000" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
//create somewhere to put the force directed graph
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
//var radius = 15;
var nodes_data = [
{"name": "PO1", "entity": "PO"},
{"name": "PO2", "entity": "PO"},
{"name": "PO3", "entity": "PO"},
{"name": "PO4", "entity": "PO"},
{"name": "PO5", "entity": "PO"},
{"name": "PO6", "entity": "PO"},
{"name": "PO7", "entity": "PO"},
{"name": "PY1", "entity": "PY"},
{"name": "PY2", "entity": "PY"},
{"name": "L1", "entity": "X"},
{"name": "L2", "entity": "X"},
{"name": "L3", "entity": "X"},
{"name": "L4", "entity": "X"},
{"name": "TK1", "entity": "TK"},
{"name": "TK2", "entity": "TK"},
{"name": "PIL1", "entity": "TK"},
{"name": "BBA1", "entity": "BA"},
{"name": "BBA2", "entity": "BA"},
{"name": "ULAC1", "entity": "UL"},
{"name": "VtaYPF", "entity": "VTA"}
]
//Sample links data
//type: A for Ally, E for Enemy
var links_data = [
{"source": "PO1", "target": "L1", "type":"A" },
{"source": "PO2", "target": "L1", "type":"A" },
{"source": "PO3", "target": "L1", "type":"A"},
{"source": "PO4", "target": "L2", "type":"A"},
{"source": "PO5", "target": "L2", "type":"A"},
{"source": "PO6", "target": "L3", "type":"A"},
{"source": "PO7", "target": "L3", "type":"A"},
{"source": "L1", "target": "L3", "type":"A"},
{"source": "L2", "target": "L3", "type":"A"},
{"source": "L3", "target": "TK1", "type":"A"},
{"source": "L3", "target": "TK2", "type":"A"},
{"source": "TK1", "target": "L4", "type":"A"},
{"source": "TK2", "target": "L4", "type":"A"},
{"source": "L4", "target": "PIL1", "type":"A"},
{"source": "PIL1", "target": "ULAC1", "type":"A"},
{"source": "PIL1", "target": "BBA1", "type":"A"},
{"source": "PIL1", "target": "BBA2", "type":"A"},
{"source": "ULAC1", "target": "VtaYPF", "type":"A"},
{"source": "BBA1", "target": "PY1", "type":"A"},
{"source": "BBA2", "target": "PY2", "type":"A"}
]
//set up the simulation and add forces
var simulation = d3.forceSimulation()
.nodes(nodes_data);
var link_force = d3.forceLink(links_data)
.id(function(d) { return d.name; });
var charge_force = d3.forceManyBody()
.strength(-100);
var center_force = d3.forceCenter(width / 2, height / 2);
simulation
.force("charge_force", charge_force)
.force("center_force", center_force)
.force("links",link_force)
;
//add tick instructions:
simulation.on("tick", tickActions );
//add encompassing group for the zoom
var g = svg.append("g")
.attr("class", "everything");
//draw lines for the links
var link = g.append("g")
.attr("class", "links")
.selectAll("line")
.data(links_data)
.enter().append("line")
.attr("stroke-width", 2)
.style("stroke", linkColour);
//draw circles for the nodes
var node = g.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes_data)
.enter()
.append("circle")
.attr("r", radius)
.attr("fill", circleColour);
//add drag capabilities
var drag_handler = d3.drag()
.on("start", drag_start)
.on("drag", drag_drag)
.on("end", drag_end);
drag_handler(node);
//add zoom capabilities
var zoom_handler = d3.zoom()
.on("zoom", zoom_actions);
zoom_handler(svg);
/** Functions **/
//Function to choose what color circle we have
//Let's return blue for males and red for females
function circleColour(d){
var my_color
switch (d.entity) {
case "PO": my_color = "black"; break;
case "PY": my_color = "cyan"; break;
case "TK": my_color = "blue"; break;
case "UL": my_color = "green"; break;
case "VTA": my_color = "green"; break;
case "BA": my_color = "cyan"; break;
case "X": my_color = "grey"; break;
}
return my_color
}
//Function to choose the line colour and thickness
//If the link type is "A" return green
//If the link type is "E" return red
function linkColour(d){
if(d.type == "A"){
return "green";
} else {
return "red";
}
}
//Drag functions
//d is the node
function drag_start(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
//make sure you can't drag the circle outside the box
function drag_drag(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function drag_end(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
//Zoom functions
function zoom_actions(){
g.attr("transform", d3.event.transform)
}
function tickActions() {
//update circle positions each tick of the simulation
node
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
//update link positions
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; });
}
function radius(d){
var my_rad
switch (d.entity) {
case "PO": my_rad = 10; break;
case "PY": my_rad = 10; break;
case "TK": my_rad = 20; break;
case "UL": my_rad = 20; break;
case "VTA": my_rad = 15; break;
case "BA": my_rad = 10; break;
case "X": my_rad = 3; break;
}
return my_rad
}
</script>
.连接线{
行程:#999;
笔划不透明度:0.6;
}
.节点圆{
笔画:黑色;
笔划宽度:0px;
}
//创建放置力定向图的位置
var svg=d3。选择(“svg”),
宽度=+svg.attr(“宽度”),
高度=+svg.attr(“高度”);
//var半径=15;
变量节点\u数据=[
{“名称”:“PO1”,“实体”:“PO”},
{“名称”:“PO2”,“实体”:“PO”},
{“名称”:“PO3”,“实体”:“PO”},
{“名称”:“PO4”,“实体”:“PO”},
{“名称”:“PO5”,“实体”:“PO”},
{“名称”:“PO6”,“实体”:“PO”},
{“名称”:“PO7”,“实体”:“PO”},
{“name”:“PY1”,“entity”:“PY”},
{“name”:“PY2”,“entity”:“PY”},
{“名称”:“L1”,“实体”:“X”},
{“名称”:“L2”,“实体”:“X”},
{“名称”:“L3”,“实体”:“X”},
{“名称”:“L4”,“实体”:“X”},
{“名称”:“TK1”,“实体”:“TK”},
{“名称”:“TK2”,“实体”:“TK”},
{“名称”:“PIL1”,“实体”:“TK”},
{“名称”:“BBA1”,“实体”:“BA”},
{“名称”:“BBA2”,“实体”:“BA”},
{“名称”:“ULAC1”,“实体”:“UL”},
{“名称”:“VtaYPF”,“实体”:“VTA”}
]
//示例链接数据
//类型:A代表盟友,E代表敌人
变量链接\u数据=[
{“源”:“PO1”,“目标”:“L1”,“类型”:“A”},
{“源”:“PO2”,“目标”:“L1”,“类型”:“A”},
{“源”:“PO3”,“目标”:“L1”,“类型”:“A”},
{“源”:“PO4”,“目标”:“L2”,“类型”:“A”},
{“源”:“PO5”,“目标”:“L2”,“类型”:“A”},
{“源”:“PO6”,“目标”:“L3”,“类型”:“A”},
{“源”:“PO7”,“目标”:“L3”,“类型”:“A”},
{“源”:“L1”,“目标”:“L3”,“类型”:“A”},
{“源”:“L2”,“目标”:“L3”,“类型”:“A”},
{“源”:“L3”,“目标”:“TK1”,“类型”:“A”},
{“源”:“L3”,“目标”:“TK2”,“类型”:“A”},
{“源”:“TK1”,“目标”:“L4”,“类型”:“A”},
{“源”:“TK2”,“目标”:“L4”,“类型”:“A”},
{“源”:“L4”,“目标”:“PIL1”,“类型”:“A”},
{“源”:“PIL1”,“目标”:“ULAC1”,“类型”:“A”},
{“源”:“PIL1”,“目标”:“BBA1”,“类型”:“A”},
{“源”:“PIL1”,“目标”:“BBA2”,“类型”:“A”},
{“source”:“ULAC1”,“target”:“VtaYPF”,“type”:“A”},
{“源”:“BBA1”,“目标”:“PY1”,“类型”:“A”},
{“源”:“BBA2”,“目标”:“PY2”,“类型”:“A”}
]
//设置模拟并添加力
var simulation=d3.forceSimulation()
.节点(节点\数据);
var link\u force=d3.forceLink(links\u数据)
.id(函数(d){返回d.name;});
var charge_force=d3.forceManyBody()
.兵力(-100);
变量中心力=d3力中心(宽度/2,高度/2);
模拟
.force(“冲锋队”,冲锋队)
.力(“中心力”,中心力)
.力(“链接”,链接力)
;
//添加勾号说明:
模拟。on(“滴答声”,滴答声动作);
//为缩放添加包围组
var g=svg.append(“g”)
.attr(“类”、“一切”);
//为链接画线
var link=g.append(“g”)
.attr(“类”、“链接”)
.selectAll(“行”)
.数据(链接和数据)
.enter().append(“行”)
.attr(“笔划宽度”,2)
.风格(“笔划”,颜色);
//为节点绘制圆
var节点=g.append(“g”)
.attr(“类”、“节点”)
.selectAll(“圆圈”)
.数据(节点\数据)
.输入()
.附加(“圆圈”)
.attr(“r”,半径)
.attr(“填充”,圆形);
//添加拖动功能
var drag_handler=d3.drag()
。打开(“开始”,拖动开始)
.打开(“拖动”,拖动)
.打开(“结束”,拖动至“结束”);
拖拽处理器(节点);
//添加缩放功能
var zoom_handler=d3.zoom()
.打开(“缩放”,缩放动作);
缩放处理程序(svg);
/**功能**/
//函数选择我们拥有的颜色圈
//让我们为雄性返回蓝色,为雌性返回红色
函数圈颜色(d){
我的颜色
开关(d.实体){
案例“PO”:my_color=“black”;中断;
案例“PY”:my_color=“青色”中断;
案例“TK”:my_color=“blue”;中断;
案例“UL”:my_color=“green”;中断;
案例“VTA”:my_color=“green”;中断;
案例“BA”:my_color=“青色”;中断;
案例“X”:my_color=“grey”;中断;
}
返回我的颜色
}
//用于选择线条颜色和厚度的函数
//如果链接类型为“A”,则返回绿色
//如果链接类型为“E”,则返回红色
功能链接颜色(d){
如果(d.type==“A”){
返回“绿色”;
}否则{
返回“红色”;
}
}
//拖动函数
//d是节点
函数拖动_开始(d){
如果(!d3.event.active)simulation.alphaTarget(0.3.restart();
d、 fx=d.x;
d、 fy