2020软件工程作业05
学号 | 姓名 |
---|---|
20177599 | 胡宇 |
20177588 | 郭承宗 |
github地址:https://github.com/a2228618156/20177599-20177588
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框架,用的是直接包含网络的链接:
-
- 胡宇:认真学习相关知识,分配任务后会很专注去做。
- 郭承宗:比较能利用现有资源,从网上或同学处学到东西。但是就是有时候太过马虎,考虑问题不会很细心。