mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-10-04 01:18:15 +02:00
Implemented unique players graph #560
This commit is contained in:
parent
0549ce32f5
commit
6c1e648741
@ -188,6 +188,17 @@ public class AnalysisContainer extends DataContainer {
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_NEW_WEEK, () -> getUnsafe(newWeek).averageNewPerDay());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_NEW_MONTH, () -> getUnsafe(newMonth).averageNewPerDay());
|
||||
|
||||
putSupplier(AnalysisKeys.UNIQUE_PLAYERS_SERIES, () ->
|
||||
new AbstractLineGraph(MutatorFunctions.toPoints(
|
||||
getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).uniqueJoinsPerDay())
|
||||
).toHighChartsSeries()
|
||||
);
|
||||
putSupplier(AnalysisKeys.NEW_PLAYERS_SERIES, () ->
|
||||
new AbstractLineGraph(MutatorFunctions.toPoints(
|
||||
getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).newPerDay())
|
||||
).toHighChartsSeries()
|
||||
);
|
||||
|
||||
Key<Integer> retentionDay = new Key<>(Integer.class, "RETENTION_DAY");
|
||||
// compareAndFindThoseLikelyToBeRetained can throw exception.
|
||||
putSupplier(retentionDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).compareAndFindThoseLikelyToBeRetained(
|
||||
|
@ -127,6 +127,8 @@ public class AnalysisKeys {
|
||||
public static final PlaceholderKey<String> ACTIVITY_STACK_CATEGORIES = CommonPlaceholderKeys.ACTIVITY_STACK_CATEGORIES;
|
||||
public static final PlaceholderKey<String> ACTIVITY_PIE_SERIES = CommonPlaceholderKeys.ACTIVITY_PIE_SERIES;
|
||||
public static final PlaceholderKey<String> CALENDAR_SERIES = new PlaceholderKey<>(String.class, "calendarSeries");
|
||||
public static final PlaceholderKey<String> UNIQUE_PLAYERS_SERIES = new PlaceholderKey<>(String.class, "uniquePlayersSeries");
|
||||
public static final PlaceholderKey<String> NEW_PLAYERS_SERIES = new PlaceholderKey<>(String.class, "newPlayersSeries");
|
||||
// Variables used only during analysis
|
||||
public static final Key<SessionsMutator> SESSIONS_MUTATOR = CommonKeys.SESSIONS_MUTATOR;
|
||||
public static final Key<TPSMutator> TPS_MUTATOR = CommonKeys.TPS_MUTATOR;
|
||||
|
@ -18,6 +18,10 @@ public class DateHoldersMutator<T extends DateHolder> {
|
||||
public TreeMap<Long, List<T>> groupByStartOfDay() {
|
||||
TreeMap<Long, List<T>> map = new TreeMap<>();
|
||||
|
||||
if (dateHolders.isEmpty()) {
|
||||
return map;
|
||||
}
|
||||
|
||||
long twentyFourHours = 24L * TimeAmount.HOUR.ms();
|
||||
for (T holder : dateHolders) {
|
||||
long date = holder.getDate();
|
||||
@ -28,11 +32,16 @@ public class DateHoldersMutator<T extends DateHolder> {
|
||||
map.put(startOfDate, list);
|
||||
}
|
||||
|
||||
// Add missing in-between dates
|
||||
for (long date = map.firstKey(); date < map.lastKey(); date += twentyFourHours) {
|
||||
map.putIfAbsent(date, new ArrayList<>());
|
||||
// Empty map firstKey attempt causes NPE if not checked.
|
||||
if (!map.isEmpty()) {
|
||||
// Add missing in-between dates
|
||||
long start = map.firstKey();
|
||||
long now = System.currentTimeMillis();
|
||||
long end = now - (now % twentyFourHours);
|
||||
for (long date = map.firstKey(); date < end; date += twentyFourHours) {
|
||||
map.putIfAbsent(date, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,8 @@ public class AnalysisPage implements Page {
|
||||
TPS_SERIES, CPU_SERIES, RAM_SERIES,
|
||||
ENTITY_SERIES, CHUNK_SERIES, PUNCHCARD_SERIES,
|
||||
WORLD_MAP_SERIES, ACTIVITY_STACK_SERIES, ACTIVITY_STACK_CATEGORIES,
|
||||
ACTIVITY_PIE_SERIES, CALENDAR_SERIES
|
||||
ACTIVITY_PIE_SERIES, CALENDAR_SERIES,
|
||||
UNIQUE_PLAYERS_SERIES, NEW_PLAYERS_SERIES
|
||||
);
|
||||
placeholderReplacer.addAllPlaceholdersFrom(analysisContainer, FormatUtils::cutDecimals,
|
||||
AVG_TPS_MONTH, AVG_TPS_WEEK, AVG_TPS_DAY,
|
||||
|
@ -121,6 +121,7 @@ public class HtmlExport extends SpecificExport {
|
||||
"web/js/helpers.js",
|
||||
"web/js/script.js",
|
||||
"web/js/charts/activityPie.js",
|
||||
"web/js/charts/lineGraph.js",
|
||||
"web/js/charts/stackGraph.js",
|
||||
"web/js/charts/performanceGraph.js",
|
||||
"web/js/charts/playerGraph.js",
|
||||
|
36
Plan/src/main/resources/web/js/charts/lineGraph.js
Normal file
36
Plan/src/main/resources/web/js/charts/lineGraph.js
Normal file
@ -0,0 +1,36 @@
|
||||
function lineChart(id, series) {
|
||||
Highcharts.stockChart(id, {
|
||||
rangeSelector: {
|
||||
selected: 2,
|
||||
buttons: [{
|
||||
type: 'hour',
|
||||
count: 12,
|
||||
text: '12h'
|
||||
}, {
|
||||
type: 'hour',
|
||||
count: 24,
|
||||
text: '24h'
|
||||
}, {
|
||||
type: 'day',
|
||||
count: 7,
|
||||
text: '7d'
|
||||
}, {
|
||||
type: 'month',
|
||||
count: 1,
|
||||
text: '30d'
|
||||
}, {
|
||||
type: 'all',
|
||||
text: 'All'
|
||||
}]
|
||||
},
|
||||
yAxis: {
|
||||
softMax: 2,
|
||||
softMin: 0
|
||||
},
|
||||
title: {text: ''},
|
||||
legend: {
|
||||
enabled: true
|
||||
},
|
||||
series: series
|
||||
});
|
||||
}
|
@ -1119,6 +1119,7 @@
|
||||
<script src="js/charts/punchCard.js"></script>
|
||||
<script src="js/charts/healthGauge.js"></script>
|
||||
<script src="js/charts/activityPie.js"></script>
|
||||
<script src="js/charts/lineGraph.js"></script>
|
||||
<script src="js/charts/stackGraph.js"></script>
|
||||
<script src="js/charts/worldPie.js"></script>
|
||||
<script src="js/charts/performanceGraph.js"></script>
|
||||
@ -1141,6 +1142,7 @@
|
||||
var v = {
|
||||
colors: {
|
||||
playersOnline: '${playersGraphColor}',
|
||||
newPlayers: '#8BC34A',
|
||||
tpsLow: '${tpsLowColor}',
|
||||
tpsMed: '${tpsMediumColor}',
|
||||
tpsHigh: '${tpsHighColor}',
|
||||
@ -1159,6 +1161,8 @@
|
||||
},
|
||||
data: {
|
||||
playersOnline: ${playersOnlineSeries},
|
||||
uniquePlayers: ${uniquePlayersSeries},
|
||||
newPlayers: ${newPlayersSeries},
|
||||
tps: ${tpsSeries},
|
||||
cpu: ${cpuSeries},
|
||||
ram: ${ramSeries},
|
||||
@ -1180,6 +1184,8 @@
|
||||
var s = {
|
||||
name: {
|
||||
playersOnline: 'Players Online',
|
||||
uniquePlayers: 'Unique Players',
|
||||
newPlayers: 'New Players',
|
||||
tps: 'TPS',
|
||||
cpu: 'CPU Usage (%)',
|
||||
ram: 'RAM Usage (MB)',
|
||||
@ -1220,6 +1226,20 @@
|
||||
color: v.colors.playersOnline,
|
||||
yAxis: 0
|
||||
},
|
||||
uniquePlayers: {
|
||||
name: s.name.uniquePlayers,
|
||||
type: s.type.spline,
|
||||
tooltip: s.tooltip.zeroDecimals,
|
||||
data: v.data.uniquePlayers,
|
||||
color: v.colors.playersOnline
|
||||
},
|
||||
newPlayers: {
|
||||
name: s.name.newPlayers,
|
||||
type: s.type.spline,
|
||||
tooltip: s.tooltip.zeroDecimals,
|
||||
data: v.data.newPlayers,
|
||||
color: v.colors.newPlayers
|
||||
},
|
||||
tps: {
|
||||
name: s.name.tps,
|
||||
type: s.type.spline,
|
||||
@ -1346,6 +1366,7 @@
|
||||
|
||||
// Chart draw scripts
|
||||
activityPie('activityPie', series.activityPie);
|
||||
lineChart('uniqueChart', [series.uniquePlayers, series.newPlayers]);
|
||||
stackChart('activityStackGraph', series.activityStackCategories, series.activityStack, 'Players');
|
||||
worldPie('worldPie', series.worldPie, series.worldPieDrillDown);
|
||||
playersChart('playerChartDay', series.playersOnline, 3);
|
||||
|
Loading…
Reference in New Issue
Block a user