mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-09-12 06:48:50 +02:00
Added Session Calendar to Player page (#115 50%)
This commit is contained in:
parent
d19b929564
commit
e2d11e6dfe
@ -25,6 +25,7 @@ import com.djrapitops.plan.utilities.comparators.SessionStartComparator;
|
||||
import com.djrapitops.plan.utilities.file.FileUtil;
|
||||
import com.djrapitops.plan.utilities.html.HtmlStructure;
|
||||
import com.djrapitops.plan.utilities.html.HtmlUtils;
|
||||
import com.djrapitops.plan.utilities.html.graphs.PlayerCalendar;
|
||||
import com.djrapitops.plan.utilities.html.graphs.PunchCardGraph;
|
||||
import com.djrapitops.plan.utilities.html.graphs.pie.ServerPreferencePie;
|
||||
import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie;
|
||||
@ -126,6 +127,11 @@ public class InspectPage extends Page {
|
||||
|
||||
ServerAccordion serverAccordion = new ServerAccordion(profile, serverNames);
|
||||
|
||||
PlayerCalendar playerCalendar = new PlayerCalendar(allSessions, registered);
|
||||
|
||||
addValue("calendarSeries", playerCalendar.toCalendarSeries());
|
||||
addValue("firstDay", 1);
|
||||
|
||||
addValue("accordionSessions", sessionsAccordion[0]);
|
||||
addValue("accordionServers", serverAccordion.toHtml());
|
||||
addValue("sessionTabGraphViewFunctions", sessionsAccordion[1] + serverAccordion.toViewScript());
|
||||
|
@ -47,6 +47,12 @@ public class FormatUtils {
|
||||
return formatMilliseconds(Math.abs(after - before));
|
||||
}
|
||||
|
||||
public static String formatTimeStampISO8601NoClock(long epochMs) {
|
||||
String format = "yyyy-MM-dd";
|
||||
|
||||
return format(epochMs, format);
|
||||
}
|
||||
|
||||
public static String formatTimeStampDay(long epochMs) {
|
||||
String format = "MMMMM d";
|
||||
|
||||
|
@ -137,7 +137,8 @@ public class HtmlExport extends SpecificExport {
|
||||
"web/js/charts/punchCard.js",
|
||||
"web/js/charts/serverPie.js",
|
||||
"web/js/charts/worldPie.js",
|
||||
"web/js/charts/healthGauge.js"
|
||||
"web/js/charts/healthGauge.js",
|
||||
"web/js/charts/sessionCalendar.js"
|
||||
};
|
||||
copyFromJar(resources);
|
||||
|
||||
@ -164,7 +165,10 @@ public class HtmlExport extends SpecificExport {
|
||||
"web/plugins/jquery/jquery.min.js",
|
||||
"web/plugins/bootstrap/js/bootstrap.js",
|
||||
"web/plugins/jquery-datatable/skin/bootstrap/js/dataTables.bootstrap.js",
|
||||
"web/plugins/jquery-datatable/jquery.dataTables.js"
|
||||
"web/plugins/jquery-datatable/jquery.dataTables.js",
|
||||
"web/plugins/fullcalendar/fullcalendar.min.js",
|
||||
"web/plugins/fullcalendar/fullcalendar.min.css",
|
||||
"web/plugins/momentjs/moment.js",
|
||||
};
|
||||
copyFromJar(resources);
|
||||
}
|
||||
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Licence is provided in the jar as license.yml also here:
|
||||
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
|
||||
*/
|
||||
package com.djrapitops.plan.utilities.html.graphs;
|
||||
|
||||
import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utility for creating FullCalendar calendar event array on Player page.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlayerCalendar {
|
||||
|
||||
private final List<Session> allSessions;
|
||||
private final long registered;
|
||||
|
||||
public PlayerCalendar(List<Session> allSessions, long registered) {
|
||||
this.allSessions = allSessions;
|
||||
this.registered = registered;
|
||||
}
|
||||
|
||||
public String toCalendarSeries() {
|
||||
StringBuilder series = new StringBuilder("[");
|
||||
|
||||
appendRegister(series);
|
||||
appendDailyPlaytime(series);
|
||||
appendSessionsAndKills(series);
|
||||
|
||||
return series.append("]").toString();
|
||||
}
|
||||
|
||||
private void appendDailyPlaytime(StringBuilder series) {
|
||||
Map<String, List<Session>> sessionsByDay = getSessionsByDay();
|
||||
|
||||
for (Map.Entry<String, List<Session>> entry : sessionsByDay.entrySet()) {
|
||||
String day = entry.getKey();
|
||||
|
||||
List<Session> sessions = entry.getValue();
|
||||
int sessionCount = sessions.size();
|
||||
long playtime = sessions.stream().mapToLong(Session::getLength).sum();
|
||||
|
||||
series.append(",{title: 'Playtime: ").append(FormatUtils.formatTimeAmount(playtime))
|
||||
.append("',start:'").append(day)
|
||||
.append("',color: '#4CAF50'")
|
||||
.append("}");
|
||||
|
||||
series.append(",{title: 'Sessions: ").append(sessionCount)
|
||||
.append("',start:'").append(day)
|
||||
.append("'}");
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, List<Session>> getSessionsByDay() {
|
||||
Map<String, List<Session>> sessionsByDay = new HashMap<>();
|
||||
for (Session session : allSessions) {
|
||||
String day = FormatUtils.formatTimeStampISO8601NoClock(session.getSessionStart());
|
||||
|
||||
List<Session> sessionsOfDay = sessionsByDay.getOrDefault(day, new ArrayList<>());
|
||||
sessionsOfDay.add(session);
|
||||
sessionsByDay.put(day, sessionsOfDay);
|
||||
}
|
||||
return sessionsByDay;
|
||||
}
|
||||
|
||||
private void appendSessionsAndKills(StringBuilder series) {
|
||||
long fiveMinutes = TimeAmount.MINUTE.ms() * 5L;
|
||||
for (Session session : allSessions) {
|
||||
String length = FormatUtils.formatTimeAmount(session.getLength());
|
||||
|
||||
series.append(",{title: 'Session: ").append(length)
|
||||
.append("',start:").append(session.getSessionStart())
|
||||
.append(",end:").append(session.getSessionEnd())
|
||||
.append("}");
|
||||
|
||||
for (PlayerKill kill : session.getPlayerKills()) {
|
||||
long time = kill.getTime();
|
||||
|
||||
series.append(",{title: 'Killed: ").append(kill.getVictim())
|
||||
.append("',start:").append(time)
|
||||
.append(",end:").append(time + fiveMinutes)
|
||||
.append(",color: 'red'")
|
||||
.append("}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void appendRegister(StringBuilder series) {
|
||||
String registered = FormatUtils.formatTimeStampYear(this.registered);
|
||||
|
||||
series.append("{title: 'Registered: ").append(registered).append("'," +
|
||||
"start: ").append(this.registered).append(",color: '#8BC34A'}");
|
||||
}
|
||||
}
|
30
Plan/src/main/resources/web/js/charts/sessionCalendar.js
Normal file
30
Plan/src/main/resources/web/js/charts/sessionCalendar.js
Normal file
@ -0,0 +1,30 @@
|
||||
function sessionCalendar(id, events, firstDay) {
|
||||
$(id).fullCalendar({
|
||||
eventColor: '#009688',
|
||||
eventLimit: true,
|
||||
firstDay: firstDay,
|
||||
|
||||
eventRender: function (eventObj, $el) {
|
||||
$el.popover({
|
||||
content: eventObj.title,
|
||||
trigger: 'hover',
|
||||
placement: 'top',
|
||||
container: 'body'
|
||||
});
|
||||
},
|
||||
|
||||
events: events,
|
||||
|
||||
navLinks: true,
|
||||
height: 'parent',
|
||||
header: {
|
||||
left: 'title',
|
||||
center: '',
|
||||
right: 'month agendaWeek agendaDay prev,next'
|
||||
}
|
||||
});
|
||||
|
||||
setTimeout(function () {
|
||||
$(id).fullCalendar('render')
|
||||
}, 1000);
|
||||
}
|
@ -450,6 +450,26 @@
|
||||
<div class="row clearfix">
|
||||
<!-- Sessions -->
|
||||
<div class="col-xs-12 col-sm-12 col-md-8 col-lg-8">
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<div class="row clearfix">
|
||||
<div class="col-xs-6 col-sm-6 col-lg-6">
|
||||
<h2><i class="col-teal fa fa-calendar-o"></i> Session Calendar</h2>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-lg-6">
|
||||
<a href="javascript:void(0)" class="help material-icons pull-right"
|
||||
data-trigger="focus" data-toggle="popover" data-placement="left"
|
||||
data-container="body" data-html="true"
|
||||
data-original-title="Session Calendar"
|
||||
data-content="Calendar that contains information about sessions for each day.<br><br>Day numbers can be clicked to inspect a particular day in higher detail.<br><br>If a title is not visible you can hover over the box to see the title."
|
||||
>help_outline</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div id="sessionCalendar" style="height: 500px;" class="dashboard-flot-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<div class="row clearfix">
|
||||
@ -646,6 +666,11 @@
|
||||
<script src="https://code.highcharts.com/modules/drilldown.js"></script>
|
||||
<script src="https://code.highcharts.com/modules/no-data-to-display.js"></script>
|
||||
|
||||
<!-- FullCalendar -->
|
||||
<link rel='stylesheet' href='../plugins/fullcalendar/fullcalendar.min.css'/>
|
||||
<script src='../plugins/momentjs/moment.js'></script>
|
||||
<script src='../plugins/fullcalendar/fullcalendar.min.js'></script>
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<script src="../plugins/font-awesome/fa-script.js"></script>
|
||||
|
||||
@ -656,13 +681,14 @@
|
||||
<script src="../js/charts/punchCard.js"></script>
|
||||
<script src="../js/charts/serverPie.js"></script>
|
||||
<script src="../js/charts/worldPie.js"></script>
|
||||
<script src="../js/charts/sessionCalendar.js"></script>
|
||||
|
||||
<!-- Chart Data -->
|
||||
<script>
|
||||
Highcharts.setOptions({
|
||||
time: {
|
||||
timezoneOffset: ${timeZone} * 60
|
||||
}
|
||||
}
|
||||
})
|
||||
var serverSeries = {
|
||||
name: 'Server Playtime',
|
||||
@ -682,12 +708,15 @@
|
||||
color: '#222',
|
||||
data: ${punchCardSeries}
|
||||
};
|
||||
var calendarSeries =;
|
||||
${calendarSeries}
|
||||
var firstDay =
|
||||
${firstDay}
|
||||
</script>
|
||||
|
||||
<!-- Plan laod script -->
|
||||
<script>
|
||||
$(function () {
|
||||
|
||||
$('.player-table').DataTable({
|
||||
responsive: true
|
||||
});
|
||||
@ -712,6 +741,7 @@
|
||||
worldPie('worldPie', worldSeries, gmSeries);
|
||||
serverPie('serverPie', serverSeries);
|
||||
punchCard('punchCard', punchcardSeries);
|
||||
sessionCalendar('#sessionCalendar', calendarSeries, firstDay);
|
||||
${sessionTabGraphViewFunctions}
|
||||
|
||||
/**/
|
||||
|
Loading…
Reference in New Issue
Block a user