软件工程实践2019第五次作业

结对信息

031702516袁嘉鸿 [图片上传失败...(image-c7addb-1571486858335)]

https://www.cnblogs.com/putaoputao/
031702546江海天 [图片上传失败...(image-d45115-1571486858335)]

https://www.cnblogs.com/sky-jiang99/

Github仓库地址

https://github.com/sky-jiang99/031702546-031702516

具体分工

江海天 代码编写,前端设计
袁嘉鸿 代码测试,编写博客

PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 30 30
Estimate 估计这个任务需要多少时间 900 1000
Development 开发 1000 1000
Analysis 需求分析 (包括学习新技术) 200 250
Design Spec 生成设计文档 60 30
Design Review 设计复审 20 10
Coding Standard 代码规范(为目前的开发制定合适的规范) 10 10
Designt 具体设计 50 60
Coding 具体编码 800 800
Code Review 代码复审 50 60
Test 测试(自我测试、修改代码,提交修改) 300 350
Reporting 报告 100 120
Test Repor 测试报告 20 20
Size Measurement 计算工作量 10 10
Postmortem&Process Improvement Plan 事后总结并提出过程改进计划 80 80
合计 2730 2830

解题思路描述与设计实现说明(心得体会)

任务分为两个: 前端页面设计 和 树的生成
家族树实现就是先做一棵树,以导师为根节点,往届学生为子节点。这样的树结构从D3.js里就能找到,所以我们选取了百度的树图框架https://blog.csdn.net/joker_fei/article/details/76910023这里面详细讲解了可折叠树图的设计方法和理念。
贴代码

d3.select(self.frameElement).style("height", "500px");
function update(source) {
  // Compute the new tree layout.计算新树图的布局
  var nodes = tree.nodes(root).reverse(),
      links = tree.links(nodes);
  // Normalize for fixed-depth.设置y坐标点,每层占180px
  nodes.forEach(function(d) { d.y = d.depth * 180; });
  // Update the nodes…每个node对应一个group
  var node = svg.selectAll("g.node")
      .data(nodes, function(d) { return d.id || (d.id = ++i); });//data():绑定一个数组到选择集上,数组的各项值分别与选择集的各元素绑定
  // Enter any new nodes at the parent's previous position.新增节点数据集,设置位置
  var nodeEnter = node.enter().append("g")  //在 svg 中添加一个g,g是 svg 中的一个属性,是 group 的意思,它表示一组什么东西,如一组 lines , rects ,circles 其实坐标轴就是由这些东西构成的。
      .attr("class", "node") //attr设置html属性,style设置css属性
      .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
      .on("click", click);
  nodeEnter.append("rect")
    .attr("x",-23)
    .attr("y", -20)
    .attr("width",140)
    .attr("height",40)
    .attr("rx",10)
      .style("fill", "#357CAE");//d 代表数据,也就是与某元素绑定的数据。
  nodeEnter.append("text")
    //.attr("x", function(d) { return d.children || d._children ? 13 : 13; })
    .attr("x","50")
    .attr("dy", "8")
    .attr("text-anchor", "middle")
    .text(function(d) { return d.name; })
    .style("fill", "white")
    .style("fill-opacity", 1);
  //将节点过渡到一个新的位置-----主要是针对节点过渡过程中的过渡效果
  //node就是保留的数据集,为原来数据的图形添加过渡动画。首先是整个组的位置
  var nodeUpdate = node.transition()  //开始一个动画过渡
      .duration(duration)  //过渡延迟时间,此处主要设置的是圆圈节点随斜线的过渡延迟
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
  nodeUpdate.select("rect")
            .attr("x",-23)
            .attr("y", -20)
            .attr("width",140)
            .attr("height",40)
            .attr("rx",10)
            .style("fill", "#357CAE");
  nodeUpdate.select("text")
    .attr("text-anchor", "middle")
      .style("fill-opacity", 1);
  //过渡现有的节点到父母的新位置。
  //最后处理消失的数据,添加消失动画
  var nodeExit = node.exit().transition()
      .duration(duration)
      .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
      .remove();
  nodeExit.select("rect")
          .attr("x",-23)
          .attr("y", -20)
          .attr("width",140)
          .attr("height",40)
          .attr("rx",10)
          .style("fill", "#357CAE");
  nodeExit.select("text")
    .attr("text-anchor", "middle")
      .style("fill-opacity", 1e-6);
  // Update the links…线操作相关
  //再处理连线集合
  var link = svg.selectAll("path.link")
      .data(links, function(d) { return d.target.id; });
  //添加新的连线
  link.enter().insert("path", "g")
      .attr("class", "link")
      .attr("d", function(d) {
        var o = {x: source.x0, y: source.y0};
        return diagonal({source: o, target: o});  //diagonal - 生成一个二维贝塞尔连接器, 用于节点连接图.
      })
    .attr('marker-end', 'url(#arrow)');
  //将斜线过渡到新的位置
  //保留的连线添加过渡动画
  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();
  //将旧的斜线过渡效果隐藏
  nodes.forEach(function(d) {
    d.x0 = d.x;
    d.y0 = d.y;
  });
}

