D3.JS训练题笔记3——(力导向图)

力导布局图:是一种用来呈现复杂关系网络的图表。在力导布局图中,系统中的每个节点都可以看成是一个放电粒子,粒子间存在某种斥力。同时,这些粒子间被它们之间的“边”所牵连,从而产生引力。系统中的粒子在斥力和引力的作用下,从随机无序的初态不断发生位移,逐渐趋于平衡有序的终态。


**

1.数据集

**
由nodes和edges两个数组组成,数组中的元素是一个个的对象。
nodes数组例如:

nodes代表节点的必要信息,name是结点的名字,size是用来表示节点的大小的值。(size可以不设置,只有name即可)

edges数组例如:
在这里插入图片描述
edges 表示的是节点之间是否连线,source是连线的起点,target是连线的终点,其中,nodes中对象的下标对应着source和target的值。

**

2.创建一个力导向图的模拟器

**

var forceSimulation = d3.forceSimulation()
                .force("link", d3.forceLink())
                .force("charge", d3.forceManyBody())
                .force("center", d3.forceCenter());

此时的数据还不可使用,需要使用forceSimulation生成节点和边的可用数据。

					//生成节点数据
                    forceSimulation.nodes(nodes)
                        .on("tick", ticked);
                    //生成边数据
                    forceSimulation.force("link")
                        .links(edges)
                        .distance(150)
                    //设置图形的中心位置
                    forceSimulation.force("center")
                        .x(w / 2)
                        .y(h / 2);
                    //在浏览器的控制台输出
                    console.log(nodes);
                    console.log(edges);

这时,输出的数据nodes和edges都发生了改变:
在这里插入图片描述
nodes数据多出了x,y和index值。
在这里插入图片描述
edges数据多出了vx,vy,x,y值。
力导向图的动效实现本质就是每一帧都重新渲染图中节点的位置(x,y), 节点的位置(x,y)是由节点上一帧所处的位置(x,y)+速度(vx,vy)所决定的。而速度就是通过力学模型所计算出来的。

**

3.绘制力导向图

**
绘制力导向图需要绘制三种图形元素:

  • line,线段,表示连线。
  • circle,圆,表示节点。
  • text,文字,描述节点信息。

**

					//绘制边
                    var links = g.append("g")
                        .selectAll("line")
                        .data(edges)
                        .enter()
                        .append("line")
                        .attr("stroke", function (d, i) {
                            return colorScale(2);   //边的颜色
                        })
                        .attr("stroke-width", 1);
                    //边上文字
                    var linksText = g.append("g")
                        .selectAll("text")
                        .data(edges)
                        .enter()
                        .append("text")
                        .text(function (d) {
                            return d.relation;
                        })
                    //建立用来放在每个节点和对应文字的分组<g>
                    var gs = g.selectAll(".circleText")
                        .data(nodes)
                        .enter()
                        .append("g")
                        .attr("transform", function (d, i) {
                            var cirX = d.x;
                            var cirY = d.y;
                            return "translate(" + cirX + "," + cirY + ")";
                        })
                        .call(d3.drag()
                            .on("start", started)
                            .on("drag", dragged)
                            .on("end", ended)
                        );

                    //绘制节点
                    gs.append("circle")
                        .attr("r", function (d, i) {    //圆圈半径
                            return d.size;
                        })
                        .attr("fill", function (d, i) {
                            return colorScale(d.size);
                        })
                    //文字
                    gs.append("text")
                        .attr("x", -25)
                        .attr("y", -5)
                        .attr("dy", 10)
                        .text(function (d) {
                            return d.name;
                        })

4.节点拖动事件监听

**
力导向图布局 force 有一个监听事件 tick。意为每进行到一个时刻,都要调用它的监听函数。以下为示例代码:

function ticked() {
                        links
                            .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; });

                        linksText
                            .attr("x", function (d) {
                                return (d.source.x + d.target.x) / 2;
                            })
                            .attr("y", function (d) {
                                return (d.source.y + d.target.y) / 2;
                            });

                        gs
                            .attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; });
                    }

效果展示:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值