軟件工程實踐2019第五次作業


1.鏈接

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.評價你的隊友

值得學習的地方

分析需求准確,能將需求合理的拆分成各個模塊,開發能力強,效率高

需要改進的地方

需要更好的配合以及溝通交流,相信我們能更好更快的完成作業


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM