d3力学图(force layout)更新
2015-12-16 22:24
525 查看
d3是javascript的一个可视化库,可以***很漂亮的表格等,其中有一个非常好玩的力学图,可以方便的进行拖拽等,但是关于更新的操作网上介绍的很少,下面介绍下关于力学图的更新,先看一个例子(http://example.codeboy.me/d3/force-layout.html,点击一次下图后可以直接按回车键添加):
csdn不能插入iframe,请点击上面链接查看。
绘制图形的方式基本上可以分为svg与canvas两种,两者各有优缺点,不对于以后屏幕越来越大,svg更加的有优势,并且svg可以很方便的进行事件交互。
下面看一下这个力学图具体实现:
更新部分只有
数据更新
力学图重新加载数据
追加对应的边与节点(enter)
去除无用的元素(remove)
执行
只要按照顺序进行,新增的节点等就可以很好的添加。
例子中有几点需要说明一下
d3的github(https://github.com/mbostock/d3/wiki/Gallery)上有很多的例子,大家可以找到自己喜欢的进行学习,同时也需要对svg有一定的学习,方便我们自己进行一些改进。
csdn不能插入iframe,请点击上面链接查看。
绘制图形的方式基本上可以分为svg与canvas两种,两者各有优缺点,不对于以后屏幕越来越大,svg更加的有优势,并且svg可以很方便的进行事件交互。
下面看一下这个力学图具体实现:
整体代码
[code]<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="css/bootstrap.min.css" rel="stylesheet"> <script src="js/jquery.min.js"></script> <script src="js/bootstrap.min.js"></script> <script src="js/layer/layer.min.js"></script> <script src="js/d3.min.js" charset="utf-8"></script> <title>d3 layout update</title> </head> <body style="height: 100%;"> <div class="container" style="padding-left: 0; width: 100%;"> <div id="svg"> </div> </div> <script> $(document).ready(function () { var height = document.body.clientHeight; var width = document.body.clientWidth; var nodes_data = [{'name': '0'}, {'name': '1'}, {'name': '2'}, {'name': '3'}, {'name': '4'}, {'name': '5'}, {'name': '6'}]; var edges_data = [{'source': 0, 'target': 1}, {'source': 0, 'target': 2}, {'source': 0, 'target': 3}, {'source': 0, 'target': 4}, {'source': 0, 'target': 5}, {'source': 0, 'target': 6}]; var color = d3.scale.category20(); var edgeWidth = 2; var r = 40; var svg = d3.select("#svg").append("svg") .attr("width", width) .attr("height", height); var force = d3.layout.force() .nodes(nodes_data) .links(edges_data) .size([width, height]) .linkDistance(200) .friction(0.8) .charge(-500) .start(); //边 var links = svg.selectAll("line") .data(edges_data) .enter() .append("line") .attr("marker-end", "url(#arrow)") .style("stroke", "#ccc") .style("stroke-width", edgeWidth); //节点 var nodes = svg.selectAll("circle") .data(nodes_data) .enter() .append("circle") .attr("r", r) .style("fill", function (d, i) { return color(i); }) .on("click", function (d, i) { if (i == 0) { update(); } }) .call(force.drag); //标签 var nodes_labels = svg.selectAll("text") .data(nodes_data) .enter() .append("text") .attr("dx", function (d, i) { return -16 * (nodes_data[i].name.length); }) .attr("dy", 5) .attr("fill", "#fff") .style("font-size", 16) .text(function (d, i) { if (i == 0) { return "点我"; } return ""; }); //运动刷新 force.on("tick", function (d) { links.attr("x1", function (d) { var distance = Math.sqrt((d.target.y - d.source.y) * (d.target.y - d.source.y) + (d.target.x - d.source.x) * (d.target.x - d.source.x)); var x_distance = (d.target.x - d.source.x) / distance * r; return d.source.x + x_distance; }).attr("y1", function (d) { var distance = Math.sqrt((d.target.y - d.source.y) * (d.target.y - d.source.y) + (d.target.x - d.source.x) * (d.target.x - d.source.x)); var y_distance = (d.target.y - d.source.y) / distance * r; return d.source.y + y_distance; }).attr("x2", function (d) { var distance = Math.sqrt((d.target.y - d.source.y) * (d.target.y - d.source.y) + (d.target.x - d.source.x) * (d.target.x - d.source.x)); var x_distance = (d.target.x - d.source.x) / distance * r; return d.target.x - x_distance; }).attr("y2", function (d) { var distance = Math.sqrt((d.target.y - d.source.y) * (d.target.y - d.source.y) + (d.target.x - d.source.x) * (d.target.x - d.source.x)); var y_distance = (d.target.y - d.source.y) / distance * r; return d.target.y - y_distance; }); nodes.attr("cx", function (d) { return d.x; }).attr("cy", function (d) { return d.y; }); nodes_labels.attr("x", function (d) { return d.x; }); nodes_labels.attr("y", function (d) { return d.y; }); }); //用于产生不同颜色的节点 var colorIndex = 8; //添加节点更新 function update() { nodes_data.push({'name': 'xxx'}); edges_data.push({'source': 0, 'target': nodes_data.length - 1}); links = links.data(force.links()); links.enter() .append("line") .style("stroke", "#ccc") .style("stroke-width", 2); links.exit().remove(); nodes = nodes.data(force.nodes()); nodes.enter().append("circle") .attr("r", 40) .style("fill", color(colorIndex++)) .call(force.drag); nodes.exit().remove(); force.start(); } //回车事件 $(document).keydown(function(e) { if(e.which == 13) { update(); } }); }); </script> </body> </html>
更新讲解
更新部分只有 update()函数,更新的操作分为以下
数据更新
力学图重新加载数据
追加对应的边与节点(enter)
去除无用的元素(remove)
执行
force.start()操作
只要按照顺序进行,新增的节点等就可以很好的添加。
例子说明
例子中有几点需要说明一下force.on("tick", function (d){...})中的计算用户绘制线条的时候只绘制两个圆之间的部分,当然这么做也便于添加箭头,也能较少一些其他的重叠操作。
var nodes_labels = svg.selectAll("text")中仅仅对第一个点进行了标注,用于提示点击操作,也可以对所有的点进行标注的。
总结
d3的github(https://github.com/mbostock/d3/wiki/Gallery)上有很多的例子,大家可以找到自己喜欢的进行学习,同时也需要对svg有一定的学习,方便我们自己进行一些改进。
相关文章推荐
- mac中使用终端生成RSA私钥和公钥文件
- 插件XAlign的使用
- 兼容性问题
- android 启动界面广告的显示
- JSP复习(一) 基础
- 比较时间和日期大小
- Linux kernel -页高速缓存和页回写 初探
- Stucts应用引起的OutOfMemoryError
- C++中mutable关键的学习
- red5下载链接
- makefile目标覆盖
- ANDROID设计招式之美--读书笔记
- 全屏显示一张图片,不显示滚动条
- [javase学习笔记]-6.2 类与对象的关系
- 高效开发iOS系列 -- 让Xcode的控制台支持LLDB类型的打印
- 正则表达式
- Mac OS X 10.10上以命令行模式使用GLWF3
- SQL 向上取整、向下取整、四舍五入取整的实例!round、rounddown、roundup
- input[type='submit']input[type='button']button等按钮在低版本的IE下面,去掉黑色边框的问题
- 插件VVDocumenter的使用