Merge branch '18-statistics-page' into 'master'
Resolve "Страница со статистикой" Closes #18 See merge request romanov73/git-extractor!14
This commit is contained in:
commit
7c59b3630c
@ -64,6 +64,7 @@ dependencies {
|
|||||||
compile group: 'org.webjars', name: 'bootstrap', version: '4.6.0'
|
compile group: 'org.webjars', name: 'bootstrap', version: '4.6.0'
|
||||||
compile group: 'org.webjars', name: 'bootstrap-select', version: '1.13.8'
|
compile group: 'org.webjars', name: 'bootstrap-select', version: '1.13.8'
|
||||||
compile group: 'org.webjars', name: 'font-awesome', version: '4.7.0'
|
compile group: 'org.webjars', name: 'font-awesome', version: '4.7.0'
|
||||||
|
compile group: 'org.webjars', name: 'highcharts', version: '7.0.0'
|
||||||
|
|
||||||
testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test'
|
testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test'
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ public class Route {
|
|||||||
public static final String LIST_REPOSITORY_BRANCHES = "listBranches";
|
public static final String LIST_REPOSITORY_BRANCHES = "listBranches";
|
||||||
public static final String INDEXING_NEW_REPOSITORY = "indexNewRepository";
|
public static final String INDEXING_NEW_REPOSITORY = "indexNewRepository";
|
||||||
public static final String FILTER_COMMITS = "filterCommits";
|
public static final String FILTER_COMMITS = "filterCommits";
|
||||||
|
public static final String STATISTIC = "statistic";
|
||||||
|
|
||||||
public static String getLIST_INDEXED_REPOSITORIES() {
|
public static String getLIST_INDEXED_REPOSITORIES() {
|
||||||
return LIST_INDEXED_REPOSITORIES;
|
return LIST_INDEXED_REPOSITORIES;
|
||||||
@ -29,4 +30,8 @@ public class Route {
|
|||||||
public static String getFILTER_COMMITS() {
|
public static String getFILTER_COMMITS() {
|
||||||
return FILTER_COMMITS;
|
return FILTER_COMMITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getSTATISTIC() {
|
||||||
|
return STATISTIC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||||
|
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ru.ulstu.extractor.controller;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import ru.ulstu.extractor.repository.CommitRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static ru.ulstu.extractor.controller.Route.STATISTIC;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class StatisticController {
|
||||||
|
private final CommitRepository commitRepository;
|
||||||
|
|
||||||
|
public StatisticController(CommitRepository commitRepository) {
|
||||||
|
this.commitRepository = commitRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(STATISTIC)
|
||||||
|
public String indexBranch(Model model) {
|
||||||
|
List<Object[]> authorCommits = commitRepository.getCommitAuthorStatistic().stream()
|
||||||
|
.map(stat -> new Object[]{stat.getAuthor(), stat.getCountCommit()})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
model.addAttribute("commitAuthorData", authorCommits);
|
||||||
|
List<Object[]> urlCommits = commitRepository.getCommitUrlStatistic().stream()
|
||||||
|
.map(stat -> new Object[]{stat.getUrl(), stat.getCountCommit()})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
model.addAttribute("commitUrlData", urlCommits);
|
||||||
|
List<Object[]> timeCommits = commitRepository.getCommitTimeStatistic().stream()
|
||||||
|
.map(stat -> new Object[]{stat.getDate(), stat.getCountCommit()})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
model.addAttribute("commitTimeData", timeCommits);
|
||||||
|
String[] date = new String[timeCommits.size()];
|
||||||
|
for (int i = 0; i < timeCommits.size(); i++) {
|
||||||
|
date[i] = timeCommits.get(i)[0].toString();
|
||||||
|
}
|
||||||
|
model.addAttribute("dates", date);
|
||||||
|
String[] url = new String[urlCommits.size()];
|
||||||
|
for (int i = 0; i < urlCommits.size(); i++) {
|
||||||
|
url[i] = urlCommits.get(i)[0].toString().substring(urlCommits.get(i)[0].toString().lastIndexOf("/") + 1);
|
||||||
|
}
|
||||||
|
model.addAttribute("urls", url);
|
||||||
|
|
||||||
|
return STATISTIC;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package ru.ulstu.extractor.model;
|
||||||
|
|
||||||
|
public class CommitAuthorStatistic {
|
||||||
|
private String author;
|
||||||
|
private Long countCommit;
|
||||||
|
|
||||||
|
public CommitAuthorStatistic(String author, Long countCommit) {
|
||||||
|
this.author = author;
|
||||||
|
this.countCommit = countCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthor() {
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getCountCommit() {
|
||||||
|
return countCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package ru.ulstu.extractor.model;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class CommitTimeStatistic {
|
||||||
|
private Date date;
|
||||||
|
private Long countCommit;
|
||||||
|
|
||||||
|
public CommitTimeStatistic(Date date, Long countCommit) {
|
||||||
|
this.date = date;
|
||||||
|
this.countCommit = countCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getCountCommit() {
|
||||||
|
return countCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package ru.ulstu.extractor.model;
|
||||||
|
|
||||||
|
public class CommitUrlStatistic {
|
||||||
|
private String url;
|
||||||
|
private Long countCommit;
|
||||||
|
|
||||||
|
public CommitUrlStatistic(String url, Long countCommit) {
|
||||||
|
this.url = url;
|
||||||
|
this.countCommit = countCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getCountCommit() {
|
||||||
|
return countCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,3 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||||
|
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||||
|
*/
|
||||||
|
|
||||||
package ru.ulstu.extractor.repository;
|
package ru.ulstu.extractor.repository;
|
||||||
|
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@ -6,9 +11,24 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
|||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
import ru.ulstu.extractor.model.Commit;
|
import ru.ulstu.extractor.model.Commit;
|
||||||
|
import ru.ulstu.extractor.model.CommitAuthorStatistic;
|
||||||
|
import ru.ulstu.extractor.model.CommitTimeStatistic;
|
||||||
|
import ru.ulstu.extractor.model.CommitUrlStatistic;
|
||||||
import ru.ulstu.extractor.model.Repository;
|
import ru.ulstu.extractor.model.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface CommitRepository extends JpaRepository<Commit, Integer> {
|
public interface CommitRepository extends JpaRepository<Commit, Integer> {
|
||||||
@Query("SELECT c FROM Commit c, Repository r, Branch b WHERE c.branch = b AND r = b.repository AND r = :repository AND b.name = :branchName")
|
@Query("SELECT c FROM Commit c, Repository r, Branch b WHERE c.branch = b AND r = b.repository AND r = :repository AND b.name = :branchName")
|
||||||
Page<Commit> findByRepositoryAndBranch(Pageable pageable, @Param("repository") Repository repository, @Param("branchName") String branchName);
|
Page<Commit> findByRepositoryAndBranch(Pageable pageable, @Param("repository") Repository repository, @Param("branchName") String branchName);
|
||||||
|
|
||||||
|
@Query("SELECT new ru.ulstu.extractor.model.CommitAuthorStatistic(c.author.name, COUNT(DISTINCT c.hash)) FROM Commit c GROUP by c.author.name")
|
||||||
|
List<CommitAuthorStatistic> getCommitAuthorStatistic();
|
||||||
|
|
||||||
|
@Query("SELECT new ru.ulstu.extractor.model.CommitUrlStatistic(c.branch.repository.url, COUNT(DISTINCT c.hash)) FROM Commit c GROUP by c.branch.repository.url")
|
||||||
|
List<CommitUrlStatistic> getCommitUrlStatistic();
|
||||||
|
|
||||||
|
@Query("SELECT new ru.ulstu.extractor.model.CommitTimeStatistic(cast(c.date as date), COUNT(DISTINCT c.hash)) FROM Commit c GROUP by cast(c.date as date) ORDER by cast(c.date as date)")
|
||||||
|
List<CommitTimeStatistic> getCommitTimeStatistic();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||||
|
# You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||||
|
#
|
||||||
|
|
||||||
messages.app-name=GitExtractor v0.1.0
|
messages.app-name=GitExtractor v0.1.0
|
||||||
messages.menu.home=Main
|
messages.menu.home=Main
|
||||||
messages.menu.indexed-repos=List of indexed repos
|
messages.menu.indexed-repos=List of indexed repos
|
||||||
messages.menu.new-repo=Analyse new repo
|
messages.menu.new-repo=Analyse new repo
|
||||||
|
messages.menu.statistic=Statistic
|
@ -1,4 +1,10 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||||
|
# You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||||
|
#
|
||||||
|
|
||||||
messages.app-name=GitExtractor v0.1.0
|
messages.app-name=GitExtractor v0.1.0
|
||||||
messages.menu.home=Main
|
messages.menu.home=Main
|
||||||
messages.menu.indexed-repos=List of indexed repos
|
messages.menu.indexed-repos=List of indexed repos
|
||||||
messages.menu.new-repo=Analyse new repo
|
messages.menu.new-repo=Analyse new repo
|
||||||
|
messages.menu.statistic=Statistic
|
@ -1,4 +1,10 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||||
|
# You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||||
|
#
|
||||||
|
|
||||||
messages.app-name=GitЁxtractor v0.1.0
|
messages.app-name=GitЁxtractor v0.1.0
|
||||||
messages.menu.home=На главную
|
messages.menu.home=На главную
|
||||||
messages.menu.indexed-repos=Список проиндексированных репозиториев
|
messages.menu.indexed-repos=Список проиндексированных репозиториев
|
||||||
messages.menu.new-repo=Анализ нового репозитория
|
messages.menu.new-repo=Анализ нового репозитория
|
||||||
|
messages.menu.statistic=Статистика
|
@ -34,6 +34,9 @@
|
|||||||
<a class="nav-link" th:href="${@route.LIST_INDEXED_REPOSITORIES}"
|
<a class="nav-link" th:href="${@route.LIST_INDEXED_REPOSITORIES}"
|
||||||
th:text="#{messages.menu.indexed-repos}">Link</a>
|
th:text="#{messages.menu.indexed-repos}">Link</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/statistic" th:text="#{messages.menu.statistic}">Link</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
183
src/main/resources/templates/statistic.html
Normal file
183
src/main/resources/templates/statistic.html
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
<!--
|
||||||
|
~ Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||||
|
~ You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
|
||||||
|
<html
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.w3.org/1999/xhtml"
|
||||||
|
layout:decorate="~{default}">
|
||||||
|
<head>
|
||||||
|
<title>Простая обработка формы на Spring MVC</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
|
</head>
|
||||||
|
<div class="container" layout:fragment="content">
|
||||||
|
<script src="/webjars/highcharts/7.0.0/highcharts.js"></script>
|
||||||
|
<script th:inline="javascript">
|
||||||
|
$(document).ready(function () {
|
||||||
|
var chart = {
|
||||||
|
type: 'scatter',
|
||||||
|
zoomType: 'xy'
|
||||||
|
};
|
||||||
|
var title = {
|
||||||
|
text: 'Количество коммитов во времени'
|
||||||
|
};
|
||||||
|
var xAxis = {
|
||||||
|
categories: [[${dates}]],
|
||||||
|
title: {
|
||||||
|
enabled: true,
|
||||||
|
text: 'Дата'
|
||||||
|
},
|
||||||
|
startOnTick: true,
|
||||||
|
endOnTick: true,
|
||||||
|
showLastLabel: true
|
||||||
|
};
|
||||||
|
var yAxis = {
|
||||||
|
title: {
|
||||||
|
text: 'Кол-во коммитов'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var plotOptions = {
|
||||||
|
scatter: {
|
||||||
|
marker: {
|
||||||
|
radius: 5,
|
||||||
|
states: {
|
||||||
|
hover: {
|
||||||
|
enabled: true,
|
||||||
|
lineColor: 'rgb(100,100,100)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
states: {
|
||||||
|
hover: {
|
||||||
|
marker: {
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
headerFormat: '<b>{series.name}</b><br>',
|
||||||
|
pointFormat: '{point.y} commits'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var series = [
|
||||||
|
{
|
||||||
|
name: 'Коммиты',
|
||||||
|
color: 'rgba(119,152,191,0.5)',
|
||||||
|
data: [[${commitTimeData}]]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
var json = {};
|
||||||
|
json.chart = chart;
|
||||||
|
json.title = title;
|
||||||
|
json.xAxis = xAxis;
|
||||||
|
json.yAxis = yAxis;
|
||||||
|
json.series = series;
|
||||||
|
json.plotOptions = plotOptions;
|
||||||
|
$('#container').highcharts(json);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<script th:inline="javascript">
|
||||||
|
$(document).ready(function () {
|
||||||
|
var chart = {
|
||||||
|
plotBackgroundColor: null,
|
||||||
|
plotBorderWidth: null,
|
||||||
|
plotShadow: false
|
||||||
|
};
|
||||||
|
var title = {
|
||||||
|
text: '% коммитов авторов'
|
||||||
|
};
|
||||||
|
var tooltip = {
|
||||||
|
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
|
||||||
|
};
|
||||||
|
var plotOptions = {
|
||||||
|
pie: {
|
||||||
|
allowPointSelect: true,
|
||||||
|
cursor: 'pointer',
|
||||||
|
dataLabels: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
showInLegend: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var series = [{
|
||||||
|
type: 'pie',
|
||||||
|
name: 'Browser share',
|
||||||
|
data: [[${commitAuthorData}]]
|
||||||
|
}];
|
||||||
|
|
||||||
|
var json = {};
|
||||||
|
json.chart = chart;
|
||||||
|
json.title = title;
|
||||||
|
json.tooltip = tooltip;
|
||||||
|
json.series = series;
|
||||||
|
json.plotOptions = plotOptions;
|
||||||
|
$('#containerPie').highcharts(json);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<script th:inline="javascript">
|
||||||
|
$(document).ready(function () {
|
||||||
|
var chart = {
|
||||||
|
type: 'column'
|
||||||
|
};
|
||||||
|
var title = {
|
||||||
|
text: 'Количество коммитов'
|
||||||
|
};
|
||||||
|
var xAxis = {
|
||||||
|
categories: [[${urls}]],
|
||||||
|
crosshair: true,
|
||||||
|
title: {
|
||||||
|
text: 'Репозиторий'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var yAxis = {
|
||||||
|
min: 0,
|
||||||
|
title: {
|
||||||
|
text: 'Кол-во'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var tooltip = {
|
||||||
|
headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
|
||||||
|
pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
|
||||||
|
'<td style="padding:0"><b>{point.y:.1f}</b></td></tr>',
|
||||||
|
footerFormat: '</table>',
|
||||||
|
shared: true,
|
||||||
|
useHTML: true
|
||||||
|
};
|
||||||
|
var plotOptions = {
|
||||||
|
column: {
|
||||||
|
pointPadding: 0.2,
|
||||||
|
borderWidth: 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var credits = {
|
||||||
|
enabled: false
|
||||||
|
};
|
||||||
|
|
||||||
|
var series = [{
|
||||||
|
name: 'Коммиты',
|
||||||
|
data: [[${commitUrlData}]]
|
||||||
|
}];
|
||||||
|
|
||||||
|
var json = {};
|
||||||
|
json.chart = chart;
|
||||||
|
json.title = title;
|
||||||
|
json.tooltip = tooltip;
|
||||||
|
json.xAxis = xAxis;
|
||||||
|
json.yAxis = yAxis;
|
||||||
|
json.series = series;
|
||||||
|
json.plotOptions = plotOptions;
|
||||||
|
json.credits = credits;
|
||||||
|
$('#containerColumn').highcharts(json);
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<div class="row">
|
||||||
|
<div id="container" style="width: 550px; height: 400px; margin: 0 auto"></div>
|
||||||
|
<div id="containerPie" style="width: 550px; height: 400px; margin: 0 auto"></div>
|
||||||
|
<div id="containerColumn" style="width: 550px; height: 400px; margin: 0 auto"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user