鏈接
github地址:https://github.com/O-VIGIA/031702414-031702444.git
結對同學:031702414陸志陽
具體分工
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了
-
問題描述:太瞌睡
-
嘗試:拉着隊友一起熬夜
-
是否解決:已解決,兩人均變憨憨
評價隊友
-
值得學習的地方
認真努力,敢於攻克難關,責任心強,編碼能力強,自學能力強。
-
需要改進的地方
喜歡花里胡哨的東西,在基本代碼還沒實現之前就想要搞事情。(兄嘚,猥瑣發育別浪)
六組測試
數據一:
導師:張三
數據二:
導師:張三
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級本科生:劉一
長路漫漫,隊友作伴