Commit 91e0d17f authored by s7_spruge_k's avatar s7_spruge_k
Browse files

Merge branch 'graph' into 'master'

implemented graph functionality

See merge request s7_spruge_k/calendar!41
parents 0e775bd4 585b7f6c
package com.example.calendar.controller;
import java.time.LocalDate;
import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import com.example.calendar.models.Calendar;
import com.example.calendar.models.Event;
import com.example.calendar.helpers.StatHelper;
import com.example.calendar.models.User;
import com.example.calendar.repo.CalendarRepo;
import com.example.calendar.repo.EventRepo;
import com.example.calendar.repo.UserRepo;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
@Controller
public class GraphController {
@Autowired
UserRepo userRepo;
@Autowired
CalendarRepo calendarRepo;
@Autowired
EventRepo eventRepo;
public User findCurrentUser()
{
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = "";
if (principal instanceof UserDetails) {
username = ((UserDetails)principal).getUsername();
} else {
username = principal.toString();
}
User currUser = userRepo.findByUsername(username);
return currUser;
}
@GetMapping(value="/stat")
public String statGet(Model models)
{
User currUser = findCurrentUser();
//If user doesnt have calendar - redirected to create
try
{
calendarRepo.findAllByUser(currUser).get(0);
}
catch(Exception e)
{
return "redirect:/add-new-calendar";
}
return "statistics";
}
@GetMapping(value="/graph")
public String graphGet(Model models)
{
User currentUser = findCurrentUser();
try
{
calendarRepo.findAllByUser(currentUser).get(0);
}
catch(Exception e)
{
return "redirect:/add-new-calendar";
}
ArrayList<Calendar> calList = calendarRepo.findAllByUser(currentUser);
ArrayList<Integer> eventCounter = new ArrayList<>();
for (Calendar c : calList) {
int temp = 0;
if(c.getEvent().isEmpty())
{
eventCounter.add(0);
continue;
}
for (Event event : eventRepo.findAllByCalendar(c)) {
temp++;
}
eventCounter.add(temp);
}
JsonArray eventArray = new JsonArray();
for (int i = 0; i < calList.size(); i++) {
JsonObject eventJson = new JsonObject();
eventJson.addProperty("name", calList.get(i).getName());
eventJson.addProperty("eventCount", eventCounter.get(i));
eventArray.add(eventJson);
}
models.addAttribute("allEvents", eventArray);
return "graph";
}
@GetMapping(value = "/choose-cal")
public String chooseCalGet(Model model, StatHelper statHelper, String calName)
{
User currUser = findCurrentUser();
//If user doesnt have calendar - redirected to create
try
{
calendarRepo.findAllByUser(currUser);
}
catch(Exception e)
{
return "redirect:/add-new-calendar";
}
ArrayList<Calendar> allUserCalendars = calendarRepo.findAllByUser(currUser);
JsonArray calendarArray = new JsonArray();
for (int i = 0; i < allUserCalendars.size(); i++) {
JsonObject calendarJson = new JsonObject();
calendarJson.addProperty("title", allUserCalendars.get(i).getName());
calendarArray.add(calendarJson);
}
ArrayList<String> graphTypes = new ArrayList<>();
graphTypes.add("bar");
graphTypes.add("doughnut");
graphTypes.add("column");
graphTypes.add("line");
ArrayList<String> analysisTypes = new ArrayList<>();
analysisTypes.add("Analysis by day");
analysisTypes.add("Analysis by month");
model.addAttribute("analysisTypes", analysisTypes);
model.addAttribute("graphTypes", graphTypes);
model.addAttribute("calendarList", calendarArray);
return "chooseCal";
}
@PostMapping(value ="/choose-cal")
public String chooseCalPost(Model models, StatHelper statHelper, String calName)
{
statHelper.setChosenCalendar(calName);
User currUser = findCurrentUser();
try
{
calendarRepo.findAllByUser(currUser);
}
catch(Exception e)
{
return "redirect:/add-new-calendar";
}
Calendar chosenCalendar = calendarRepo.findByName(calName);
try
{
ArrayList<Event> allEventsInCal = eventRepo.findAllByCalendar(chosenCalendar);
}
catch(Exception e)
{
System.out.println("Nav event kalendara");
return "redirect:/choose-cal";
}
ArrayList<Event> allEventsInCal = eventRepo.findAllByCalendar(chosenCalendar);
if(statHelper.getStatMethod().equals("Analysis by month"))
{
ArrayList<Integer> eventCountInMonths = new ArrayList<>();
LocalDate now = LocalDate.now();
for (int i = 1; i <= 12; i++) {
int temp = 0;
for (Event e : allEventsInCal) {
if(e.getStartDate().getMonthValue() == i && now.getYear() == e.getStartDate().getYear())
{
temp++;
}
}
eventCountInMonths.add(temp);
}
ArrayList<String> monthNames = new ArrayList<>();
monthNames.add("January");
monthNames.add("February");
monthNames.add("March");
monthNames.add("April");
monthNames.add("May");
monthNames.add("June");
monthNames.add("July");
monthNames.add("August");
monthNames.add("September");
monthNames.add("October");
monthNames.add("November");
monthNames.add("December");
JsonArray eventArray = new JsonArray();
for (int i = 0; i < eventCountInMonths.size(); i++) {
JsonObject eventJson = new JsonObject();
eventJson.addProperty("name", monthNames.get(i));
eventJson.addProperty("eventCount", eventCountInMonths.get(i));
eventArray.add(eventJson);
}
String title = "Event count each month in calendar: " + statHelper.getChosenCalendar();
models.addAttribute("name", title);
models.addAttribute("allEvents", eventArray);
}
else if(statHelper.getStatMethod().equals("Analysis by day"))
{
ArrayList<Integer> eventCountThisMonth = new ArrayList<>();
LocalDate now = LocalDate.now();
for (int i = 1; i <= now.lengthOfMonth(); i++) {
int temp = 0;
for (Event e : allEventsInCal) {
if(e.getStartDate().getDayOfMonth() == i && now.getYear() == e.getStartDate().getYear())
{
temp++;
}
}
eventCountThisMonth.add(temp);
}
JsonArray eventArray = new JsonArray();
for (int i = 0; i < eventCountThisMonth.size(); i++) {
JsonObject eventJson = new JsonObject();
eventJson.addProperty("name", i+1);
eventJson.addProperty("eventCount", eventCountThisMonth.get(i));
eventArray.add(eventJson);
}
String title = "Event count this month by days: " + statHelper.getChosenCalendar();
models.addAttribute("name", title);
models.addAttribute("allEvents", eventArray);
}
models.addAttribute("graphType", statHelper.getGraphMethod());
return "stats";
}
}
package com.example.calendar.helpers;
public class StatHelper {
private String chosenCalendar;
private String statMethod;
private String graphMethod;
public StatHelper() {}
public StatHelper(String chosenCalendar, String statMethod, String graphMethod) {
this.chosenCalendar = chosenCalendar;
this.statMethod = statMethod;
this.graphMethod = graphMethod;
}
public String getChosenCalendar() {
return chosenCalendar;
}
public void setChosenCalendar(String chosenCalendar) {
this.chosenCalendar = chosenCalendar;
}
public String getStatMethod() {
return statMethod;
}
public void setStatMethod(String statMethod) {
this.statMethod = statMethod;
}
public String getGraphMethod() {
return graphMethod;
}
public void setGraphMethod(String graphMethod) {
this.graphMethod = graphMethod;
}
@Override
public String toString() {
return "StatHelper [chosenCalendar=" + chosenCalendar + ", statMethod=" + statMethod + ", graphMethod="
+ graphMethod + "]";
}
}
......@@ -10,8 +10,10 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.springframework.data.annotation.Transient;
......@@ -42,6 +44,7 @@ public class User {
@Column(name = "activeCalendar")
private String activeCalendar = "";
public User() {
}
......@@ -112,6 +115,8 @@ public class User {
this.activeCalendar = activeCalendar;
}
@Override
public String toString() {
return "ID= " + user_ID +" " +username + " password=" + password + "activeCal: " + activeCalendar;
......
......@@ -94,7 +94,7 @@ $(document).ready(function() {
navLinks: true, // can click day/week names to navigate views
editable: false,
eventLimit: true, // allow "more" link when too many events
timeFormat: 'H(:mm)',
timeFormat: 'H:mm',
events: all
......
<!DOCTYPE html>
<html xmlns:th="www.tymeleaf.org" lang="en">
<head>
<meta charset="utf-8">
<title>Choose </title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.1.0/fullcalendar.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.7/semantic.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<div class="container w-50 ">
<br><br><br> <form action="#" th:action="@{/choose-cal}" th:object="${statHelper}" method="post">
<h2 class="form-signin-heading text-center">Your calendars</h2><br>
<div class="form-group">
<label for="chooseCalendarForm">Choose a calendar</label>
<select multiple class="form-control" id="calendarSelection" th:value="${chosenCalendar}" name="calName">
</select>
</div>
<div class="form-group">
</div>
<select th:field="*{statMethod}">
<option
th:each="dropdownValue: ${analysisTypes}"
th:value="${dropdownValue}"
th:text="${dropdownValue}" ></option>
</select>
<ul>
<li th:each="radioValue: ${graphTypes}">
<input type="radio"
th:field="*{graphMethod}"
th:value="${radioValue}" />
<label
th:text="${radioValue}"></label>
</li>
</ul>
<br> <button class="btn btn-lg btn-primary btn-block" type="submit">Generate statistics!</button><br>
</form>
</div>
<input type="hidden" id="calendars" th:value="${calendarList}"/>
<script>
var x = document.getElementById("calendarSelection");
var allCalendars = JSON.parse(document.getElementById("calendars").value)
for(let i = 0; i < allCalendars.length; i++){
option = document.createElement("option");
option.text = allCalendars[i].title;
x.add(option);
}
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.1.0/fullcalendar.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.7/semantic.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>Statistics</title>
</head>
<input type="hidden" id="events" th:value="${allEvents}"/>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript">
var allEvents = JSON.parse(document.getElementById("events").value)
window.onload = function () {
var dataFromEvents = [];
for (i = 0; i < allEvents.length; i++) {
dataFromEvents[i] = {
label: allEvents[i].name,
y: allEvents[i].eventCount
}
}
console.log(dataFromEvents);
var chart = new CanvasJS.Chart("chartContainer", {
title:{
text: "Event count in your calendars"
},
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "column",
//dataPoints : dataFromEvents;
dataPoints: dataFromEvents
}
]
});
chart.render();
}
</script>
</head>
<body>
<div id="chartContainer" style="height: 300px; width: 100%;"></div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html xmlns:th="www.tymeleaf.org" lang="en">
<head>
<meta charset="utf-8">
<title>Add an Event</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.1.0/fullcalendar.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.7/semantic.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<style>
</style>
<a href="/graph">Compare Calendars </a><br>
<a href="/choose-cal">Calendar Analysis </a>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.1.0/fullcalendar.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.7/semantic.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>Statistics</title>
</head>
<input type="hidden" id="events" th:value="${allEvents}"/>
<input type="hidden" id="name" th:value="${name}"/>
<input type="hidden" id="graphType" th:value="${graphType}"/>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript">
var allEvents = JSON.parse(document.getElementById("events").value)
var name = document.getElementById("name").value
var graph = document.getElementById("graphType").value
window.onload = function () {
var dataFromEvents = [];
for (i = 0; i < allEvents.length; i++) {
dataFromEvents[i] = {
label: allEvents[i].name,
y: allEvents[i].eventCount
}
}
console.log(dataFromEvents);
var chart = new CanvasJS.Chart("chartContainer", {
title:{
text: name
},
axisX:{
interval: 1,
},
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: graph,
//dataPoints : dataFromEvents;
dataPoints: dataFromEvents
}
]
});
chart.render();