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(/[(
)
]+/)//按行分成组
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,但是他掌握的很快,我很多地方不懂问他都耐心的跟我解释。改进地方的话就是解答问题时候再慢一点,我是真的跟不上,我太难了。
贾懿:林某可以端茶送水。很多地方第一次接触不是很懂,讨论一下理解还是比较快的。改进地方就是不要拖拉,做好规划。