• 【 D3.js 高级系列 — 2.0 】 机械图 + 人物关系图


    机械图(力路线图)结合老百姓的关系图中的生活,这是更有趣。

    本文将以此为证据,所列的如何图插入外部的图像和文字的力学。

    在【第 9.2 章】中制作了一个最简单的力学图。其后有非常多朋友有疑问,基本的问题包含:

    • 怎样在小球旁插入文字
    • 怎样将小球换为别的图形
    • 怎样插入图片
    • 怎样限制小球运动的边界

    本文将对以上问题依次做出讲解。当中前三点是 SVG 元素的问题。和 D3 无多大关联。

    1. SVG 图片

    SVG 的图片元素的具体讲解可看【官方文档-图片】。通常,我们仅仅须要使用到图片元素的五个属性就够了。

    <image xlink:href="image.png" x="200" y="200" width="100" height="100"></image>

    当中:

    • xlink:href - 图片名称或图片网址
    • x - 图片坐上角 x 坐标
    • y - 图片坐上角 y 坐标
    • width - 图片宽度
    • height- 图片高度

    在 D3 中插入图片,代码形如:

    svg.selectAll("image")
    	.data(dataset)
    	.enter()
    	.append("image")
    	.attr("x",200)
    	.attr("y",200)
    	.attr("width",100)
    	.attr("height",100)
    	.attr("xlink:href","image.png");

    2. SVG 文本

    SVG 的文本元素和图片类似,具体属性见【官方文档-文本】。

    <text x="250" y="150" dx="10" dy="10" font-family="Verdana" font-size="55" fill="blue" >Hello</text>

    当中:

    • x - 文本 x 坐标
    • y - 文本 y 坐标
    • dx- x 轴方向的文本平移量
    • dy- y 轴方向的文本平移量
    • font-family - 字体
    • font-size - 字体大小
    • fill - 字体颜色

    在 D3 中插入文本,代码形如:

    svg.selectAll("text")
    	.data(dataset)
    	.enter()
    	.append("text")
    	.attr("x",250)
    	.attr("y",150)
    	.attr("dx",10)
    	.attr("dy",10)
    	.text("Hello");
     

    3. 源文件

    接下来制作力学图的源文件。本次将数据写入 JSON 文件里。

    呵呵。借用一下【仙剑4】的人物。本人也是个仙剑迷,期待15年7月【仙剑6】的上市。

    {
    "nodes":[
    { "name": "云天河"   , "image" : "tianhe.png" },
    { "name": "韩菱纱"   , "image" : "lingsha.png" },
    { "name": "柳梦璃"   , "image" : "mengli.png" },
    { "name": "慕容紫英" , "image" : "ziying.png" }
    ],
    "edges":[
    { "source": 0 , "target": 1 , "relation":"挚友" },
    { "source": 0 , "target": 2 , "relation":"挚友" },
    { "source": 0 , "target": 3 , "relation":"挚友" }
    ]
    }

    如上,在 JSON 文件里加入数据。再将图片文件与 JSON 文件放于同一文件夹下就可以(放哪都行,最主要是看程序中是怎样实现的)。

    4. 力学图

    4.1 读入文件

    读入 JSON 文件,这点应该非常熟了吧。不然能够先看看【第 9.4 章】。

    d3.json("relation.json",function(error,root){
    			
    			if( error ){
    				return console.log(error);
    			}
    			console.log(root);
    }

    4.2 定义力学图的布局

    力学图的 Layout(布局)例如以下:

    			var force = d3.layout.force()
    							.nodes(root.nodes)
    							.links(root.edges)
    							.size([width,height])
    							.linkDistance(200)
    							.charge(-1500)
    							.start();

    当中 linkDistance 是结点间的距离, charge 是定义结点间是吸引(值为正)还是相互排斥(值为负),值越大力越强。

    4.3 绘制连接线

    绘制结点之间的连接线的代码例如以下:

    			var edges_line = svg.selectAll("line")
    								.data(root.edges)
    								.enter()
    								.append("line")
    								.style("stroke","#ccc")
    								.style("stroke-width",1);
    								
    			var edges_text = svg.selectAll(".linetext")
    								.data(root.edges)
    								.enter()
    								.append("text")
    								.attr("class","linetext")
    								.text(function(d){
    									return d.relation;
    								});

    当中,第 1 - 6 行:绘制直线

    第 8 - 15 行:绘制直线上的文字

    直线上文字的样式为:

    .linetext {
    	font-size: 12px ;
    	font-family: SimSun;
    	fill:#0000FF;
    	fill-opacity:0.0;
    }

    fill-opacity 是透明度,0表示全然透明,1表示全然不透明。这里是0。表示初始状态下不显示。

    4.4 绘制结点

    绘制结点的图片和文字:

    			var nodes_img = svg.selectAll("image")
    								.data(root.nodes)
    								.enter()
    								.append("image")
    								.attr("width",img_w)
    								.attr("height",img_h)
    								.attr("xlink:href",function(d){
    									return d.image;
    								})
    								.on("mouseover",function(d,i){
    									d.show = true;
    								})
    								.on("mouseout",function(d,i){
    									d.show = false;
    								})
    								.call(force.drag);
    			
    			var text_dx = -20;
    			var text_dy = 20;
    			
    			var nodes_text = svg.selectAll(".nodetext")
    								.data(root.nodes)
    								.enter()
    								.append("text")
    								.attr("class","nodetext")
    								.attr("dx",text_dx)
    								.attr("dy",text_dy)
    								.text(function(d){
    									return d.name;
    								});

    第 1 - 16 行:绘制图片

    第 10 - 15 行:当鼠标移到图片上时。显示与此结点想关联的连接线上的文字。在这里仅仅是对 d.show 进行布尔型赋值。在后面更新时会用到这个值。

    第 21 - 30 行:绘制图片下方的文字

    4.5 更新

    让力学图不断更新,使用 force.on("tick",function(){ }),表示每一步更新都调用 function 函数。

    			force.on("tick", function(){
    				
    				//限制结点的边界
    				root.nodes.forEach(function(d,i){
    					d.x = d.x - img_w/2 < 0     ?

    img_w/2 : d.x ; d.x = d.x + img_w/2 > width ? width - img_w/2 : d.x ; d.y = d.y - img_h/2 < 0 ?

    img_h/2 : d.y ; d.y = d.y + img_h/2 + text_dy > height ? height - img_h/2 - text_dy : d.y ; }); //更新连接线的位置 edges_line.attr("x1",function(d){ return d.source.x; }); edges_line.attr("y1",function(d){ return d.source.y; }); edges_line.attr("x2",function(d){ return d.target.x; }); edges_line.attr("y2",function(d){ return d.target.y; }); //更新连接线上文字的位置 edges_text.attr("x",function(d){ return (d.source.x + d.target.x) / 2 ; }); edges_text.attr("y",function(d){ return (d.source.y + d.target.y) / 2 ; }); //是否绘制连接线上的文字 edges_text.style("fill-opacity",function(d){ return d.source.show || d.target.show ? 1.0 : 0.0 ; }); //更新结点图片和文字 nodes_img.attr("x",function(d){ return d.x - img_w/2; }); nodes_img.attr("y",function(d){ return d.y - img_h/2; }); nodes_text.attr("x",function(d){ return d.x }); nodes_text.attr("y",function(d){ return d.y + img_w/2; }); });

     

    5. 结果

    结果例如以下:


    可点击以下的地址,右键点浏览器查看完整代码:http://www.ourd3js.com/demo/J-2.0/relationforce.html

    6. 结束语

    在【入门系列】中,疑问最多的是【树状图】,本想先解决问题的。可是因为我也有些问题还没想明确。所以先写本文这个较easy的。接下来还将有几篇关于力学图的,树状图的整理要略微拖一段时间。

    谢谢阅读。


    文档信息


  • 相关阅读:
    AIMS 2013中的性能报告工具不能运行的解决办法
    读懂AIMS 2013中的性能分析报告
    在线研讨会网络视频讲座 方案设计利器Autodesk Infrastructure Modeler 2013
    Using New Profiling API to Analyze Performance of AIMS 2013
    Map 3D 2013 新功能和新API WebCast视频下载
    为Autodesk Infrastructure Map Server(AIMS) Mobile Viewer创建自定义控件
    ADN新开了云计算Cloud和移动计算Mobile相关技术的博客
    JavaScript修改css样式style
    文本编辑神器awk
    jquery 开发总结1
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5041083.html
Copyright © 2020-2023  润新知