mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-15 05:41:51 +08:00
Added Session Calendar to Server page (#115 100%)
This commit is contained in:
parent
e2d11e6dfe
commit
517ffa0bcf
@ -23,6 +23,7 @@ import com.djrapitops.plan.utilities.html.Html;
|
||||
import com.djrapitops.plan.utilities.html.graphs.ActivityStackGraph;
|
||||
import com.djrapitops.plan.utilities.html.graphs.PunchCardGraph;
|
||||
import com.djrapitops.plan.utilities.html.graphs.WorldMap;
|
||||
import com.djrapitops.plan.utilities.html.graphs.calendar.ServerCalendar;
|
||||
import com.djrapitops.plan.utilities.html.graphs.line.*;
|
||||
import com.djrapitops.plan.utilities.html.graphs.pie.ActivityPie;
|
||||
import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie;
|
||||
@ -128,6 +129,11 @@ public class AnalysisData extends RawData {
|
||||
geolocationsTab(geoLocations);
|
||||
commandUsage(commandUsage);
|
||||
|
||||
List<Long> registered = profile.getPlayers().stream().map(PlayerProfile::getRegistered).collect(Collectors.toList());
|
||||
ServerCalendar serverCalendar = new ServerCalendar(registered, sessions);
|
||||
addValue("calendarSeries", serverCalendar.toCalendarSeries());
|
||||
addValue("firstDay", 1);
|
||||
|
||||
addValue("ops", ops.size());
|
||||
addValue("playersTotal", playersTotal);
|
||||
|
||||
|
@ -25,8 +25,8 @@ 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.calendar.PlayerCalendar;
|
||||
import com.djrapitops.plan.utilities.html.graphs.pie.ServerPreferencePie;
|
||||
import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie;
|
||||
import com.djrapitops.plan.utilities.html.structure.ServerAccordion;
|
||||
|
@ -138,7 +138,8 @@ public class HtmlExport extends SpecificExport {
|
||||
"web/js/charts/serverPie.js",
|
||||
"web/js/charts/worldPie.js",
|
||||
"web/js/charts/healthGauge.js",
|
||||
"web/js/charts/sessionCalendar.js"
|
||||
"web/js/charts/sessionCalendar.js",
|
||||
"web/js/charts/onlineActivityCalendar.js"
|
||||
};
|
||||
copyFromJar(resources);
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 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;
|
||||
package com.djrapitops.plan.utilities.html.graphs.calendar;
|
||||
|
||||
import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.data.container.Session;
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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.calendar;
|
||||
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Utility for creating FullCalendar calendar event array on Player page.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ServerCalendar {
|
||||
|
||||
private final List<Long> registerDates;
|
||||
private final Map<UUID, List<Session>> sessions;
|
||||
|
||||
public ServerCalendar(List<Long> registerDates, Map<UUID, List<Session>> sessions) {
|
||||
this.registerDates = registerDates;
|
||||
this.sessions = sessions;
|
||||
}
|
||||
|
||||
public String toCalendarSeries() {
|
||||
StringBuilder series = new StringBuilder("[");
|
||||
|
||||
series.append("{title: 'badcode',start:0}");
|
||||
appendSessionRelatedData(series);
|
||||
appendRegistered(series);
|
||||
|
||||
return series.append("]").toString();
|
||||
}
|
||||
|
||||
private void appendRegistered(StringBuilder series) {
|
||||
Map<String, Integer> registeredByDay = getRegisteredByDay();
|
||||
|
||||
for (Map.Entry<String, Integer> entry : registeredByDay.entrySet()) {
|
||||
String day = entry.getKey();
|
||||
Integer newPlayers = entry.getValue();
|
||||
|
||||
series.append(",{title: 'New: ").append(newPlayers)
|
||||
.append("',start:'").append(day)
|
||||
.append("',color: '#8BC34A'")
|
||||
.append("}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void appendSessionRelatedData(StringBuilder series) {
|
||||
Map<String, Map<UUID, List<Session>>> sessionsByDay = getSessionsByDay();
|
||||
|
||||
for (Map.Entry<String, Map<UUID, List<Session>>> entry : sessionsByDay.entrySet()) {
|
||||
String day = entry.getKey();
|
||||
|
||||
Map<UUID, List<Session>> sessionsPerUsers = entry.getValue();
|
||||
long sessionCount = sessionsPerUsers.values().stream().mapToLong(Collection::size).sum();
|
||||
long playtime = sessionsPerUsers.values().stream().flatMap(Collection::stream).mapToLong(Session::getLength).sum();
|
||||
long uniquePlayers = sessionsPerUsers.size();
|
||||
|
||||
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("',color: '#009688'")
|
||||
.append("}");
|
||||
|
||||
series.append(",{title: 'Unique: ").append(uniquePlayers)
|
||||
.append("',start:'").append(day)
|
||||
.append("'}");
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Map<UUID, List<Session>>> getSessionsByDay() {
|
||||
Map<String, Map<UUID, List<Session>>> sessionsByDay = new HashMap<>();
|
||||
for (Map.Entry<UUID, List<Session>> entry : sessions.entrySet()) {
|
||||
UUID player = entry.getKey();
|
||||
List<Session> sessions = entry.getValue();
|
||||
|
||||
for (Session session : sessions) {
|
||||
String day = FormatUtils.formatTimeStampISO8601NoClock(session.getSessionStart());
|
||||
|
||||
Map<UUID, List<Session>> sessionsPerUserOfDay = sessionsByDay.getOrDefault(day, new HashMap<>());
|
||||
List<Session> sessionsOfUser = sessionsPerUserOfDay.getOrDefault(player, new ArrayList<>());
|
||||
sessionsOfUser.add(session);
|
||||
sessionsPerUserOfDay.put(player, sessionsOfUser);
|
||||
sessionsByDay.put(day, sessionsPerUserOfDay);
|
||||
}
|
||||
}
|
||||
return sessionsByDay;
|
||||
}
|
||||
|
||||
private Map<String, Integer> getRegisteredByDay() {
|
||||
Map<String, Integer> RegisteredByDay = new HashMap<>();
|
||||
for (Long registered : registerDates) {
|
||||
String day = FormatUtils.formatTimeStampISO8601NoClock(registered);
|
||||
|
||||
int registeredPerDay = RegisteredByDay.getOrDefault(day, 0);
|
||||
registeredPerDay += 1;
|
||||
RegisteredByDay.put(day, registeredPerDay);
|
||||
}
|
||||
return RegisteredByDay;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
function onlineActivityCalendar(id, events, firstDay) {
|
||||
$(id).fullCalendar({
|
||||
eventColor: '#2196F3',
|
||||
firstDay: firstDay,
|
||||
|
||||
eventRender: function (eventObj, $el) {
|
||||
$el.popover({
|
||||
content: eventObj.title,
|
||||
trigger: 'hover',
|
||||
placement: 'top',
|
||||
container: 'body'
|
||||
});
|
||||
},
|
||||
|
||||
events: events,
|
||||
|
||||
height: 'parent',
|
||||
header: {
|
||||
left: 'title',
|
||||
center: '',
|
||||
right: 'month prev,next'
|
||||
}
|
||||
});
|
||||
|
||||
setTimeout(function () {
|
||||
$(id).fullCalendar('render')
|
||||
}, 1000);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
function sessionCalendar(id, events, firstDay) {
|
||||
$(id).fullCalendar({
|
||||
eventColor: '#009688',
|
||||
eventLimit: true,
|
||||
eventLimit: 4,
|
||||
firstDay: firstDay,
|
||||
|
||||
eventRender: function (eventObj, $el) {
|
||||
@ -20,7 +20,7 @@ function sessionCalendar(id, events, firstDay) {
|
||||
header: {
|
||||
left: 'title',
|
||||
center: '',
|
||||
right: 'month agendaWeek agendaDay prev,next'
|
||||
right: 'month agendaWeek agendaDay today prev,next'
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -708,10 +708,8 @@
|
||||
color: '#222',
|
||||
data: ${punchCardSeries}
|
||||
};
|
||||
var calendarSeries =;
|
||||
${calendarSeries}
|
||||
var firstDay =
|
||||
${firstDay}
|
||||
var calendarSeries = ${calendarSeries};
|
||||
var firstDay = ${firstDay};
|
||||
</script>
|
||||
|
||||
<!-- Plan laod script -->
|
||||
|
@ -454,12 +454,10 @@
|
||||
<div class="row clearfix">
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<div class="body">
|
||||
<!-- Nav tabs -->
|
||||
<div class="row clearfix">
|
||||
<div class="col-xs-6 col-sm-6 col-lg-6">
|
||||
<h2><i class="col-blue fa fa-area-chart"></i> Online Activity</h2>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-lg-6">
|
||||
<div class="col-xs-12 col-sm-12 col-lg-12">
|
||||
<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"
|
||||
@ -467,33 +465,62 @@
|
||||
data-content="Chart of Player Counts, recorded by TPS task.
|
||||
<br><br>TPS task starts 50 seconds after Plan enables and records Maximum player count for each minute."
|
||||
>help_outline</a>
|
||||
<ul class="nav nav-tabs tab-nav-right" role="tablist">
|
||||
<li role="presentation" class="active"><a href="#playersOnline"
|
||||
data-toggle="tab"><i
|
||||
class="fa fa-area-chart"></i> ONLINE ACTIVITY</a></li>
|
||||
<li role="presentation"><a href="#uniqueAndNew" data-toggle="tab"><i
|
||||
class="fa fa-area-chart"></i> UNIQUE PLAYERS</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane fade in active" id="playersOnline">
|
||||
<div id="playerChartMonth" style="height: 500px;"
|
||||
class="dashboard-flot-chart"></div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane fade" id="uniqueAndNew">
|
||||
<div id="uniqueChart" style="height: 500px;" class="dashboard-flot-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div id="playerChartMonth" class="dashboard-flot-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<div class="body">
|
||||
<!-- Nav tabs -->
|
||||
<div class="row clearfix">
|
||||
<div class="col-xs-6 col-sm-6 col-lg-6">
|
||||
<h2><i class="col-black fa fa-braille"></i> Punchcard</h2>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-lg-6">
|
||||
<div class="col-xs-12 col-sm-12 col-lg-12">
|
||||
<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="Player Join PunchCard"
|
||||
data-content="Chart displays the time and days players usually join the server.<br><br>Unlike Player page punchcard, only the last 30 days are included.<br><br><b>Relative Activity:</b> Size of a dot is relative to amount of sessions started in that hour."
|
||||
data-original-title="Calendar and Punchcard"
|
||||
data-content="Chart displays the time and days players usually join the server.
|
||||
<br><br>Unlike Player page punchcard, only the last 30 days are included.
|
||||
<br><br><b>Relative Activity:</b> Size of a dot is relative to amount of sessions started in that hour."
|
||||
>help_outline</a>
|
||||
<ul class="nav nav-tabs tab-nav-right" role="tablist">
|
||||
<li role="presentation" class="active"><a href="#calendarTab"
|
||||
data-toggle="tab"><i
|
||||
class="fa fa-calendar"></i> CALENDAR</a></li>
|
||||
<li role="presentation"><a href="#punchCardTab" data-toggle="tab"><i
|
||||
class="fa fa-braille"></i> PUNCHCARD</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane fade in active" id="calendarTab">
|
||||
<div id="calendar" style="height: 500px;" class="dashboard-flot-chart"></div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane fade" id="punchCardTab">
|
||||
<div id="punchCard" style="height: 500px;" class="dashboard-flot-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div id="punchCard" class="dashboard-flot-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -1086,6 +1113,11 @@
|
||||
<!-- Header, Sidenav & Skin changer -->
|
||||
<script src="js/admin.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>
|
||||
|
||||
<!-- Plan Charts -->
|
||||
<script src="js/charts/playerGraph.js"></script>
|
||||
<script src="js/charts/punchCard.js"></script>
|
||||
@ -1098,6 +1130,7 @@
|
||||
<script src="js/charts/resourceGraph.js"></script>
|
||||
<script src="js/charts/worldGraph.js"></script>
|
||||
<script src="js/charts/worldMap.js"></script>
|
||||
<script src="js/charts/onlineActivityCalendar.js"></script>
|
||||
|
||||
<!-- Chart Data -->
|
||||
<script>
|
||||
@ -1125,7 +1158,8 @@
|
||||
},
|
||||
values: {
|
||||
tpsMed: ${tpsMedium},
|
||||
tpsHigh: ${tpsHigh}
|
||||
tpsHigh: ${tpsHigh},
|
||||
firstDay: ${firstDay}
|
||||
},
|
||||
data: {
|
||||
playersOnline: ${playersOnlineSeries},
|
||||
@ -1141,7 +1175,8 @@
|
||||
punchCard: ${punchCardSeries},
|
||||
activityStack: ${activityStackSeries},
|
||||
activityStackCategories: ${activityStackCategories},
|
||||
healthIndex: ${healthIndex}
|
||||
healthIndex: ${healthIndex},
|
||||
calendar: ${calendarSeries}
|
||||
}
|
||||
};
|
||||
|
||||
@ -1326,6 +1361,7 @@
|
||||
worldMap('worldMap', v.colors.geolocationsLow, v.colors.geolocationsHigh, series.geolocations);
|
||||
punchCard('punchCard', series.punchCard);
|
||||
healthGauge('healthGauge', [v.data.healthIndex]);
|
||||
onlineActivityCalendar('#calendar', v.data.calendar, v.values.firstDay);
|
||||
${sessionTabGraphViewFunctions}
|
||||
|
||||
/**/
|
||||
|
Loading…
Reference in New Issue
Block a user