1.First thing first.
博客作業:https://edu.cnblogs.com/campus/fzu/2019FZUSEZ/homework/8736
項目地址:https://github.com/JoyJia2/081700414-021700913
你只需要下載main.html文件就可以運行我們的作品了!!!
2.具體分工;
021700913林立:打野
081700414賈懿:中單
3.psp表格:
PSP2.1 | Personal Software Process Stages | 預估耗時(分鍾) | 實際耗時(分鍾) |
---|---|---|---|
Planning | 計划 | 60 | 90 |
Estimate | 估計這個任務需要多少時間 | 60 | 90 |
Development | 開發 | 300 | 600 |
Analysis | 需求分析 (包括學習新技術) | 300 | 600 |
Design Spec | 生成設計文檔 | 120 | 120 |
Design Review | 設計復審 | 60 | 60 |
Coding Standard | 代碼規范 (為目前的開發制定合適的規范) | 60 | 120 |
Design | 具體設計 | 120 | 120 |
Coding | 具體編碼 | 300 | 300 |
Code Review | 代碼復審 | 60 | 120 |
Test | 測試(自我測試,修改代碼,提交修改) | 180 | 200 |
Reporting | 報告 | 60 | 60 |
Test Repor | 測試報告 | 60 | 120 |
Size Measurement | 計算工作量 | 60 | 40 |
Postmortem & Process Improvement Plan | 事后總結, 並提出過程改進計划 | 120 | 120 |
合計 | 1920 | 2760 |
根據數據對象來實現樹(empty.json只是個工具人)
function myFunction()
{
//文本處理區域
var txt=document.getElementById("input").value;
var top=txt.slice(txt.indexOf(":")+1,txt.indexOf("2"))//你把你老師給我交了
var cmaohao=txt.match(/:/g);
var brunch=cmaohao.length-1;
var lines = txt.split(/[(\r\n)\r\n]+/)//按行分成組
var add={ //初始化對象
"name":"張三",
"children":
[
{
"name":"2016級博士生" ,
"children":
[
{"name":"林立" }
]
}
]
};
add.name=lines[0].slice(0,lines[1].indexOf(":"));//導師名賦值
var temp=lines[1].slice(0,lines[1].indexOf(":"));//學生類型這樣獲取
var temp1=lines[1].slice(lines[1].indexOf(":")+1,50)
var temp1=temp1.split('、')//該類型下學生名單數組這樣獲取
for(var i =0;i<brunch;i++)
{
add.children[i]={
"name":"2016級博士生" ,
"children":
[
{"name":"林1" }
]
};
add.children[i].name=lines[i+1].slice(0,lines[i+1].indexOf(":"));
for(var j =0;j<lines[i+1].slice(lines[i+1].indexOf(":")+1,50).split('、').length;j++)
{
var temp=lines[i+1].slice(lines[i+1].indexOf(":")+1,50).split('、')[j];
add.children[i].children[j]={"name":"林立" };
add.children[i].children[j].name=temp;
}
}
//圖像區域大小
var R = 600;
//動畫持續時間
var duration=600;
//節點編號
var index=0;
//定義一個Tree對象,定義旋轉角度和最大半徑
var tree = d3.layout.tree()
.size([360,R/2-120])
.separation(function(a,b) { return (a.parent == b.parent ? 1 : 2)/a.depth;});
//定義布局方向
var diagonal = d3.svg.diagonal()
.projection(function(d) {
var r = d.y, a = (d.x-90) / 180 * Math.PI;
return [r * Math.cos(a), r * Math.sin(a)];
});
//新建畫布,移動到圓心位置
var svg = d3.select("body").append("svg")
.attr("width", R)
.attr("height", R)
.append("g")
.attr("transform", function(d){ return "translate("+R/2+"," + R/2 + ")";});
//根據JSON數據生成樹
d3.json("empty.json", function(error, data)
{
//在這修改之前的json
data=add;
var root=data;
//根據數據生成nodes集合
var nodes = tree.nodes(data);
//記錄現在的位置
nodes.forEach(function(d){
d.x0 = d.x;
d.y0 = d.y;
});
//獲取node集合的關系集合
var links = tree.links(nodes);
//根據node集合生成節點,添加id是為了區分是否冗余的節點
var node = svg.selectAll(".node")
.data(nodes,function(d){return d.id|| (d.id = ++index);});
//為關系集合設置貝塞爾曲線連接
var link=svg.selectAll(".link")
.data(links, function(d) { return d.target.id;})
.enter()
.append("path")
.attr("class", "link")
.attr("d",diagonal);
node.enter()
.append("g")
.attr("class", "node")
.attr("transform",function(d){return "rotate(" + (d.x-90) + ")translate(" + d.y + ")"; })
.on("click",nodeClick);
//為節點添加圓形標記,如果有子節點為紅色,否則綠色
node.append("circle")
.attr("fill",function(d){return d.children==null?"#0F0":"#F00";})
.attr("r", 5);
//為節點添加說明文字
node.append("text")
.attr("dy", ".4em")
.text(function(d){return d.name;})
.attr("text-anchor", function(d) { return "start" ; })
.attr("transform", function(d) { return "translate(8)"; });
//點擊的話,隱藏或者顯示子節點
function nodeClick(d)
{
if (d.children)
{
d._children = d.children;
d.children = null;
}
else
{
d.children = d._children;
d._children = null;
}
update(d);
}
//更新顯示
function update(source)
{
//取得現有的節點數據,因為設置了Children屬性,沒有Children的節點將被刪除
var nodes = tree.nodes(root).reverse();
var links = tree.links(nodes);
//為節點更新數據
var node = svg.selectAll("g.node")
.data(nodes,function(d){return d.id|| (d.id = ++index);});
//為鏈接更新數據
var link = svg.selectAll("path.link").data(links, function(d) {return d.target.id;});
//更新鏈接
link.enter()
.append("path")
.attr("class", "link")
.attr("d", function(d) {
var o = {x: source.x, y: source.y};
return diagonal({source: o, target: o});
});
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();
//更新節點集合
var nodeEnter = node.enter()
.append("g")
.attr("class", "node")
.attr("transform",function(d){return "rotate(" + (source.x0-90) + ")translate(" + source.y0 + ")"; })
.on("click",nodeClick);
//為節點添加圓形標記,如果有子節點為紅色,否則綠色
node.append("circle")
.attr("fill",function(d){return d.children==null && d._children==null?"#0F0":"#F00";})
.attr("r", 5);
//為節點添加說明文字
node.append("text")
.attr("dy", ".4em")
.text(function(d){return d.name;})
.attr("text-anchor", function(d) { return "start"; })
.attr("transform", function(d) {return "translate(8)";});
//節點動畫
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) { return "rotate(" + (d.x-90) + ")translate(" + d.y + ")"; });
//將無用的子節點刪除
var nodeExit =node.exit()
.transition()
.duration(duration)
.attr("transform", function(d){return "rotate(" + (source.x-90) + ")translate(" + source.y + ")"; })
.remove();
//記錄下當前位置,為下次動畫記錄初始值
nodes.forEach(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
});
}
5.附加特點設計與展示:
我們的可視化非常人性化,有迥異的發散風格。
文本的排版實際上還非常符合人體力學,為了更好的閱讀結果,你還得活動一下脖子。
走的是極簡主義,花里胡哨的沒有整太多。
你甚至可以添加插班生名單
6.在博客中給出目錄說明和使用說明:
在我給出的github中下載main.html 用chrome打開即可。
7.單元測試:
to be continued
8.貼出GitHub代碼簽入記錄:
9.遇到的代碼模塊異常或結對困難及解決方法:
因為最初對任務既沒有經驗也沒有頭緒,做到現在已經不記得開始的思路了,在這次任務中也深有體會----工作方向不確定的時候就容易呈樹狀發散思路,然后在每個樹枝方向上作權重評估,但是如果發散遠了發現這個方向不可行就很難回到上一個節.所有類似的工作中畫一個簡要的工作方向圖或簡單的工作日志。
不過我靈機一動打開了瀏覽器的歷史記錄,歸納了一下工作日志:
入門
10/13:CSS,js以及php的了解,並且最初的理解是要處理輸入文本,那應該需要用到數據庫,於是又了解了一下mysql和前端的結合。
只有高手才能活着用到最后
10/14:下載安裝了推薦的WampSever--所謂前端開發環境搭建,這里也確定了后面的開發工具---notepad++和chrome。按照教程在wamp文件夾下面建立了一個我的demo文件夾,在里面直接創建html,就可以在chrome中輸入localhost/訪問我的html頁面了。這基本上是我的開發環境雛形(其實一直都是這個)。
這里有遇到了一個問題,在wamp搭建完成后我修改了一下它的配置文件,最后發現只有一個服務器在運行,一個離線,也不是我80端口的占用問題,最后發現了是我配置文件修改后里面有語法錯誤,終得以解決。Notepad++應該配一句產品描述,我都幫它想好了---“只有高手才能用到最后”。我基本上剛剛入門相關語言,notepad++並不會給你報語法錯誤,於是一個令我現在還心有余悸的死循環:
編輯->保存->chrome F5刷新->輸入文本->運行->失敗->編輯
誕生了,這個真的給我整吐了,但是我沉浸於這個剛剛成功的運行環境,沒有想着下載IDE(也不清楚下載哪一個IDE),一直用到最后。
夠用就行,不求甚解
10/15:自然而然的就知道需要html頁面表單處理,於是摸索了一下html js php的表達處理機制,實現應該蠻簡單的,先看看怎么生成樹狀圖吧。這個時候突然接觸到D3,於是開始學習D3相關的用法,csdn和知乎上關於D3的所有教程我基本都有瀏覽,不過真正適合新手從0開始的只有csdn上一個js.d3系列文章(其實還有D3源文檔,現在看來是我的失策,當時因為源文檔全是英語並且太過於詳細而選擇了csdn上的文章),奈何這個教程的配圖都丟失了,我看着相當難受。
我們的d3庫是直接從網絡獲取的,所以操作者運行的時候最好是連接着網絡。
誤入歧途
10/16:在邊學d3,邊看看是不是應該學d3。還有json的學習,實際上這個時候已經有了一個簡單的實現路線:
頁面表單提交->形成json->生成目的樹狀圖
但是這個簡單的路線其實有很多的問題:1.表單文本怎樣轉換為json。2.轉換為的json應該存儲到哪。3.存儲的json可以被我后面的模塊調用嗎。
10/17:還在研究js和json的交互。並且繼續寫我的生成樹,樹上的文本方向,樹枝長度,由於是用到哪學到哪,寫起來十分吃力。幾乎一整天都在csdn【十二月咖啡館工作室】里摸索。
10/18:繼續在html css js php中摸爬滾打,實際上這個時候我還不知道應該在哪個語言哪個文本哪個部分實現哪個功能。哦不對,功能我還是知道的。
10.19:漸漸清晰了js方向,js語法應該支持輸入文本的處理,然后這里作了一個聰明的決定。我事先創建一個json文件到服務器,然后頁面讀入文本轉為一個數組(具體split等方法不贅述),然后再在json轉換為js對象后對其修改,再來生成樹,這也是我最后的辦法。
----這次作業時間成本有些過於昂貴了,我其他科目的課業也很繁重,這次作業以后,我會對自己的時間安排作更健康的規划。
10.評價你的隊友:
林立:賈某態度認真,效率高,都是第一次接觸HTML、css、js,但是他掌握的很快,我很多地方不懂問他都耐心的跟我解釋。改進地方的話就是解答問題時候再慢一點,我是真的跟不上,我太難了。
賈懿:林某可以端茶送水。很多地方第一次接觸不是很懂,討論一下理解還是比較快的。改進地方就是不要拖拉,做好規划。