D3.js 实现这种图形需要哪些概念和技术

D3.js 实现这种图形需要哪些概念和技术,d3.js,graph-theory,D3.js,Graph Theory,我想画一幅动态的视觉效果图,展示某些功能块是如何相互作用的。我很难定义我需要什么样的图形,以及什么(如果有的话)d3布局函数最适合开始使用。我甚至不确定我的示例是否属于图形的定义范围 总体思路是将一组函数及其输入和输出可视化。它以一组输入开始,以一组输出结束。中间有几个函数,每个函数接受输入并生成一个或多个输出。每个输出可作为一个或多个功能的输入。因此,每条边/线表示一个输出被传输到一个函数作为输入(并且是单向的) 我不是在寻找代码中的答案,而是要了解我需要从哪些概念开始。图像可能有问题,无法

我想画一幅动态的视觉效果图,展示某些功能块是如何相互作用的。我很难定义我需要什么样的图形,以及什么(如果有的话)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