1.链接
- github地址
- 结对同学
2.给出具体分工
031702338郑学贵:代码编写
031702612 陈志超:需求分析,素材收集,ui设计,测试
3.PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
Planning | 计划 | 60 | 50 |
Estimate | 估计这个任务需要多少时间 | 60 | 45 |
Development | 开发 | 600 | 480 |
Analysis | 需求分析 (包括学习新技术) | 300 | 200 |
Design Spec | 生成设计文档 | 100 | 60 |
Design Review | 设计复审 | 100 | 100 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 40 |
Design | 具体设计 | 60 | 60 |
Coding | 具体编码 | 600 | 480 |
Code Review | 代码复审 | 60 | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 180 | 150 |
Reporting | 报告 | 120 | 120 |
Test Repor | 测试报告 | 60 | 60 |
Size Measurement | 计算工作量 | 30 | 30 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 60 | 60 |
合计 | 2420 | 1995 |
4.解题思路描述与设计实现说明
需求分析
读完题目,经过认真的分析,NABCD模型,我们将整个需求分成三个模块
- 处理输入数据模块
- TreeGraph模块
- 个人信息展示模块
算法关键
主要在于处理输入数据,首先空行分割数据,数据按组来处理,每一组在通过关键字检测提取分割,最后维护出图的邻接表。然后通过dfs递归遍历图,将数据格式修改为指定要求的构建树图数据格式,传入对应的类,渲染出关系树。
树的结构设计
因为存在多树关联的情况,那么本质上就是构造出一张DAG,但是我们经过讨论后,认为如果构造一张DAG的话,可能层级结构不是那么清晰,我们决定如果多棵树有公共节点就合并成为一颗树,每一个级别也抽象成一个点,例如"2016级博士生"也作为图上的一个点,每一人物节点的父节点先是他是什么年级的学生,再连着他的导师,公共节点拿去拆分成多个副本,这样结构关系清晰,并且也能够清楚知道他跟过哪些导师,但是每个人只保存他的最高学历。
代码片段(已加注释)
因为写的网页,唯一有逻辑性的代码则就只有处理数据这一模块,其他部分只是处理页面样式等。
handleData() {
let text = document.getElementById("data");
var data = text.value; //从输入框获取数据
var lis = data.split("\n"); //先按空行分割成多组数据
let rk = new Map(); //用于比较排名,记录某人的最高学历
(rk["导师"] = 0),
(rk["博士生"] = 1),
(rk["硕士生"] = 2),
(rk["本科生"] = 3);
var ID = 0;
let str = ["博士生", "硕士生", "本科生"]; //关键字检测
var _this = this;
for (var i = 0; i < lis.length; ) {
var j;
for (j = i + 1; j < lis.length; ++j) {
if (lis[j] == "") break;
}
// [i,j)为一组数据
let th = lis[i].substring(3);
_this.edge[th] = [];
_this.info[th] = "导师";
//使用map,map的第一维是字符串,对应人名,第二维对应一个数组,对应他连接的人
for (var k = i + 1; k < j; ++k) {
var cur, idx;
for (var value of str) {
idx = lis[k].indexOf(value);
if (idx != -1) {
cur = lis[k].substring(0, idx + 3);
_this.edge[th].push(lis[k].substring(0, idx + 3) + th);
_this.edge[cur + th] = [];
_this.info[cur + th] = value;
_this.used[cur + th] = 1;
//used用于标记某个点是否有父节点
//info用于处理每个人的最高学历
break;
}
}
var stu = lis[k].substring(idx + 4).split("、");
for (var value of stu) {
//更新最高学历
if (_this.info[value] == null || rk[_this.info[value]] > rk[cur])
_this.info[value] = cur;
//通过、分割,进行连边
_this.edge[cur + th].push(value);
_this.used[value] = 1;
}
}
i = j + 1;
}
for (var key in _this.info) {
//可能存在多个树,我们之前将有父节点的点used都标记了,
//因此used没被标记过的点则一定是根节点,从根节点出发,递归遍历图,处理数据格式
if (_this.used[key] == null) {
_this.data.push(_this.formatData(key, -1));
}
}
this.$router.push({
path: "/user/relation",
query: {
data: JSON.stringify(_this.data)
}
});
},
formatData(rt, fa) {
//每个点的信息包括id,name,lv(学历),以及他的儿子节点,其他就是普通的dfs。
let now = {};
now.name = rt;
now.id = this.ID;
this.ID += 1;
now.lv = this.info[rt];
now.children = [];
let arr = this.edge[rt];
if (arr == null) return now;
for (var i = 0; i < arr.length; ++i) {
now.children.push(this.formatData(arr[i], rt));
}
if (rt.indexOf(fa) != -1) {
let tmp = rt.substring(0, rt.indexOf(fa));
now.name = tmp;
}
return now;
}
5.附加特点设计与展示
5.1设计的创意独到之处,这个设计的意义
- 将数据用树状图可视化,这样结构清晰,人物之间的关系一目了然
- 增加了查看个人信息的功能,显示他的信息,以及以他为根的关系树。
- 系统模块化开发,扩展性强,后续可以增加其他新的功能
- 单独设置一个处理输入的页面,
更加美观
5.2实现思路
在树图界面中,每个节点添加event,右键即可跳转查看对应的信息。
5.3代码片段
graph.on("node:contextmenu", ev => {
//找到节点的信息,如果是‘xxx级博士生’等虚拟节点则不跳转,如果是真实人物则跳转到个人信息页面
//传递对应的参数
let name=ev.item._cfg.model.label;
if(name.indexOf("博士生")!=-1)return;
if(name.indexOf("硕士生")!=-1)return;
if(name.indexOf("本科生")!=-1)return;
this.$router.push({
path:'info',
query:{
data:ev.item._cfg.model
}
})
});
5.4成果展示
显示个人信息,以及以他为根的关系树。
6.在博客中给出目录说明和使用说明
6.1目录组织
s使用vue+iview+antv开发,vue脚手架大大提升生产力,src文件下,assets存放静态资源,components存放不同的模块,router配置一下路由,控制页面跳转,用到的资源全局导入即可。
dist文件夹:只包括图中两项,在本地服务器上直接运行index.html即可。
6.2如何运行
方式一:下载dist文件夹。然后再本地服务器上打开index.html(可以用vscode打开,然后装个live server,go live即可)。
Tip: built files are meant to be served over an HTTP server.
Opening index.html over file:// won't work.
方式二:下载所有文件,先装node,再安装vue,然后
cd ‘对应的文件夹’
npm install
npm run dev
6.3运行截图及说明
在文本框内输入合法数据,按按钮即可生成
生成的图如下,关系树支持拖动,大小缩放,鼠标放在上面滚轮滑动即可缩放,鼠标选中即可拖动。多颗树的时候,下拉浏览器滚动条即可看到其他树。
右键人物节点跳转到个人信息界面,显示他为根的关系树。
7.单元测试【10'】
7.1如何构造测试数据?
根据不同情况,构造出边界数据,单树的情况,多树的情况,多树关联的情况
7.2测试工具 以及学习
使用的vue-jest,有官方文档,并且讲的通俗易懂。
7.3部分代码
因为整个作业下来更多的是页面的样式,都可以直观的测试出来,有可能出错的就是在于数据的处理,自己构造了一些数据用jest测试。
顺利通过测试(inputData中处理输入数据)
8.贴出Github的代码签入记录
9.遇到的代码模块异常或结对困难及解决方法【4'】
问题描述
树图的位置和button一直不对,以及组件的样式问题。
做过哪些尝试
查找博客,去社区和qq群提问。
是否解决?
已经解决。
收获
提升了解决问题的能力,对框架的使用和一些坑点有了更深的理解。
10.评价你的队友
值得学习的地方
分析需求准确,能将需求合理的拆分成各个模块,开发能力强,效率高
需要改进的地方
需要更好的配合以及沟通交流,相信我们能更好更快的完成作业