【D3.js数据可视化系列教程】(二十四)--力导向图

力导向图(可拖动)

  1. 数据格式

定义节点和连接对象数组。

【司机提示】

  • nodes和edges是必备的两个属性。
  • nodes中的数据是一个表示节点的对象数组;
  • edges是一个表示边的对象数组,其中source和target子属性是必备的,其值代表了nodes数组中的索引。
  • 节点和边数组都可以有额外的属性。
var dataset={
    nodes:[//节点
      { name:"Adam"},
      { name:"Bob"},
      { name:"Carride"},
      { name:"Donovan"},
      { name:"Edward"},
      { name:"Felicity"},
      { name:"George"},
      { name:"Hannah"},
      { name:"Iris"},
      { name:"Jerry"} 
    ],
    edges:[//边
      { source:0,target:1,weight:1,color:1},
      { source:0,target:2,weight:3,color:4},
      { source:0,target:3,weight:4,color:6},
      { source:0,target:4,weight:6,color:65},
      { source:1,target:5,weight:3,color:76},
      { source:2,target:5,weight:8,color:879},
      { source:2,target:5,weight:7,color:989},
      { source:3,target:4,weight:9,color:643},
      { source:5,target:8,weight:1,color:54},
      { source:5,target:9,weight:3,color:54}, 
      { source:6,target:7,weight:4,color:45},
      { source:7,target:8,weight:0,color:43},
      { source:2,target:8,weight:8,color:243},
      { source:3,target:8,weight:1,color:43},
      { source:5,target:8,weight:5,color:13},
      { source:6,target:8,weight:3,color:351},
      { source:8,target:9,weight:4,color:1}
   ]
};

  2. 力布局

转化数据为适合生成力导向图的对象数组

var force=d3.layout.force()
    .nodes(dataset.nodes)// 加载节点数据
    .links(dataset.edges)// 加载边数据
    .size([w,h])// 设置有效空间的大小
    .linkDistance(50)// 连线的长度
    .charge(-200)// 负电荷量,相互排斥设置的负值越大越排斥
    .start();// 启用力布局

  3. 画线

创建作为连线的svg直线

var edges=svg.selectAll("line")
    .data(dataset.edges)
    .enter()
    .append("line")
    .style("stroke",function(d){// 设置线的颜色
        return colors(d.color);
    })
    .style("stroke-width",function(d,i){// 设置线的宽度
        return d.weight;
    });

  4. 画点

创建作为连线的svg圆形

var nodes=svg.selectAll("circle")
    .data(dataset.nodes)
    .enter()
    .append("circle")
    .attr("r",function(d){// 设置圆点的半径,圆点的度越大weight属性值越大,可以对其做一点数学变换
        return Math.log(d.weight)*10;
    })
    .style("fill",function(d){
        return colors(d.weight*d.weight*d.weight);
    })
    .call(force.drag);//可以拖动 

  5. 节拍

每个节拍力布局会重新模拟一次,直到自动收敛。

force.on("tick",function(){
    // 更新连线坐标
    edges.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;
    });

    // 更新节点坐标
    nodes.attr("cx",function(d){
        return d.x;
    })
    .attr("cy",function(d){
        return d.y;
    });

})

  6. 完整代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>testD3-22-force.html</title>
    <script type="text/javascript" src="d3.js"></script>
    <style type="text/css">
    </style>
</head>
<body>
<script type="text/javascript">
var h=300;
var w=300;
// 颜色函数
var colors=d3.scale.category20()//创建序数比例尺和包括20中颜色的输出范围

//(1)定义节点和联系对象数组
var dataset={
    nodes:[//节点
        { name:"Adam"},
        { name:"Bob"},
        { name:"Carride"},
        { name:"Donovan"},
        { name:"Edward"},
        { name:"Felicity"},
        { name:"George"},
        { name:"Hannah"},
        { name:"Iris"},
        { name:"Jerry"} 
    ],
    edges:[//边
        { source:0,target:1,weight:1,color:1},
        { source:0,target:2,weight:3,color:4},
        { source:0,target:3,weight:4,color:6},
        { source:0,target:4,weight:6,color:65},
        { source:1,target:5,weight:3,color:76},
        { source:2,target:5,weight:8,color:879},
        { source:2,target:5,weight:7,color:989},
        { source:3,target:4,weight:9,color:643},
        { source:5,target:8,weight:1,color:54},
        { source:5,target:9,weight:3,color:54}, 
        { source:6,target:7,weight:4,color:45},
        { source:7,target:8,weight:0,color:43},
        { source:2,target:8,weight:8,color:243},
        { source:3,target:8,weight:1,color:43},
        { source:5,target:8,weight:5,color:13},
        { source:6,target:8,weight:3,color:351},
        { source:8,target:9,weight:4,color:1}
    ]
};

//(2)转化数据为适合生成力导向图的对象数组
var force=d3.layout.force()
    .nodes(dataset.nodes)//加载节点数据
    .links(dataset.edges)//加载边数据
    .size([w,h])//设置有效空间的大小
    .linkDistance(50)//连线的长度
    .charge(-200)//负电荷量,相互排斥设置的负值越大越排斥
    .start();//设置生效

var svg=d3.select("body")
    .append("svg")
    .attr("width",w)
    .attr("height",h);

//(3)创建作为连线的svg直线
var edges=svg.selectAll("line")
    .data(dataset.edges)
    .enter()
    .append("line")
    .style("stroke",function(d){//  设置线的颜色
        return colors(d.color);
    })
    .style("stroke-width",function(d,i){//设置线的宽度
        return d.weight;
    });

//(4) 创建作为连线的svg圆形
var nodes=svg.selectAll("circle")
    .data(dataset.nodes)
    .enter()
    .append("circle")
    .attr("r",function(d){//设置圆点的半径,圆点的度越大weight属性值越大,可以对其做一点数学变换
        return Math.log(d.weight)*10;
    })
    .style("fill",function(d){
        return colors(d.weight*d.weight*d.weight);
    })
    .call(force.drag);//可以拖动

 //(5)打点更新,没有的话就显示不出来了
force.on("tick",function(){
    //边
    edges.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;
    });

    //节点
    nodes.attr("cx",function(d){
        return d.x;
    })
    .attr("cy",function(d){
        return d.y;
    });

})
</script>

</body>
</html>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值