-
- 分工:0317:写代码,写博客 莫得东西:收集素材,设计框架
- PSP:
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟)| 实际耗时(分钟) - | :-: | :-: |:-:|
Planning | 计划 | 30 | 30
Estimate | 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 600 | 550 |
Analysis | 需求分析 (包括学习新技术) | 800 | 850 |
Design Spec | 生成设计文档 | 30 | 30 |
Design Review | 设计复审 | 30 | 30 |
Coding Standard| 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
Design | 具体设计 | 100 | 110 |
Coding| 具体编码 | 800 | 900 |
Code Review | 代码复审 | 60 | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 60 | 50 |
Reporting | 报告 | 60 | 60 |
Test Report | 测试报告 | 30 | 30 |
Size Measurement | 计算工作量 | 30 | 30 |
Postmortem & Process Improvement Plan| 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | | 2720 | 2820 | - 解题思路:
- 代码组织与内部实现设计:代码就是html,首先进行数据处理,然后根据节点和边进行建图。从根节点通过d3框架渲染树形结构。
- 关键代码和流程图:
- 代码:
- 输入:
- 读取数据:var str=document.all.text.value;//读取数据
- 数据处理:
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 = 2300 - margin.right - margin.left, height = 2300 - margin.top - margin.bottom; s var i = 0, duration = 750;//过渡延迟时间 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 + ")"); //定义节点属性 root.x0 = height / 2; root.y0 = 0; update(root); d3.select(self.frameElement).style("height", "1600px"); function update(source) { //计算新树图的布局 var nodes = tree.nodes(root).reverse(), links = tree.links(nodes); //设置y坐标点 nodes.forEach(function(d) { d.y = d.depth * 250; }); var node = svg.selectAll("g.node") .data(nodes, function(d) { return d.id || (d.id = ++i); }); //新增节点数据集,设置位置 var nodeEnter = node.enter().append("g") .attr("class", "node") //attr设置html属性,style设置css属性 .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }) .on("click", click); //添加连接点 .attr("x",-20) .attr("y", -15) //结点位置 .attr("width",50) //矩形宽高 .attr("height",50) .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", "http://b-ssl.duitang.com/uploads/item/201403/23/20140323215226_kFcax.jpeg") //图片地址 return "url(#pat)"; }) nodeEnter.append("text") .attr("x", function(d) { return d.children || d._children ? 13 : 13; }) .attr("dy", "50") .attr("text-anchor", "middle") .text(function(d) { return d.name; }) .style("fill", "#2dbb8a") .style("fill-opacity", 1); //将节点过渡到一个新的位置 //node就是保留的数据集,为原来数据的图形添加过渡动画 var nodeUpdate = node.transition() //开始一个动画过渡 .duration(duration) //过渡延迟时间 .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });//YES //过渡现有的节点到父母的新位置。 //处理数据,添加消失动画 var nodeExit = node.exit().transition() .duration(duration) .attr("transform", function(d) { return "translate(" + source.x + "," + source.y + ")"; })//YES .remove(); //再处理连线集合 var link = svg.selectAll("path.link") .data(links, function(d) { return d.target.id; }); //添加新的连线 link.enter().insert("path", "g") .attr("class", "link") .attr("d", function(d) { var o = {y: source.x0, x: source.y0}; return diagonal({source: o, target: o}); //生成一个连接器, 用于节点连接图. }) .attr('marker-end', 'url(#arrow)'); //将斜线过渡到新的位置 //添加过渡动画 link.transition() .duration(duration) .attr("d", diagonal); //过渡现有的斜线到父母的新位置。 //添加过渡动画 link.exit().transition() .duration(duration) .attr("d", function(d) { var o = {x: source.x, y: source.y}; return diagonal({source: o, target: o}); }) .remove(); //将旧的斜线过渡效果隐藏 nodes.forEach(function(d) { d.x0 = d.y; d.y0 = d.x; }); } //切换子节点事件 function click(d) { if (d.children) { d._children = d.children; d.children = null; } else { d.children = d._children; d._children = null; } update(d); } }
- 代码:
- 创意:家族树中,可以通过点击节点头像使得此节点下面的子节点收起。
- 成果:
通过点击节点,博士生的子节点被隐藏起来。
- 成果:
- 问题及解决:
- 问题:两棵树无法共存操作,一旦共存就只能看,不能做到创意,刚开始无从入手,根本没有头绪。
- 行动:百度搜索、找前端相关视频学习、找其他同学问怎么做(这个最有用)。
- 解决:两颗树还是不会
- 收获:虽然没学到多少,但从百度和视频中也对前端有了一定的认识。还有独立学习的能力,以及可以制作一个简单的网页。
- 目录说明:
- 首先是框架,此次用的是d3框架,用的是直接包含网络的链接:
- 使用方面,直接下载我们Github中的家族树.html,打开方式选择谷歌浏览器即可进入,因为用的是包含网络的链接,所以不需要下载d3的文件,但是得能正常上网。
- 评价队友:
- 031702125:认真学习相关知识,分配任务后会很专注去做。
- 031702149:比较能利用现有资源,从网上或同学处学到东西。但是就是有时候太过马虎,考虑问题不会很细心。
软工第五次结对作业
猜你喜欢
转载自www.cnblogs.com/luosangpingcuo/p/11705808.html
今日推荐
周排行