结对作业2
作业描述
这个作业属于哪个课程 | 2021软件工程实践w班福州大学 |
---|---|
这个作业要求在哪里 | 结对第二次作业--顶会热词统计的实现 |
结对学号 | 221801415&221801425 |
这个作业的目标 | 实现顶会热词统计 |
其他参考文献 | CSDN、Yii权威指南 |
PSP表格
PSP2.1 | Personal Software Process stages | 预估耗时(min) | 实际耗时(min) |
---|---|---|---|
Planning | 计划 | 20 | 20 |
·Estimate | ·估计这个任务需要多少时间 | 4500 | 5000 |
Development | 开发 | 2880 | 3000 |
· Analysis | · 需求分析 (包括学习新技术) | 500 | 600 |
· Design Spec | · 生成设计文档 | 20 | 20 |
· Design Review | · 设计复审 | 10 | 20 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
· Design | · 具体设计 | ||
· Coding | · 具体编码 | 1120 | 1200 |
· Code Review | · 代码复审 | 30 | 40 |
· Test | · 测试(自我测试,修改代码,提交修改) | 120 | 150 |
Reporting | 报告 | 20 | 30 |
· Test Repor | · 测试报告 | 10 | 20 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 50 | 60 |
合计 | 4800 | 5180 |
Github仓库地址
成果展示
结对讨论过程
过程:刚看到题目时,作业要求里推荐使用web框架,两个人对于web的掌握并不是很熟练,基本上很少写过,因此学习web框架的过程中,效率是很低的。后来在请教同学的过程中,联想到上学期web实践学到过的yii2.0框架,最后决定使用它来进行开发。yii2.0框架是基于php的,对于论文的增删改查等操作是比较容易实现的。再考虑到作业要求的论文列表和关键词图谱等要求,经过一个下午对于php语言和yii2.0框架视频的学习,我们使用了php+JavaScript实现了对于关键词数据的折线图和饼状图的构建,并在饼状图上实现了点击跳转事件。
数据库设计
主要有用户类和论文类组成
实现过程
基于Yii框架开发
1.登录功能的实现,编写登录表单,用户输入账号密码后,将表单发送给控制器类中的登录方法,进行验证,登录方法将数据发送给登陆模型,登录模型将数据与数据库中的数据进行比对,将结果返还给控制器类,登陆成功页面跳转到主页。
2.论文列表的实现,模型类从数据库中获取论文信息,并将此数据作为数据提供者发送欸视图类,论文视图类利用gridview部件将数据展示。
3.论文搜索功能的实现,搜索框分为标题搜索框,内容搜索框等,用户输入信息,发送到论文控制器中的index方法,该方法将数据发送给,模型类中的论文搜索模型,搜索模型从数据库中搜索符合条件的论文并利用gridview展示搜索结果。
4.热词统计部分使用echarts实现,根据从数据库中查询到的数据来描绘出相应的柱形图和饼状图,从数据库中的查询到的数据先转换为数组形式,再通过json_encode()方法将数据转换为json,最后传入到JavaScript数组中实现输出。最后实现了点击饼状图上关键词的跳转功能,能够跳转到该关键词所属原论文的链接页面。
功能结构图
代码声明
1.论文控制器类,实现论文搜索修改删除等操作
<?php
namespace backend\controllers;
use Yii;
use common\models\Paper;
use common\models\PaperSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
class PaperController extends Controller
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
public function actionIndex()//搜索功能实现
{
$searchModel = new PaperSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
public function actionView($id)//论文详情
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
public function actionCreate()//新建论文
{
$model = new Paper();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->link]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
public function actionUpdate($id)//修改论文
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->link]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
public function actionDelete($id)//删除论文
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
protected function findModel($id)
{
if (($model = Paper::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
2.实现热词分析的界面类,通过查询数据库获得的数据来制作柱形图和饼状图
<?php
/* @var $this yii\web\View */
use common\models\overall;
use common\models\taganalysis;
$pdata=overall::getOverall();
$cvrp=taganalysis::getDataPagercvrp();
$eccv=taganalysis::getDataPagereccv();
$iccv=taganalysis::getDataPagericcv();
$this->title = 'My Yii Application';
?>
<div class="site-index">
<div class="chart0">
<?php
/* @var $this yii\web\View */
use yii\helpers\Html;
$this->title = '图表分析';
$this->params['breadcrumbs'][] = $this->title;
?>
<script type="text/javascript" src="https://cdn.bootcss.com/echarts/3.7.0/echarts.min.js"></script>
<div class="site-about">
<h1><?= Html::encode($this->title) ?></h1>
<div id="main" style="width: 800px;height:400px;float:left;"></div>
</div>
<script type="text/javascript" >
// 基于准备好的dom,初始化echarts实例
var chartDom = document.getElementById('main');
var myChartz = echarts.init(chartDom);
var option;
var meeting = 3;
var categoryCount = 18;
var xAxisData = [];
var customData = [];
var legendData = [];
var dataList = [];
legendData.push('trend');
var encodeY = [];
for (var i = 0; i < meeting; i++) {
legendData.push(('ICCV') + '');
legendData.push(('ECCV') + '');
legendData.push(('CVPR') + '');
dataList.push([]);
encodeY.push(1 + i);
}
for (var i = 0; i < categoryCount; i++) {
var val = Math.random() * 1000;
xAxisData.push(i+2003);
var customVal = [i];
customData.push(customVal);
for (var j = 0; j < dataList.length; j++) {
var value = j === 0
? echarts.number.round(val, 2)
: echarts.number.round(Math.max(0, dataList[j - 1][i] + (Math.random() - 0.5) * 200), 2);
dataList[j].push(value);
customVal.push(value);
}
}
function renderItem(params, api) {
var xValue = api.value(0);
var currentSeriesIndices = api.currentSeriesIndices();
var barLayout = api.barLayout({
barGap: '30%', barCategoryGap: '20%', count: currentSeriesIndices.length - 1
});
var points = [];
for (var i = 0; i < currentSeriesIndices.length; i++) {
var seriesIndex = currentSeriesIndices[i];
if (seriesIndex !== params.seriesIndex) {
var point = api.coord([xValue, api.value(seriesIndex)]);
point[0] += barLayout[i - 1].offsetCenter;
point[1] -= 20;
points.push(point);
}
}
var style = api.style({
stroke: api.visual('color'),
fill: null
});
return {
type: 'polyline',
shape: {
points: points
},
style: style
};
}
option = {
title: {
text: '论文数量对比',
},
tooltip: {
trigger: 'axis'
},
legend: {
data: legendData
},
dataZoom: [{
type: 'slider',
start: 50,
end: 70
}, {
type: 'inside',
start: 50,
end: 70
}],
xAxis: {
data: xAxisData
},
yAxis: {},
series: [{
type: 'custom',
name: 'trend',
renderItem: renderItem,
itemStyle: {
borderWidth: 2
},
encode: {
x: 0,
y: encodeY
},
data: customData,
z: 100
}].concat(dataList.map(function (data, index) {
return {
type: 'bar',
animation: false,
name: legendData[index + 1],
itemStyle: {
opacity: 0.5
},
data: data
};
}))
};
option && myChartz.setOption(option);
</script>
<div id="main2" style="width: 550px;height:400px;float:left;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main2'));
var p=<?php echo json_encode($pdata) ?>;
var js_arr = p.map(item => {
return Object.values(item)
})
// 指定图表的配置项和数据
var option2 = {
series : [
{
name: '评论详情',
type: 'pie',
radius: 120,
data:[
{value:js_arr[0][2], name:js_arr[0][1],url:"https://doi.org/10.1007/978-3-030-01228-1_48"},
{value:js_arr[1][2], name:js_arr[1][1],url:"https://doi.org/10.1007/978-3-030-58568-6_33"},
{value:js_arr[2][2], name:js_arr[2][1],url:"https://doi.org/10.1007/978-3-030-01231-1_4"},
{value:js_arr[3][2], name:js_arr[3][1],url:"https://doi.org/10.1109/CVPR.2000.854723"},
{value:js_arr[4][2], name:js_arr[4][1],url:"https://doi.org/10.1007/978-3-030-01231-1_27"},
{value:js_arr[5][2], name:js_arr[5][1],url:"https://doi.org/10.1007/978-3-030-01216-8_6"},
{value:js_arr[6][2], name:js_arr[6][1],url:"https://doi.org/10.1007/978-3-030-11018-5_6"},
{value:js_arr[7][2], name:js_arr[7][1],url:"https://doi.org/10.1007/978-3-030-01225-0_36"},
{value:js_arr[8][2], name:js_arr[8][1],url:"https://doi.org/10.1007/978-3-030-01231-1_10"},
{value:js_arr[9][2], name:js_arr[9][1],url:"https://doi.org/10.1007/978-3-030-01216-8_39"},
],
//roseType: 'angle',
itemStyle: {
normal: {
shadowBlur: 200,
shadowColor: 'rgba(0, 0, 0, 0.5)',
label:{
show: true,
formatter: '{b} : {c} ({d}%)'
},
}
}
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option2);
myChart.on('click',function(params){
var url=params.data.url;
window.location.href=url;
})
</script>
</div>
</div>
]
};
option && myChartz.setOption(option);
</script>
<div id="main2" style="width: 550px;height:400px;float:left;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main2'));
var p=<?php echo json_encode($pdata) ?>;
var js_arr = p.map(item => {
return Object.values(item)
})
// 指定图表的配置项和数据
var option2 = {
series : [
{
name: '评论详情',
type: 'pie',
radius: 120,
data:[
{value:js_arr[0][2], name:js_arr[0][1],url:"https://doi.org/10.1007/978-3-030-01228-1_48"},
{value:js_arr[1][2], name:js_arr[1][1],url:"https://doi.org/10.1007/978-3-030-58568-6_33"},
{value:js_arr[2][2], name:js_arr[2][1],url:"https://doi.org/10.1007/978-3-030-01231-1_4"},
{value:js_arr[3][2], name:js_arr[3][1],url:"https://doi.org/10.1109/CVPR.2000.854723"},
{value:js_arr[4][2], name:js_arr[4][1],url:"https://doi.org/10.1007/978-3-030-01231-1_27"},
{value:js_arr[5][2], name:js_arr[5][1],url:"https://doi.org/10.1007/978-3-030-01216-8_6"},
{value:js_arr[6][2], name:js_arr[6][1],url:"https://doi.org/10.1007/978-3-030-11018-5_6"},
{value:js_arr[7][2], name:js_arr[7][1],url:"https://doi.org/10.1007/978-3-030-01225-0_36"},
{value:js_arr[8][2], name:js_arr[8][1],url:"https://doi.org/10.1007/978-3-030-01231-1_10"},
{value:js_arr[9][2], name:js_arr[9][1],url:"https://doi.org/10.1007/978-3-030-01216-8_39"},
],
//roseType: 'angle',
itemStyle: {
normal: {
shadowBlur: 200,
shadowColor: 'rgba(0, 0, 0, 0.5)',
label:{
show: true,
formatter: '{b} : {c} ({d}%)'
},
}
}
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option2);
myChart.on('click',function(params){
var url=params.data.url;
window.location.href=url;
})
</script>
</div>
</div>
心路历程
张吴晗:这次结对作业到这也就结束了,从刚拿到题目时候两个人的两脸懵逼到两个人齐心协力共同完成此次作业,心情还是像坐过山车一样。无论是对于php和JavaScript的使用,还是对于yii2.0框架的掌握,我从中收获颇丰。张富源同学对于页面设计方面有着独特的见解,能够使得页面看起来更加美观,在编程过程中,对于我提出的问题也会进行耐心的回答,编程出现的问题也能与我进行积极的讨论,一起查阅资料去解决。
张富源:这次作业是难忘的对于没有什么网站开发经验的我来说是一次挑战,需要快速学习php语言,yii框架学习,学习新技术的路上是兴奋又紧张的,每一门技术的学习都是一门挑战,也是提高自己专业能力的台阶。和队友共同开发这个项目不至于一个人开发那样手足无措。我不会的他可能会,他不会的我可能会,都不会的知识也是一起学习。张吴晗同学对新技术有较高的兴趣,我经常向他请教。他也能耐心的回答我的问题。