1

力学图(也称为导向图,也有叫网络拓补图的,反正就是通过排斥得到关系远近的结构)在社交网络研究、信息传播途径等群体关系研究中应用非常广泛,它可以直观地反映群体与群体之间联系的渠道、交集多少,群体内部成员的联系强度等。

效果图

请输入图片描述

力学参数

width:500, height:600, distance(自动计算), linkStrength:2, charge: (-10 / k)*1.5 , gravity: 100 * k

这里的k 有个最优计算:var k = Math.sqrt(nodes.length / (width * height));

构图(d3.layout)——力学(Force)的API说明

d3.layout.force -节点(node)基于物理模拟的位置连接。
force.on - 监听布局位置的变化。(仅支持"start","step","end"三种事件)
force.nodes - 获得或设置布局中的节点(node)阵列组。
force.links - 获得或设置布局中节点间的连接(Link)阵列组。.
force.size - 获取或设置布局的 宽 和 高 的大小.
force.linkDistance - 获取或设置节点间的连接线距离.
force.linkStrength - 获取或设置节点间的连接强度.
force.friction - 获取或设置摩擦系数.
force.charge - 获取或设置节点的电荷数.(电荷数决定结点是互相排斥还是吸引)
force.gravity - 获取或设置节点的引力强度.
force.theta - 获取或设置电荷间互相作用的强度.
force.start - 开启或恢复结点间的位置影响.
force.resume - 设置冷却系数为0.1,并重新调用start()函数.
force.stop - 立刻终止结点间的位置影响.(等同于将冷却系数设置为0)
force.alpha - 获取或设置布局的冷却系数.(冷却系数为0时,节点间不再互相影响)
force.tick - 让布局运行到下一步.
force.drag - 获取当前布局的拖拽对象实例以便进一步绑定处理函数.

示例代码:
http://jsbin.com/huroramu/1/edit?html,css,js,output

增加鼠标移动上去的高亮效果

示例代码:
http://jsbin.com/huroramu/2/edit?html,css,js,output
请输入图片描述

删除node, 删除path

function findLinkIndex(relation_id){
  var links = force.links();

  for (var i in links) {
     if (links[i]['relation_id']==relation_id ) return i;
  }

  return -1;
}

function removeLink(d){
   var nodes = force.nodes();
   var links = force.links();

   // 去掉link
   var index = findLinkIndex(d.relation_id);
   links.splice(index,1);

   force.nodes(nodes);
   force.links(links);

   force.start();

   $(".link").eq(index).remove();
}

function findNodeIndex(module_id){
  var nodes=force.nodes();

    for (var i in nodes){
        if (nodes[i]['module_id']==module_id ) return i;
    }
    return -1;
}

function removeNode(d){
   var nodes = force.nodes();
   var links = force.links();

    // 去掉node
    var index = findNodeIndex(d.module_id);
    nodes.splice(index,1);

    force.nodes(nodes);
    force.links(links);

    force.start();

    $(".node").eq(index).remove();

}

点击效果或右键点击效果

path.on("contextmenu",contextMenuLinks);

function contextMenuLinks (data,index){
    var position = d3.mouse(this);

    var x, y;

    if (d3.event.pageX || d3.event.pageY) {
        var x = d3.event.pageX;
        var y = d3.event.pageY;
    } else if (d3.event.clientX || d3.event.clientY) {
        var x = d3.event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
        var y = d3.event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }

    d3.select('#relationMenu')
        .style('position', 'absolute')
        .style('left', x + "px")
        .style('top', y + "px")
        .style('display', 'block')
        .on('mouseleave', function() {
             d3.select('#relationMenu').style('display', 'none');
        });
   d3.event.preventDefault();
}

额外补充

  1. 求数组最大值
    Math.max.apply(null, array);

  2. 按给定范围内 比例求出大小
    范围最大值max,
    范围最小值min,
    当前的值x,
    当前组的最大值currentMax
    min+(max-min)*x/currentMax;

范围值是12(最小值)~30(最大值)
var arr = [1,2,3,4,5];
求4 的比例值
var max = Math.max.apply(null, arr);//5
12+(30-12)*(4/5)


小渝人儿
1.1k 声望849 粉丝

前端工程师


引用和评论

0 条评论