mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-09-07 04:18:26 +02:00
PunchCard for player page
This commit is contained in:
parent
c41b8c201e
commit
8862fb467c
@ -237,9 +237,10 @@ public class SessionsMutator {
|
||||
}
|
||||
|
||||
public List<Long> toSessionStarts() {
|
||||
List<Long> starts = new ArrayList<>();
|
||||
sessions.forEach(session -> starts.add(session.getDate()));
|
||||
return starts;
|
||||
return sessions.stream()
|
||||
.map(Session::getDate)
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public double toAveragePlayersOnline(PlayersOnlineResolver playersOnlineResolver) {
|
||||
|
@ -73,6 +73,7 @@ public class PlayerJSONParser {
|
||||
data.put("player_kills", player.getValue(PlayerKeys.PLAYER_KILLS).orElse(Collections.emptyList()));
|
||||
data.put("player_deaths", player.getValue(PlayerKeys.PLAYER_DEATHS).orElse(Collections.emptyList()));
|
||||
data.put("sessions", sessionsMutator.toServerNameJSONMaps(graphs, config.getWorldAliasSettings(), formatters));
|
||||
data.put("punchcard_series", graphs.special().punchCard(sessionsMutator).getDots());
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -16,15 +16,13 @@
|
||||
*/
|
||||
package com.djrapitops.plan.utilities.html.graphs.special;
|
||||
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.store.keys.SessionKeys;
|
||||
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
|
||||
import com.djrapitops.plan.utilities.html.graphs.HighChart;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Bubble Chart that represents login "punches" of players.
|
||||
@ -33,14 +31,14 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class PunchCard implements HighChart {
|
||||
|
||||
private final Collection<Session> sessions;
|
||||
private final SessionsMutator sessions;
|
||||
|
||||
/**
|
||||
* Constructor for the graph.
|
||||
*
|
||||
* @param sessions All sessions of All users this PunchCard represents.
|
||||
*/
|
||||
PunchCard(Collection<Session> sessions) {
|
||||
PunchCard(SessionsMutator sessions) {
|
||||
this.sessions = sessions;
|
||||
}
|
||||
|
||||
@ -48,7 +46,7 @@ public class PunchCard implements HighChart {
|
||||
* First number signifies the Day of Week. (0 = Monday, 6 = Sunday)
|
||||
* Second number signifies the Hour of Day. (0 = 0 AM, 23 = 11 PM)
|
||||
*/
|
||||
private List<int[]> getDaysAndHours(Collection<Long> sessionStarts) {
|
||||
private int[][] getDaysAndHours(Collection<Long> sessionStarts) {
|
||||
return sessionStarts.stream().map((Long start) -> {
|
||||
Calendar day = Calendar.getInstance();
|
||||
day.setTimeInMillis(start);
|
||||
@ -65,57 +63,48 @@ public class PunchCard implements HighChart {
|
||||
dayOfWeek = 6;
|
||||
}
|
||||
return new int[]{dayOfWeek, hourOfDay};
|
||||
}).collect(Collectors.toList());
|
||||
}).toArray(int[][]::new);
|
||||
}
|
||||
|
||||
private int[][] turnIntoArray(Collection<Long> sessionStarts) {
|
||||
List<int[]> daysAndHours = getDaysAndHours(sessionStarts);
|
||||
int[][] dataArray = createEmptyArray();
|
||||
for (int[] dAndH : daysAndHours) {
|
||||
int d = dAndH[0];
|
||||
int h = dAndH[1];
|
||||
dataArray[d][h] = dataArray[d][h] + 1;
|
||||
private int[][] turnIntoMatrix(Collection<Long> sessionStarts) {
|
||||
int[][] daysAndHours = getDaysAndHours(sessionStarts);
|
||||
int[][] matrix = createZeroMatrix();
|
||||
for (int[] dayAndHour : daysAndHours) {
|
||||
int day = dayAndHour[0];
|
||||
int hour = dayAndHour[1];
|
||||
matrix[day][hour] = matrix[day][hour] + 1;
|
||||
}
|
||||
return dataArray;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toHighChartsSeries() {
|
||||
List<Long> sessionStarts = getSessionStarts(sessions);
|
||||
int[][] dataArray = turnIntoArray(sessionStarts);
|
||||
int big = findBiggestValue(dataArray);
|
||||
int[][] scaled = scale(dataArray, big);
|
||||
StringBuilder arrayBuilder = new StringBuilder("[");
|
||||
for (int i = 0; i < 7; i++) {
|
||||
for (int j = 0; j < 24; j++) {
|
||||
int value = scaled[i][j];
|
||||
if (j == 0) {
|
||||
arrayBuilder.append("{x:").append(24 * 3600000);
|
||||
} else {
|
||||
arrayBuilder.append("{x:").append(j * 3600000);
|
||||
}
|
||||
arrayBuilder.append(", y:").append(i)
|
||||
.append(", z:").append(value).
|
||||
append(", marker: { radius:").append(value)
|
||||
.append("}}");
|
||||
if (i != 6 || j != 23) {
|
||||
arrayBuilder.append(",");
|
||||
}
|
||||
return getDots().toString();
|
||||
}
|
||||
|
||||
public List<Dot> getDots() {
|
||||
List<Dot> dots = new ArrayList<>();
|
||||
|
||||
List<Long> sessionStarts = sessions.toSessionStarts();
|
||||
|
||||
int[][] dayHourMatrix = turnIntoMatrix(sessionStarts);
|
||||
int big = findBiggestValue(dayHourMatrix);
|
||||
int[][] scaled = scale(dayHourMatrix, big);
|
||||
|
||||
for (int day = 0; day < 7; day++) {
|
||||
for (int hour = 0; hour < 24; hour++) {
|
||||
int value = scaled[day][hour];
|
||||
|
||||
int x = hour == 0 ? 24 * 3600000 : hour * 3600000;
|
||||
|
||||
dots.add(new Dot(x, day, value, value));
|
||||
}
|
||||
}
|
||||
arrayBuilder.append("]");
|
||||
return arrayBuilder.toString();
|
||||
|
||||
return dots;
|
||||
}
|
||||
|
||||
private List<Long> getSessionStarts(Collection<Session> data) {
|
||||
return data.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(session -> session.getUnsafe(SessionKeys.START))
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private int[][] createEmptyArray() {
|
||||
private int[][] createZeroMatrix() {
|
||||
int[][] dataArray = new int[7][24];
|
||||
for (int i = 0; i < 7; i++) {
|
||||
for (int j = 0; j < 24; j++) {
|
||||
@ -151,4 +140,43 @@ public class PunchCard implements HighChart {
|
||||
}
|
||||
return scaled;
|
||||
}
|
||||
|
||||
public static class Dot {
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
Marker marker;
|
||||
|
||||
public Dot(int x, int y, int z, int radius) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.marker = new Marker(radius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" +
|
||||
"x:" + x +
|
||||
", y:" + y +
|
||||
", z:" + z +
|
||||
", marker:" + marker +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static class Marker {
|
||||
int radius;
|
||||
|
||||
Marker(int radius) {
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" +
|
||||
"radius:" + radius +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,11 +18,12 @@ package com.djrapitops.plan.utilities.html.graphs.special;
|
||||
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.store.mutators.PlayersMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
|
||||
import com.djrapitops.plan.utilities.html.graphs.HighChart;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -38,7 +39,11 @@ public class SpecialGraphFactory {
|
||||
// Inject Constructor.
|
||||
}
|
||||
|
||||
public HighChart punchCard(Collection<Session> sessions) {
|
||||
public PunchCard punchCard(List<Session> sessions) {
|
||||
return punchCard(new SessionsMutator(sessions));
|
||||
}
|
||||
|
||||
public PunchCard punchCard(SessionsMutator sessions) {
|
||||
return new PunchCard(sessions);
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@
|
||||
<h6 class="m-0 font-weight-bold col-black"><i class="fas fa-fw fa-braille"></i>
|
||||
Punchcard</h6>
|
||||
</div>
|
||||
<div class="chart-area" id="punchcard">
|
||||
<div class="chart-area" id="punchCard">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card shadow mb-4">
|
||||
@ -1318,6 +1318,16 @@
|
||||
jsonRequest("../v1/player?player=${playerName}", function (json, error) {
|
||||
loadPlayerOverviewValues(json, error);
|
||||
loadSessionAccordion(json, error);
|
||||
if (json) {
|
||||
punchCard("punchCard", {
|
||||
name: 'Relative Activity',
|
||||
color: '#222',
|
||||
data: json.punchcard_series
|
||||
})
|
||||
} else if (error) {
|
||||
$('#punchCard').text("Failed to load graph data: " + error)
|
||||
}
|
||||
|
||||
});
|
||||
setLoadingText('Rendering graphs..');
|
||||
setLoadingText('Sorting players table..');
|
||||
|
Loading…
Reference in New Issue
Block a user