整个树做好了过后难点就在如何填入数据了,说实话要做文字识别的时候我整个人是懵的,给了一段正正经经的中文要提取里面的文字数据我是完全没有想法的。这时候启发来了,第二次团队作业的发布,周六一个上午在实验室肝了一上午的WordCount的代码,正好和一个大佬队友一起写单词的识别提取还有记频率环节,知到了py和java有split这个函数,果然js里也有。然后中午回宿舍赶紧学怎么用,补上了这段识别代码。(本来想着用户不管输入什么都输出导师张三的样例的QAQ
贴代码

    let text = document.getElementsByTagName('textarea')[0].value
    let line1 = text.split(/[(\r\n)\r\n]+/) // 根据回车分割
    if ( line1.length == 1 )
    {
      line1=['导师:张三','2016级博士生:天一、王二、吴五','2015级硕士生:李四、王五、许六','2016级硕士生:刘一、李二、李三','2017级本科生:刘六、琪七、司四']
    }
    let teacher = line1[0].split(':')
    let sign1 = 1
    let sign2 = 1
    let sign3 = 1
    let teacherObj = {
      name: '',
      children: []
    } // {老师:{本科生:{2017:学生}}}
    let studentObjList = [] // {2017:学生}
    let gradeObjList = []   // {本科生:{2017:学生}}
    let DoctorObjList = []
    let benkeshengObjList = []
    let shuoshishengObjList = []
    //////
    for (let i = 1; i < line1.length; i++) {
        let student = line1[i].split(':')//得到学生的名单
        let degree = student[0].split('级')[1]
        let grade = student[0].split('级')[0]
        let students = student[1].split('、')
        studentObjList = []
        ////
        for (let i = 0; i < students.length; i++) {
            let obj = {}
            obj.name = students[i]
            studentObjList.push(obj)
        }
        ////
        gradeObjList = []
        gradeObjList.name = grade + '级'
        gradeObjList.children = studentObjList
        //teacherObj.children.push(gradeObjList)  // 插入其他年级及届数
        if (degree === '博士生') {
          if (sign1){
            DoctorObjList = []
            DoctorObjList.name = '博士生'
            DoctorObjList.children=gradeObjList
            DoctorObjList.children.push(gradeObjList)
            teacherObj.children.push(DoctorObjList)
            sign1 = 0
          } else{
            DoctorObjList.children.push(gradeObjList)
          }
        } else if ( degree === '本科生' ) {
          if (sign2)
          {
            benkeshengObjList = []
            benkeshengObjList.name = '本科生'
            benkeshengObjList.children=gradeObjList
            benkeshengObjList.children.push(gradeObjList)
            teacherObj.children.push(benkeshengObjList)
            sign2 = 0
          } else {
            benkeshengObjList.children.push(gradeObjList)
          }
        } else if ( degree === '硕士生' ) {
          if (sign3)
          {
            shuoshishengObjList = []
            shuoshishengObjList.name = '硕士生'
            shuoshishengObjList.children=gradeObjList
            shuoshishengObjList.children.push(gradeObjList)
            teacherObj.children.push(shuoshishengObjList)
            sign3 = 0;
          } else {
            shuoshishengObjList.children.push(gradeObjList)
          }
        }  
    }
    //////
    teacherObj.name = teacher[1]
    console.log(line1)
    treeData = []//把数据置为空
    treeData.push(teacherObj)//放入数据
    root = treeData[0]
    update(root)

附加特点设计与展示

软件工程实践2019第五次作业_第1张图片

https://img2018.cnblogs.com/blog/1797320/201910/1797320-20191019192915718-2145896167.png)

遇到的代码模块异常或结对困难及解决方法

其实还是遇到了很多问题,最开始的问题,前端,没接触过,所以就搜索了很多文章,很多别人的博客,别人的成品,也看了html和css的各种概念语法规则,发现熟悉这些不是很快能掌握的,后来只能大概了解一下后开始写作业,不然截止时间交不上,最后还是实现了家族树,然后到了编写代码阶段,我们参考了CSDN上的一边文章,大概了解了一下,有了思路,开始进行编程,然后开始github仓库的问题,我阅读了一下作业文章中关于github使用方法的链接,才明白了一些,没有这个教程,自己查找时候还总会遇到广告,很难搜到有用的信息,这片教程还没完全熟悉,我已经收藏下来,有时间看一看再进行学习。我觉得经过一次次的完成作业和学习,虽然过程很麻烦,我们还会收获很多。

评价你的队友

ptpt :sky 是一个随性的人,代码能力可以,但是做事喜欢拖着,希望能积极一点。
sky :ptpt很认真,能把琐碎的事情完成,同样喜欢拖着,代码写的一般

你可能感兴趣的:(软件工程实践2019第五次作业)