• 软件工程实践第五次作业


    软件工程第五次作业————结对作业

    第二次结对作业————实现学术家族树

    一、结对信息 传送门

    博客地址:
    Yuqiancha 学号:061700232
    博客作业地址:https://www.cnblogs.com/spongebobyjh/p/11706182.html
    zhazhahui 学号:131700114
    博客作业地址:https://www.cnblogs.com/booob/p/11706181.html
    Github地址:
    (https://github.com/54zhazhahui/131700114-061700232)

    二、具体分工

    Yuqiancha:部分代码,测试
    zhazhahui:部分代码,测试

    PSP表格

    PSP Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    Planning 计划 30 40
    Estimate 估计这个任务需要多少时间 30 40
    Development 开发 150 120
    Analysis 需求分析 (包括学习新技术) 950 750
    Design Spec 生成设计文档 30 30
    Design Review 设计复审 30 60
    Coding Standard 代码规范 (为目前的开发制定合适的规范) 60 30
    Design 具体设计 60 90
    Coding 具体编码 480 600
    Code Review 代码复审 60 90
    Test 测试(自我测试,修改代码,提交修改) 180 240
    Reporting 报告 30 30
    Test Repor 测试报告 60 60
    Size Measurement 计算工作量 10 60
    Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 30 60
    合计 2200 2300
    ###四、解题思路描述与设计实现说明 对我们来说这次这次实验的难度是比较大的,两个人都没有接触过前端知识,完全的零基础。在这种情况下,我们还是在网上认真学习了很多。但是时间真的是太短了,我们在短时间功利的学习了一些知识以后,在基于网上d3上面的代码,完成了这次实验。 首先代码是html,进行数据输入以后,一行一行的截取,然后找里面的关键字那就先用split()把整个输入内容按照那个"换行符"分组,如果是按顺序输入直接用就行,如果不是,就按照关键字找,遍历list数组,在内容里面找关键字,然后,比如遍历数组,找第几个里面有"导师",找到之后创建导师数组,把冒号之后的内容再按"顿号分组",把他们放进导师数组。大概就是这样的做法。 **主要代码** ```
    <script>
    d3.select("body").style("background-image", "url(http://bbs.212300.com/data/attachment/forum/201910/14/163604wb2ehf9eyhzrbyet.jpg)");
    	function GetTextAreaValue()
    	{ 
    		var str=document.all.text.value;
    		arrstr=str.split('
    ');
    		var next=new Map;var level=new Map;
    		var f=new Map;var x=["博士生", "硕士生", "本科生"];
    		var map=new Map();var vi=[];
    		map["导师"]=4;map["博士生"]=3;map["硕士生"]=2;map["本科生"]=1;
    		for(var i=0;i<arrstr.length;)
    		{
    			var j;
    			for(j=i;j<arrstr.length;j++)
    			{
    				if(arrstr[j]=="")
    				{
    					break;
    				}
    			}
    			var item=arrstr[i].split(':');
    			var tp=item[1];
    			next[tp]=[];
    			level[tp]=item[0];
    			vi.push(tp);
    			for(var l=i+1;l<j;l++)
    			{
    				for(var val of x)
    				{
    					if(arrstr[l].indexOf(val)!=-1)
    					{
    						var item1=arrstr[l].split(':');
    						var z=item1[0]+tp;
    						next[tp].push(z);
    						level[z]=val;
    						next[z]=[];
    						f[z]=1;
    						vi.push(z);
    						break;
    					}
    				}
    				
    				var s=item1[1].split('、');
    				for(var val of s)
    				{
    					console.log(val);
    					
    						next[z].push(val);
    						f[val]=1;
    						level[val]=item1[0];
    						vi.push(val);																
    				}
    			}
    			i=j+1;
    			
    		}
    		for(var val of vi)
    		{
    			
    			if(f[val]==null)
    			{
    				var root=dfs(val,-1);
    			}
    		}
    				function dfs(u,fa)
    		{
    			var ss;
    			ss={};
    			ss.name=u;
    			ss.children=[];
    			var v=next[u];
    			if(v==null)
    			{
    				return ss;
    			}
    			for(var i=0;i<v.length;i++)
    			{
    				ss.children.push(dfs(v[i],u));
    			}
    			if(u.indexOf(fa)!=-1)
    			{
    				var t=u.substring(0, u.indexOf(fa));
    				ss.name=t;
    			}
    			return ss;
    		}
    		var svg; 
    		d3.selectAll("svg").remove();
    		var margin = {top: 50, right: 20, bottom: 20, left: 20},
    							width = 1500 - margin.right - margin.left,
    							height = 1500 - margin.top - margin.bottom;
    
    			
    			 
    				var i = 0,
    				duration = 500;//过渡延迟时间
    				
    			 
    			var tree = d3.layout.tree()//创建一个树布局
    				.size([height, width]);
    			 
    			var diagonal = d3.svg.diagonal()
    				.projection(function(d) { return [d.x, d.y]; });//创建新的斜线生成器
    			 
    			 
    			// Setup zoom and pan
    			var zoom = d3.behavior.zoom()
    				.scaleExtent([.1,1])
    				.on('zoom', function(){
    					svg.attr("transform", "translate(" + d3.event.translate + ") scale(" + d3.event.scale + ")");
    			});
    			 
    			//声明与定义画布属性
    			svg = d3.select("body").append("svg")
    				.attr("width", width + margin.right + margin.left)
    				.attr("height", height + margin.top + margin.bottom)
    				.call(zoom)
    				.append("g")
    				.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    			 
    			
    			//treeData为上边定义的节点属性
    			root.x0 = height / 2;
    			root.y0 = 0;
    			 
    			update(root);
    			 
    			d3.select(self.frameElement).style("height", "1600px");
    			 
    			function update(source) {
    			 
    			  // Compute the new tree layout.计算新树图的布局
    			  var nodes = tree.nodes(root).reverse(),
    				  links = tree.links(nodes);
    			 
    			  // Normalize for fixed-depth.设置y坐标点,每层占250px
    			  nodes.forEach(function(d) { d.y = d.depth * 250; });
    			 
    			  // Update the nodes…每个node对应一个group
    			  var node = svg.selectAll("g.node")
    				  .data(nodes, function(d) { return d.id || (d.id = ++i); });//data():绑定一个数组到选择集上,数组的各项值分别与选择集的各元素绑定
    			 
    			  // Enter any new nodes at the parent's previous position.新增节点数据集,设置位置
    			  var nodeEnter = node.enter().append("g")  //在 svg 中添加一个g,g是 svg 中的一个属性,是 group 的意思,它表示一组什么东西,如一组 lines , rects ,circles 其实坐标轴就是由这些东西构成的。
    				  .attr("class", "node") //attr设置html属性,style设置css属性
    				  .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
    				  .on("click", click);
    				  nodeEnter.append("rect")
    				.attr("x",-20)
    				.attr("y", -10)       
    				.attr("width",30)      
    				.attr("height",30)
    				.attr("rx",10)
    				.attr("fill", function(d){
    				//创建人物图片
    				var defs = svg.append("defs").attr("id", "imgdefs")
    				var catpattern = defs.append("pattern")
    										.attr("id", "pat")
    										.attr("height", 1)
    										.attr("width", 1)
    										.attr("patternContentUnits","objectBoundingBox")
    				catpattern.append("image")
    						.attr("width", "1.4")
    						.attr("height", "1")
    						.attr("xlink:href", "timg.jpg")
    				return "url(#pat)";
    			})
    				//  .style("fill", "#dff0e7");d 代表数据,也就是与某元素绑定的数据。
    			 
    			  nodeEnter.append("text")
    				.attr("x", function(d) { return d.children || d._children ? 10 : 10; })
    				.attr("dy", "40")
    				.attr("text-anchor", "middle")
    				.text(function(d) { return d.name; })
    				.style("fill", "#2dbb8a")
    				.style("fill-opacity", 1);
    			  // Transition nodes to their new position.将节点过渡到一个新的位置-----主要是针对节点过渡过程中的过渡效果
    			  //node就是保留的数据集,为原来数据的图形添加过渡动画。首先是整个组的位置
    			  var nodeUpdate = node.transition()  //开始一个动画过渡
    				  .duration(duration)  //过渡延迟时间,此处主要设置的是圆圈节点随斜线的过渡延迟
    				  .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });//YES
    			 
    			 
    			  // Transition exiting nodes to the parent's new position.过渡现有的节点到父母的新位置。
    			  //最后处理消失的数据,添加消失动画
    			  var nodeExit = node.exit().transition()
    				  .duration(duration)
    				  .attr("transform", function(d) { return "translate(" + source.x + "," + source.y + ")"; })//YES
    				  .remove();
    			 
    			  // Update the links…线操作相关
    			 
    			  //再处理连线集合
    			  var link = svg.selectAll("path.link")
    				  .data(links, function(d) { return d.target.id; });
    			 
    			 
    			  // Enter any new links at the parent's previous position.
    			  //添加新的连线
    			  link.enter().insert("path", "g")
    				  .attr("class", "link")
    				  .attr("d", function(d) {
    					var o = {y: source.x0, x: source.y0};//YES
    					return diagonal({source: o, target: o});  //diagonal - 生成一个二维贝塞尔连接器, 用于节点连接图.
    				  })
    				.attr('marker-end', 'url(#arrow)');
    			 
    			  // Transition links to their new position.将斜线过渡到新的位置
    			  //保留的连线添加过渡动画
    			  link.transition()
    				  .duration(duration)
    				  .attr("d", diagonal);
    			 
    			  // Transition exiting nodes to the parent's new position.过渡现有的斜线到父母的新位置。
    			  //消失的连线添加过渡动画
    			  link.exit().transition()
    				  .duration(duration)
    				  .attr("d", function(d) {
    					var o = {x: source.x, y: source.y};//NO
    					return diagonal({source: o, target: o});
    				  })
    				  .remove();
    			 
    			  // Stash the old positions for transition.将旧的斜线过渡效果隐藏
    			  nodes.forEach(function(d) {
    				d.x0 = d.y;
    				d.y0 = d.x;
    			  });
    			}
    			 
    			//定义一个将某节点折叠的函数
    			// Toggle children on click.切换子节点事件
    			function click(d) {
    			  if (d.children) {
    				d._children = d.children;
    				d.children = null;
    			  } else {
    				d.children = d._children;
    				d._children = null;
    			  }
    			  update(d);
    			}
    		}	
       
    </script>
    
    ```

    五.附加特点设计与展示

    六、目录说明和使用说明

    七、单元测试

    八、Github的代码签入记录

    九.遇到的代码模块异常或结对困难及解决方法

    遇到的主要问题就是在处理输入数据时的问题。刚开始数据很难处理,函数运用不准确。
    解决办法:在网上学习了很多方法解决。真的是太难了。

    十、评价队友

    Yuqiancha:这次实验真的太难了(大声哭),队友也很给力,在我们两个不懈努力(濒临崩溃)的情况下,还是大概完成了。

    zhazhahui:队友比较给力,我之前对前端完全不了解,都是队友带我的。

  • 相关阅读:
    关于排序--sort()和qsort()使用
    UVA--147 Dollars(完全背包)
    UVA--674 Coin Change(完全背包)
    HDU--1203 I NEED A OFFER!(01背包)
    编程中关于无穷大的设定技巧
    HDU--2126 Buy the souvenirs(二维01背包)
    HDU--2639 Bone Collector II(01背包)
    MySQL中的group_concat函数
    Redis监控
    JAVA中的代理模式
  • 原文地址:https://www.cnblogs.com/booob/p/11706181.html
Copyright © 2020-2023  润新知