学术家族树的前端实现
这初始的黄金之风luxiaoye
What does not kill me makes me stronger
链接
github地址:https://github.com/O-VIGIA/031702414-031702444.git
结对同学:031702444李尚佳
具体分工
031702414陆志阳:算法设计和实现,单元测试,代码优化
031702444李尚佳:前端页面设计和实现
共同完成:jstree的实现 博客内容撰写
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(h) | 实际耗时(h) |
---|---|---|---|
Planning | 计划 | 3 | 4 |
Estimate | 估计这个任务需要多少时间 | 58 | 69 |
Development | 开发 | 5 | 8 |
Analysis | 需求分析 (包括学习新技术) | 8 | 24 |
Design Spec | 生成设计文档 | 2 | 5 |
Design Review | 设计复审 | 1 | 2 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 2 | 3 |
Design | 具体设计 | 2 | 2 |
Coding | 具体编码 | 10 | 8 |
Code Review | 代码复审 | 3 | 2 |
Test | 测试(自我测试,修改代码,提交修改) | 4 | 3 |
Reporting | 报告 | 4 | 2 |
Test Repor | 测试报告 | 2 | 1 |
Size Measurement | 计算工作量 | 2 | 1 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 3 | 4 |
合计 | 58 | 69 |
解题思路描述与设计实现说明
读完题目,分析要点如下:
- 文本数据的提取
- 文本数去提取完如何保存和传送
- 树状动态结构的生成
- 树状结构缩放的实现
代码组织与内部实现设计(类图)
说明算法的关键与关键实现部分流程图
在没开始之前 我们两个 是这么想的 ((( :
算法:
缩放算法:
定义 检查函数(节点)
{
检查该节点所有的父节点
如果 其所有父节点的缩放标志全为1,该节点与所有的父节点连线消失并且该节点消失
如果 其至少有一个父节点的缩放标志不为1,该节点只与缩放标志为1的父节点连线消失并且该节点不消失
}
定义 缩放函数(节点)
{
点击节点,以此节点为父节点,找到他的所有的儿子节点(第一层儿子节点),该节点缩放标志为1。
检查节点(子节点)
缩放函数(子节点)
}
主函数()
{
缩放函数(点击的节点);
}
在分工开始了之后我是这么想的
算法
。。。。。。。。。。。。。。
最后是则个样子?!
多行不E必自闭 ~
好了正经起来:
在打关联树的时候
比较有意思的一个算法可能就是递归查找子节点了,就是当前树的根节点和前面树的节点是否有关联
写这个算法的过程中,因为数据是json格式,所以求父节点下一级子节点的长度就是关键。
刚开始憨憨写了个 json. length()/.size()...发现都不对,最后只能自己去手打,发现手打也没那么难
//自定义json长度查找函数,返回json树的下层子节点的长度(个数)
function getJsonLength(jsonData) {
var json_length = 0;
for (var temp in jsonData) {
//alert("Son is " + item);
json_length++;
}
return jsonLength;
}
剩下的就交给我的递归查找函数了,直接上代码,看注释
/*
检查函数,遍历之前所有树的所有子节点,查找是否有导师的学生也是导师的情况,若有此种情况则此树重构
*/
//@nodes 源json树
//@find_name 要找的导师名
//@may_need 可能需要添加的json树
function check(nodes, find_name, may_need, keke) {
var fanhui1 = 0;
var fanhui2 = 1;
// alert("checkcheckcheckcheckcheckcheck");
var length_now = getJsonLength(nodes.children);
// alert("chang = " + length_now)
for (var ll = 0; ll < length_now; ll++) {
// alert(nodes.children[ll].name);
if (nodes.children[ll].name == find_name) {//第ll个子节点的名字是否与要查找的相同
// alert("hhhhhhhhhhhhhh");
quanju_flag = 1;如果有一棵树和其他树有关联此变量为一树的颗数不增加
//add_tree(nodes.children[ll].children, may_need, keke);
// alert("add");
// alert(getJsonLength(may_need));
nodes.children[ll] = may_need;//将该json树添加到儿子节点作为关联
// alert("add success");
return fanhui2;
} else {
check(nodes.children[ll], find_name, may_need, keke);
// return;
}
}
return fanhui1;
}
其他的地方,也就是搞json的时候的经常犯傻,不过最后还是渐渐清晰了。
有关树的生成,我把队友的画图代码封装成函数,用json数据存放成当前所有的树,最后一起生成防止生成关联树之后又生成关联树的子树,树的棵树用模块独立树减去关联树统计画出。
详细的生成树的逻辑思想见下面的流程图@lxy
贴出你认为重要的/有价值的代码片段,并解释
alert("宇宙最有价值的代码");
这就是最有价值的代码☝
正经一点开始正题
在上面的“算法的关键与关键实现部分流程图 ”我其实已经列出了一些代码都是一些功能函数
最有价值的就是主函数代码把,它。。多累啊
解释看注释和上面流程图
//追逐函数
/*
分割传输过来的数据并构造json树结构
相当于主函数功能
*/
function chase() {
var count = 0; //定义儿子节点的编号
var flag = 0; //定义标志是否为关联树值为1
var all_data = document.getElementById("user").value;
var sclice_data = [];
var model_data = [];
model_data = all_data.split("\n\n");
//生成树型结构数据
for (var j = 0; j < model_data.length; ++j) {
//初始化变量
count = 0;
//flag = 0;
quanju_flag = 0;
count_shu = 0
sclice_data = model_data[j].split("\n");
for (var i = 0; i < sclice_data.length; ++i) {
var head_tmp = "";
var body_tmp = "";
var hb = sclice_data[i].split(":"); //从冒号分割一层字符串
head_tmp = hb[0];
body_tmp = hb[1];
//处理冒号前的部分
if (head_tmp == "导师") {
var daoshi2 = {
"name": body_tmp,
"parent": "null",
"children": [{}]
}
treeData[j] = daoshi2; //将导师嵌入节点
} else {
var children = {
"name": head_tmp,
"parent": "null",
"children": [{}]
}
treeData[j].children[count] = children; //将年级及职业嵌入节点
var bodies = body_tmp.split("、");
//document.write("姓名:");
for (var kk = 0; kk < bodies.length; ++kk) {
var children = {
"name": bodies[kk],
"parent": "null",
//"children": [{}]
}
//treeData.push(children);
treeData[j].children[count].children[kk] = children; //将姓名嵌入节点
}
count++; //第二子节点编号加一,生成下一个第二子节点
}
}
var tree_tmp = treeData[j];
var name_tmp = treeData[j].name;
for (num_tmp = 0; num_tmp < j; num_tmp++) {
check(treeData[num_tmp], name_tmp, tree_tmp, num_tmp);
}
if (!quanju_flag) count_shu++;//若有关联树则独立树的棵数不增加
}
//生成所有树
alert("shu: " + count_shu);
for (var i = 0; i <= count_shu; i++) {
shuInit(i)
}
}
附加特点设计与展示
设计的创意独到之处以及设计的意义
- 采用透明图片作为背景,增加界面的美观感
- 左右四六分的格局,使界面显得整齐规整
- 蓝绿透明框配色,极具简约感
-支持多颗关联树
实现思路
-
用不同的div构建层次
-
css样式使用百分比宽高绝对定位
-
算法和js操作详细请见上面的介绍
实现成果展示
- 前端输入界面:
- 生成树状结构界面:
- 家族树缩放界面:
在博客中给出目录说明和使用说明
说明你的目录是如何组织的
目录
-
FT4.0
- index.html(在chrome上运行)
- style.css(外部样式表)
- tree.js(生成家族书的函数)
- background.jpg(背景图片)
- d3.v3.min.js(d3库)
-
README:使用说明文件
-
使用方式
下载FT4.0到本地,解压后文件本地,用chrome打开index.html,在右侧文本框输入文本。
学术家族树以文本形式输入,点击提交文本框。
-
文本格式
输入:
学术家族树以文本形式输入,点击提交文本框,考虑学术家族树的文本格式是这样的:
导师:张三
2016级博士生:天一、王二、吴五
2015级硕士生:李四、王五、许六
2016级硕士生:刘一、李二、李三
2017级本科生:刘六、琪七、司四
导师:吴五
2016级博士生:天一、王二、吴2015级硕士生:李四、王五、许六
2016级硕士生:刘一、李二、李三
2017级本科生:刘2、琪七、司四
导师:刘2
2016级博士生:天一、王二2015级硕士生:李四、王五、许六
2016级硕士生:刘一、李、李三
2017级本科生:刘、琪七、司四
!!!文本最后不能换行
其中,"导师:","级博士生:","级硕士生:","级本科生:"和"、"当做关键词处理;若有多组输入,中间空一行。
输出:
树的节点,鼠标点击后是可以缩放的。同时,支持呈现多棵树并存、两棵关联树共存等形式。
在左侧家族树下会显示可缩放的树状结构,即生成的家族树。
测试人员如何运行你的网页
- 点击github上把文件Clone到本地,解压后即可使用,需保证上述所有文件在同一个文件夹下。
- 直接用Chrome打开indext.html,输入格式按照作业要求。
- 在右侧的文本框输入数据,点击提交文本,将会在左侧生成一棵以导师为根节点的树。支持多棵树并存以及关联树。
单元测试
说明你们选用的测试工具,是如何学习单元测试的,能出一份你自己的简易教程吗?
展示出项目部分单元测试代码,并说明测试的函数
说明构造测试数据的思路,你是如何考虑各种情况的?你如何考虑将来测试人员的***难?
单元测试,说实话多这个东西十分的陌生,虽然在上次的数独中有单元测试的一点点模块,助教大神不给我分啊气,这次希望助教大神。。。给点分,(憨憨只想开个玩笑,大神别搞我。这次单元测试也是相对比较简单的。
单元测试也花了不少时间,我在查找了很多js单元测试的框架之后选定了抹茶,mocha!多好的名字,我想必打起来也会和吃抹茶一样。
测试工具:mocha
我首先对我的求json树长度函数进行了测试,测试了两种情况
上图把
1子节点
2子节点的子节点
可见,虽然。。。。。但是都成功单元测试出来了,说明我的json树求长度功能还是可以的。
然后我又对子节点查找函数进行了测试
查找 子节点的子节点 的姓名
然后出现了我快要笑死的东西
什么,竟然错了,在凌晨的四点的福大,仰望床底的我不禁开始了静静的思考
思考后并且和前面的比对之后我发现少加了东西,因为我是在单元测试.js中外部请求了函数模块,所以要加上module,鸭嘞鸭嘞,然后我愉快的加上了model。。。 -------》to be comtinue
这个这个我竟看了老半天才发现,真的是xsl
测试成功,在所有子节点中以及子节点的子节点等等可以找到了名字为“yyy”的同学
然后我测试一下在所有的子节点中找到 陆小爷 同学
果然,找不到陆小爷同学,因为他打软工去了。
测试成功。时间原因没有过多测试。
重点来了,下面可能是最入门级的单元测试教程
我仔细的浏览了一下博客作业中给出的mocha教程,发现很不容易上手(就是菜)
上手的教程在这哈哈哈哈哈
首先在电脑上安装node环境,并且配置环境变量path,(当然可以选择msi自行配制)
配置好之后就可以愉快的用npm命令啦,npm install mocha安装抹茶
配置抹茶.bin目录到path环境变量,然后就能愉快的运行你的test.js代码
关于断言的单元测试代码可以参考博客作业的教程。
//对单元测试当时爱了两个小时
构造单元测试的思路,和应对未来的***难
思路清晰:
测试json长度为例,测试完根结点的长度,是否能测出子节点的长度呢。
查找子节点,是否能遍历所有子节点进行查找呢
应对***难:
如果我们角色互换,我会让你看看什么叫残忍!
//多学习,多做事。做到足够优秀,代码足够健壮。
贴出Github的代码签入记录
你以为是这样,我也想
他其实长这样
遇到的代码模块异常或结对困难及解决方法
-
问题描述:树状结构难以实现。
-
尝试:学习VUE,D3等框架,寻找类似树状可折叠结构的模板,学习API使用。
-
是否解决:已解决。
-
问题描述:界面设计简单简陋,不堪入目,html+css不熟练。
-
尝试:广泛寻找优质界面,并借鉴学习,在B站和菜鸟教程寻找入门教学资源,一步步慢慢学习建立。
-
是否解决:已解决
-
问题描述:无法与界面树进行数据交互
-
尝试:学习json,用json做结构
-
是否解决:已解决
-
问题描述:对json完全不了解
-
尝试:打码测试,测试节点,测试遍历等等learning by doing
-
是否解决:玩6了
-
问题描述:太瞌睡
-
尝试:拉着队友一起熬夜
-
是否解决:已解决,两人均变憨憨
评价队友
-
值得学习的地方
和我一样有着永不放弃的黄金精神,
-
需要改进的地方
不喜欢花里胡哨的东西,在基本代码还没实现之前就 不想着要搞事情。(兄嘚,Java得浪啊)
六组测试
数据一:
导师:张三
数据二:
导师:张三
2016级博士生:天一
2015级硕士生:李四
2016级硕士生:刘一
2017级本科生:刘六
数据三:
导师:张三
2016级博士生:天一、王二、吴五
2015级硕士生:李四、王五、许六
数据四:
导师:张三
2016级博士生:天一、王二、吴五
2015级硕士生:李四、王五、许六
2016级硕士生:刘一、李二、李三
2017级本科生:刘六、琪七、司四
数据五:
导师:张三
2016级博士生:天一、王二、吴五
2015级硕士生:李四、王五、许六
2016级硕士生:刘一、李二、李三
2017级本科生:刘六、琪七、司四
导师:吴五
2016级博士生:天一、王二、吴
2015级硕士生:李四、王五、许六
2016级硕士生:刘一、李二、李三
2017级本科生:刘2、琪七、司四
数据六:
导师:张三
2016级博士生:天一、王二、吴五
2015级硕士生:李四、王五、许六
2016级硕士生:刘一、李二、李三
2017级本科生:刘六、琪七、司四
导师:吴五
2016级博士生:天二、王四、吴六
2015级硕士生:李一、王八、许七
2016级硕士生:刘三、李八、李二
2017级本科生:刘一、琪八、司四九
导师:刘2
2016级博士生:天四、王九
2015级硕士生:李四
2016级硕士生:刘一
2017级本科生:刘一
长路漫漫,队友作伴
posted on 2019-10-19 18:04 Martrix-revolution 阅读(1450) 评论(6) 编辑 收藏 举报