第4次作业-结对编程之实验室程序实现
这个作业属于哪个课程 | 软件工程2020秋学期 |
---|---|
这个作业要求在哪里 | [https://edu.cnblogs.com/campus/fzu/SE2020/homework/11277] |
这个作业的目标 | 学习HTML、CSS、JavaScript、框架使用等相关知识,根据题目要求实现学术家族树 |
学号 | 031802244、031802224 |
1.博客链接及GitHub项目地址
结对同学的博客链接:
学号 | 姓名 | 博客链接
--|:--😐--😐--:
031802244|张智和|[https://www.cnblogs.com/6028dog/]
031802224|欧文烨|[https://www.cnblogs.com/concorde/]
作业的博客链接:[https://edu.cnblogs.com/campus/fzu/SE2020/homework/11277]
GitHub项目地址:[https://github.com/zzHee/031802244-031802224]
2.具体分工:
031802244张智和:主要负责代码编写、测试、UI设计
031802224欧文烨:主要负责资料查找、博客编写、归纳总结
3.PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 20 |
Estimate | 估计这个任务需要多少时间 | 10 | 10 |
Development | 开发 | 1200 | 1440 |
Analysis | 需求分析 (包括学习新技术) | 480 | 500 |
Design Spec | 生成设计文档 | 20 | 20 |
Design Review | 设计复审 | 30 | 20 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 10 |
Design | 具体设计 | 50 | 90 |
Coding | 具体编码 | 480 | 600 |
Code Review | 代码复审 | 60 | 30 |
Test | 测试(自我测试,修改代码,提交修改) | 60 | 120 |
Reporting | 报告 | 60 | 80 |
Test Report | 测试报告 | 10 | 20 |
Size Measurement | 计算工作量 | 20 | 30 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 40 | 60 |
合计 | 1610 | 1950 |
4.解题思路描述与设计实现说明
解题思路
通过分析题目,我们可以知道大致的实现过程是这样的:首先我们需要在web页面提供一个文本框,然后在文本框中输入给定的师生信息和个人技能信息,接着把这些信息以树形结构的形式展现出来。通过上面的分析,我们可以初步得到代码的组织与内部实现设计如下面流程图所示:
数据流图
设计实现
获取文本框内容
为"现在添加"按钮绑定显示输入文本框事件函数
使用.getElementById()函数获得文本框内的值,并使用split()函数按照双回车和单回车进行拆分。
var all_data = document.getElementById("user").value;
var sclice_data = [];
var model_data = [];
model_data = all_data.split("\n\n");
sclice_data = model_data[j].split("\n");
分析输入内容
- 初步建树
对每行按”:“使用split()拆分并判断输入的第一个语段是“导师“、“年级”、“姓名”进行分类处理。
这里使用正则区分是否是“xxxx”年级行
if(head_tmp == "导师"){
}else if(/[1-9][0-9]*/.test(head_tmp)){
}else{}
如果是导师,创建一个根节点,填充节点信息并插入树数组中。
如果是xx级生,创建一个节点,填充姓名信息,并连接到上述根节点之后。
如果是姓名,说明输入的是技能,则读取之后技能并插入姓名对应节点之后。
- 对关联树进行合并
function Reconstruct(nodes, find_name, may_need, keke) {
var length_now = getJsonLength(nodes.children);
for (var ll = 0; ll < length_now; ll++) {
//查找此节点名是否与传入名相同
if (nodes.children[ll].name == find_name) {
quanju_flag = 1;
nodes.children[ll] = may_need; //将该传入树添加到儿子节点作为关联
return 1;
} else {
Reconstruct(nodes.children[ll], find_name, may_need, keke);
}
}
return 0;
}
绘制成员树
创建树布局,并插入svg标签,svg下的g标签、link标签以及相应的属性和点击事件。
var tree = d3.layout.tree().size([h, w]);
var svg = d3.select("#show-tree")
.append("svg")
.append("g");
创建斜线生成器。
var diagonal = d3.svg.diagonal()
.projection(function(d) {
return [d.y, d.x];
});
添加过渡动画(示例)
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) {
return "translate(" + d.y + "," + d.x + ")";
});
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function(d) {
return "translate(" + source.y + "," + source.x + ")";
})
.remove();
绑定点击动画
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
5.附加特点设计与展示
附加特点设计
- 我们在这个网页中实现了多个导师,多棵树并存的情形
- 能够实现子结点是导师时的关联树情形
- 能够实现多组数据的连续多次输入
- 在文本框输入后自动隐藏文本框,不遮挡树的显示空间
实现思路与关键代码
- 多棵树并存:利用treeData[]数组实现
var tree_tmp = treeData[j];
var name_tmp = treeData[j].name;
for (num_tmp = 0; num_tmp < j; num_tmp++) {
Reconstruct(treeData[num_tmp], name_tmp, tree_tmp, num_tmp);
}
if (!quanju_flag) count_shu++;
- 关联树:将已经存在的树放在树数组中,每新建一棵树就通过Reconstruct()函数回到树数组中查找是否有关联树存在,如果存在就将新树插入到对应的节点之后,实现关联树的合并。
function Reconstruct(nodes, find_name, may_need, keke) {
var length_now = getJsonLength(nodes.children);
for (var ll = 0; ll < length_now; ll++) {
//查找此节点名是否与传入名相同
if (nodes.children[ll].name == find_name) {
quanju_flag = 1;
nodes.children[ll] = may_need; //将该传入树添加到儿子节点作为关联
return 1;
} else {
Reconstruct(nodes.children[ll], find_name, may_need, keke);
}
}
return 0;
}
成果展示
- 初始界面
- 出现文本输入框
- 输入信息
- 生成成员树
- 多棵树并存
- 关联树
6.目录说明和使用说明
文件目录
- d3.v3.min.js:d3框架文件
- index.html:成员树文件
- style.css:网页的css样式文件
- script.js:需要导入的js文件
使用说明
文件下载后放在同一个文件夹中
- 进入MemberTree文件夹
- 用谷歌Chrome浏览器打开index.html文件,先点击左上角的“现在添加”按钮,文本输入框出现
- 按照格式输入数据后,点击“生成”按钮即可
- 可以多次输入多组数据而不需要刷新页面,生成的树会全部显示在页面上
7.单元测试
白盒测试用例如下,自动化测试工作仍在进行
一棵树
导师:张三
2016级博士生:天一、王二、吴五
2015级硕士生:李四、王五、许六
一棵树,其中一个叶节点有技能
导师:张三
2016级博士生:天一、王二、吴五
2015级硕士生:李四、王五、许六
2016级硕士生:刘一、李二、李三
2017级本科生:刘六、琪七、司四
刘六:JAVA、数学建模
两棵关联树
导师:张三
2016级博士生:天一、王二、吴五
2015级硕士生:李四、王五、许六
2016级硕士生:刘一、李二、李三
2017级本科生:刘六、琪七、司四
导师:天一
2017级本科生:李久、王琪、斯四
两棵关联树,其中一个叶节点有技能树
导师:张三
2016级博士生:天一、王二、吴五
2015级硕士生:李四、王五、许六
2016级硕士生:刘一、李二、李三
2017级本科生:刘六、琪七、司四
导师:天一
2017级本科生:李久、王琪、斯四
李久:前端
两棵独立树
导师:张三
2016级博士生:天一、王二、吴五
2015级硕士生:李四、王五、许六
2016级硕士生:刘一、李二、李三
2017级本科生:刘六、琪七、司四
导师:李斯
2017级本科生:李久、王琪、斯四
8.GitHub的代码签入记录截图
9.遇到的代码模块异常或结对困难及解决方法
-
起初,我们对于输入的数据如何分类感到束手无策。通过上网查询资料,学习到可以利用split()拆分字符串。
-
我们原本设想的技能呈现方式是,将鼠标悬浮在叶结点上方即可查看,不过受时间所限,我们尚未实现这一功能,后期可能会增加。
-
整个项目主要工作就是学习javascript语法同时去实现相应的功能,主要的阻碍其实就是对相关领域知识的不熟悉。除此之外可以说没有遇到大的困难,报错之后仔细阅读错误信息并回去重新学习函数功能一般就能解决。
-
项目让我感到最为头疼的就是测试工具的安装,安装Node.js和npm之后使用npm自动下载依赖包,(也包括测试工具依赖包的下载)这一步总是出错,cli中npm就一直在那转转转,转完给个安装失败,在网上查找了很多方法都没有得到解决。也还没能完成自动化测试部分。
10.对队友的评价
-
张智和:队友对待工作认真,准确地把握作业的方向,制定最简洁有效的行动轨迹。对时间的把握,项目每天都会有新的进展。在组队过程中我们配合的很默契,分工明确。协同工作有效地提高彼此效率。这次结对编程受益良多,很高兴能有这样的队友。
-
欧文烨:我的队友张智和是一个认真努力的人,对于此次结对作业,他对于每一个细节都有很高的要求,树的设计哪里不够美观、文字排版哪里不够规范,都逃不过他的法眼。由于这次作业涉及的方向对我来说是完全陌生的,这次也多亏了他良好的代码功底。在组队完成作业的过程中,我对于前端知识的了解也深了一个层次,非常感谢他的帮助与指导。最终我们各自分工,发挥所长,还算比较圆满地完成了任务,他是一个很不错的队友,期待我们的下一次合作!