mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-03-10 22:01:00 +01:00
Rest of Analysis Graphs to HighCharts
This commit is contained in:
parent
30f8fd69e7
commit
a2cc3a332b
@ -69,15 +69,12 @@ public class ActivityPart extends RawData {
|
|||||||
|
|
||||||
final List<SessionData> sessions = joins.getAllSessions();
|
final List<SessionData> sessions = joins.getAllSessions();
|
||||||
|
|
||||||
long averageLength = MathUtils.averageLong(AnalysisUtils.transformSessionDataToLengths(sessions));
|
List<Long> lengths = AnalysisUtils.transformSessionDataToLengths(sessions);
|
||||||
|
long averageLength = MathUtils.averageLong(lengths);
|
||||||
addValue("sessionaverage", FormatUtils.formatTimeAmount(averageLength));
|
addValue("sessionaverage", FormatUtils.formatTimeAmount(averageLength));
|
||||||
|
|
||||||
String punchCardArray = PunchCardGraphCreator.generateDataArray(sessions);
|
addValue("punchcardseries", PunchCardGraphCreator.createDataSeries(sessions));
|
||||||
addValue("datapunchcard", punchCardArray);
|
addValue("sessionlengthseries", SessionLengthDistributionGraphCreator.createDataSeries(lengths));
|
||||||
|
|
||||||
String[] sessionDistribution = SessionLengthDistributionGraphCreator.generateDataArraySessions(sessions);
|
|
||||||
addValue("datasessiondistribution", sessionDistribution[0]);
|
|
||||||
addValue("labelssessiondistribution", sessionDistribution[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void playerActivityGraphs() {
|
private void playerActivityGraphs() {
|
||||||
|
@ -40,21 +40,6 @@ public class TPSPart extends RawData {
|
|||||||
List<TPS> week = TPSGraphCreator.filterTPS(tpsData, now - TimeAmount.WEEK.ms());
|
List<TPS> week = TPSGraphCreator.filterTPS(tpsData, now - TimeAmount.WEEK.ms());
|
||||||
List<TPS> day = TPSGraphCreator.filterTPS(tpsData, now - TimeAmount.DAY.ms());
|
List<TPS> day = TPSGraphCreator.filterTPS(tpsData, now - TimeAmount.DAY.ms());
|
||||||
|
|
||||||
String tpsScatterDay = TPSGraphCreator.buildScatterDataStringTPS(day, TimeAmount.DAY.ms());
|
|
||||||
String tpsScatterWeek = TPSGraphCreator.buildScatterDataStringTPS(week, TimeAmount.WEEK.ms());
|
|
||||||
|
|
||||||
String cpuScatterDay = CPUGraphCreator.buildScatterDataString(day, TimeAmount.DAY.ms());
|
|
||||||
String cpuScatterWeek = CPUGraphCreator.buildScatterDataString(week, TimeAmount.WEEK.ms());
|
|
||||||
String ramScatterDay = RamGraphCreator.buildScatterDataString(day, TimeAmount.DAY.ms());
|
|
||||||
String ramScatterWeek = RamGraphCreator.buildScatterDataString(week, TimeAmount.WEEK.ms());
|
|
||||||
|
|
||||||
String entityScatterDay = WorldLoadGraphCreator.buildScatterDataStringEntities(day, TimeAmount.DAY.ms());
|
|
||||||
String entityScatterWeek = WorldLoadGraphCreator.buildScatterDataStringEntities(week, TimeAmount.WEEK.ms());
|
|
||||||
String chunkScatterDay = WorldLoadGraphCreator.buildScatterDataStringChunks(day, TimeAmount.DAY.ms());
|
|
||||||
String chunkScatterWeek = WorldLoadGraphCreator.buildScatterDataStringChunks(week, TimeAmount.WEEK.ms());
|
|
||||||
|
|
||||||
addValue("tpsscatterday", tpsScatterDay);
|
|
||||||
addValue("tpsscatterweek", tpsScatterWeek);
|
|
||||||
|
|
||||||
addValue("tpsseries", TPSGraphCreator.buildSeriesDataString(tpsData));
|
addValue("tpsseries", TPSGraphCreator.buildSeriesDataString(tpsData));
|
||||||
addValue("cpuseries", CPUGraphCreator.buildSeriesDataString(tpsData));
|
addValue("cpuseries", CPUGraphCreator.buildSeriesDataString(tpsData));
|
||||||
@ -62,19 +47,6 @@ public class TPSPart extends RawData {
|
|||||||
addValue("entityseries", WorldLoadGraphCreator.buildSeriesDataStringEntities(tpsData));
|
addValue("entityseries", WorldLoadGraphCreator.buildSeriesDataStringEntities(tpsData));
|
||||||
addValue("chunkseries", WorldLoadGraphCreator.buildSeriesDataStringChunks(tpsData));
|
addValue("chunkseries", WorldLoadGraphCreator.buildSeriesDataStringChunks(tpsData));
|
||||||
|
|
||||||
addValue("cpuscatterday", cpuScatterDay);
|
|
||||||
addValue("cpuscatterweek", cpuScatterWeek);
|
|
||||||
addValue("ramscatterday", ramScatterDay);
|
|
||||||
addValue("ramscatterweek", ramScatterWeek);
|
|
||||||
|
|
||||||
addValue("entityscatterday", entityScatterDay);
|
|
||||||
addValue("entityscatterweek", entityScatterWeek);
|
|
||||||
addValue("chunkscatterday", chunkScatterDay);
|
|
||||||
addValue("chunkscatterweek", chunkScatterWeek);
|
|
||||||
|
|
||||||
Runtime runtime = Runtime.getRuntime();
|
|
||||||
addValue("maxram", runtime.maxMemory() / 1000000);
|
|
||||||
|
|
||||||
double averageTPSWeek = MathUtils.averageDouble(week.stream().map(TPS::getTps));
|
double averageTPSWeek = MathUtils.averageDouble(week.stream().map(TPS::getTps));
|
||||||
double averageTPSDay = MathUtils.averageDouble(day.stream().map(TPS::getTps));
|
double averageTPSDay = MathUtils.averageDouble(day.stream().map(TPS::getTps));
|
||||||
|
|
||||||
|
@ -29,6 +29,30 @@ public class PunchCardGraphCreator {
|
|||||||
throw new IllegalStateException("Utility class");
|
throw new IllegalStateException("Utility class");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String createDataSeries(Collection<SessionData> sessions) {
|
||||||
|
List<Long> sessionStarts = getSessionStarts(sessions);
|
||||||
|
List<int[]> daysAndHours = AnalysisUtils.getDaysAndHours(sessionStarts);
|
||||||
|
int[][] dataArray = createDataArray(daysAndHours);
|
||||||
|
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 (value == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
arrayBuilder.append("{x:").append(j * 3600000).append(", y:").append(i).append(", z:").append(value).append(", marker: { radius:").append(value).append("}}");
|
||||||
|
if (i != 6 || j != 23) {
|
||||||
|
arrayBuilder.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arrayBuilder.append("]");
|
||||||
|
return arrayBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param data
|
* @param data
|
||||||
* @return
|
* @return
|
||||||
|
@ -24,6 +24,37 @@ public class SessionLengthDistributionGraphCreator {
|
|||||||
throw new IllegalStateException("Utility class");
|
throw new IllegalStateException("Utility class");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a data series of session lengths for Sessions bar chart.
|
||||||
|
* <p>
|
||||||
|
* Contains values from 0 up to 120 minutes
|
||||||
|
*
|
||||||
|
* @param lengths Lengths of all sessions in a list.
|
||||||
|
* @return Data for Highcharts series.
|
||||||
|
*/
|
||||||
|
public static String createDataSeries(List<Long> lengths) {
|
||||||
|
Map<Long, Integer> bars = getValues(lengths);
|
||||||
|
List<Long> keys = new ArrayList<>(bars.keySet());
|
||||||
|
Collections.sort(keys);
|
||||||
|
|
||||||
|
StringBuilder arrayBuilder = new StringBuilder("[");
|
||||||
|
int i = 0;
|
||||||
|
int size = keys.size();
|
||||||
|
for (Long key : keys) {
|
||||||
|
if (key > 120) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Integer value = bars.get(key);
|
||||||
|
arrayBuilder.append("['").append(key - 5).append(" - ").append(key).append(" min',").append(value).append("]");
|
||||||
|
if (i < size) {
|
||||||
|
arrayBuilder.append(", ");
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
arrayBuilder.append("]");
|
||||||
|
return arrayBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param data
|
* @param data
|
||||||
* @return
|
* @return
|
||||||
@ -86,11 +117,14 @@ public class SessionLengthDistributionGraphCreator {
|
|||||||
Map<Long, Integer> values = new HashMap<>();
|
Map<Long, Integer> values = new HashMap<>();
|
||||||
long lengthInMinutes = 5;
|
long lengthInMinutes = 5;
|
||||||
|
|
||||||
while (!unused.isEmpty() && lengthInMinutes < 120) {
|
while (!unused.isEmpty() || lengthInMinutes <= 120) {
|
||||||
long length = lengthInMinutes * 60 * 1000;
|
long length = lengthInMinutes * 60 * 1000;
|
||||||
List<Long> lessThan = unused.stream().filter(l -> l < length).collect(Collectors.toList());
|
List<Long> lessThan = unused.stream().filter(l -> l < length).collect(Collectors.toList());
|
||||||
values.put(lengthInMinutes, lessThan.size());
|
int amount = lessThan.size();
|
||||||
|
if (amount != 0) {
|
||||||
|
values.put(lengthInMinutes, amount);
|
||||||
unused.removeAll(lessThan);
|
unused.removeAll(lessThan);
|
||||||
|
}
|
||||||
lengthInMinutes += 5;
|
lengthInMinutes += 5;
|
||||||
}
|
}
|
||||||
return values;
|
return values;
|
||||||
|
@ -4,6 +4,19 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class WorldMapCreator {
|
public class WorldMapCreator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor used to hide the public constructor
|
||||||
|
*/
|
||||||
|
private WorldMapCreator() {
|
||||||
|
throw new IllegalStateException("Utility class");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a data series with iso-a3 specification of Country codes.
|
||||||
|
*
|
||||||
|
* @param geoCodeCounts
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public static String createDataSeries(Map<String, Integer> geoCodeCounts) {
|
public static String createDataSeries(Map<String, Integer> geoCodeCounts) {
|
||||||
StringBuilder arrayBuilder = new StringBuilder("[");
|
StringBuilder arrayBuilder = new StringBuilder("[");
|
||||||
|
|
||||||
|
@ -283,23 +283,28 @@ public class AnalysisUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param sessionStarts
|
* Transforms the session start list into a list of int arrays.
|
||||||
* @return
|
* <p>
|
||||||
|
* First number signifies the Day of Week. (0 = Monday, 6 = Sunday)
|
||||||
|
* Second number signifies the Hour of Day. (0 = 0 AM, 23 = 11 PM)
|
||||||
|
*
|
||||||
|
* @param sessionStarts List of Session start Epoch ms.
|
||||||
|
* @return list of int arrays.
|
||||||
*/
|
*/
|
||||||
public static List<int[]> getDaysAndHours(List<Long> sessionStarts) {
|
public static List<int[]> getDaysAndHours(List<Long> sessionStarts) {
|
||||||
return sessionStarts.stream().map((Long start) -> {
|
return sessionStarts.stream().map((Long start) -> {
|
||||||
Calendar day = Calendar.getInstance();
|
Calendar day = Calendar.getInstance();
|
||||||
day.setTimeInMillis(start);
|
day.setTimeInMillis(start);
|
||||||
int hourOfDay = day.get(Calendar.HOUR_OF_DAY);
|
int hourOfDay = day.get(Calendar.HOUR_OF_DAY); // 0 AM is 0
|
||||||
int dayOfWeek = day.get(Calendar.DAY_OF_WEEK) - 2;
|
int dayOfWeek = day.get(Calendar.DAY_OF_WEEK) - 2; // Monday is 0, Sunday is -1
|
||||||
if (hourOfDay == 24) {
|
if (hourOfDay == 24) { // Check if hour is 24 (Should be impossible but.)
|
||||||
hourOfDay = 0;
|
hourOfDay = 0;
|
||||||
dayOfWeek += 1;
|
dayOfWeek += 1;
|
||||||
}
|
}
|
||||||
if (dayOfWeek > 6) {
|
if (dayOfWeek > 6) { // If Hour added a day on Sunday, move to Monday
|
||||||
dayOfWeek = 0;
|
dayOfWeek = 0;
|
||||||
}
|
}
|
||||||
if (dayOfWeek < 0) {
|
if (dayOfWeek < 0) { // Move Sunday to 6
|
||||||
dayOfWeek = 6;
|
dayOfWeek = 6;
|
||||||
}
|
}
|
||||||
return new int[]{dayOfWeek, hourOfDay};
|
return new int[]{dayOfWeek, hourOfDay};
|
||||||
|
@ -406,7 +406,7 @@
|
|||||||
<div class="info-icon">
|
<div class="info-icon">
|
||||||
<i class="fa fa-user-plus" aria-hidden="true"></i>
|
<i class="fa fa-user-plus" aria-hidden="true"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-text">
|
<div class="info-text" style="width: 60%;">
|
||||||
<div class="info-number">
|
<div class="info-number">
|
||||||
%newperdaymonth%
|
%newperdaymonth%
|
||||||
</div>
|
</div>
|
||||||
@ -491,7 +491,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<canvas id="punchcard" width="1000" height="600" style="width: 95%;"></canvas>
|
<div id="punchcard" style="width: 100%; height:400px;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -515,7 +515,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<canvas id="sessiondistribution" width="1000" height="600" style="width: 95%;"></canvas>
|
<div id="sessionDistribution" style="width: 100%; height:400px;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -773,6 +773,16 @@
|
|||||||
data: %geomapseries%,
|
data: %geomapseries%,
|
||||||
joinBy: ['iso-a3', 'code']
|
joinBy: ['iso-a3', 'code']
|
||||||
};
|
};
|
||||||
|
var sessionLengthSeries = {
|
||||||
|
name: 'Sessions',
|
||||||
|
color: '#89c471',
|
||||||
|
data: %sessionlengthseries%
|
||||||
|
};
|
||||||
|
var punchcardSeries = {
|
||||||
|
name: 'Relative Activity',
|
||||||
|
color: '#222',
|
||||||
|
data: %punchcardseries%
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
function playersChart() {
|
function playersChart() {
|
||||||
@ -958,7 +968,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
function gmPie() {
|
function gmPie() {
|
||||||
var myChart = Highcharts.chart('gmPie', {
|
Highcharts.chart('gmPie', {
|
||||||
chart: {
|
chart: {
|
||||||
plotBackgroundColor: null, plotBorderWidth: null, plotShadow: false,
|
plotBackgroundColor: null, plotBorderWidth: null, plotShadow: false,
|
||||||
type: 'pie'
|
type: 'pie'
|
||||||
@ -984,139 +994,64 @@
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
// Session start puchcard bubblechart
|
function punchCard() {
|
||||||
function day(i) {
|
Highcharts.chart('punchcard' , {
|
||||||
switch (i) {
|
chart: {
|
||||||
case 0:
|
defaultSeriesType: 'scatter'
|
||||||
return 'Monday';
|
|
||||||
case 1:
|
|
||||||
return 'Tuesday';
|
|
||||||
case 2:
|
|
||||||
return 'Wednesday';
|
|
||||||
case 3:
|
|
||||||
return 'Thursday';
|
|
||||||
case 4:
|
|
||||||
return 'Friday';
|
|
||||||
case 5:
|
|
||||||
return 'Saturday';
|
|
||||||
case 6:
|
|
||||||
return 'Sunday';
|
|
||||||
default:
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function hour(i) {
|
|
||||||
switch (i) {
|
|
||||||
case 25:
|
|
||||||
case - 1:
|
|
||||||
case - 2:
|
|
||||||
case - 3:
|
|
||||||
case - 4:
|
|
||||||
case - 5:
|
|
||||||
return '';
|
|
||||||
default:
|
|
||||||
return i + ':00';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var ctxpunch = document.getElementById("punchcard");
|
|
||||||
var datapunch = {
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: 'Player Join Punchcard',
|
|
||||||
data: %datapunchcard% ,
|
|
||||||
backgroundColor: "#222",
|
|
||||||
hoverBackgroundColor: "#333",
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
var punchcardChart = new Chart(ctxpunch, {
|
|
||||||
type: 'bubble',
|
|
||||||
data: datapunch,
|
|
||||||
options: {
|
|
||||||
tooltips: {
|
|
||||||
callbacks: {
|
|
||||||
label: function(tooltipItems, data) {
|
|
||||||
return day(tooltipItems.yLabel) + ': ' + hour(tooltipItems.xLabel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
scales: {
|
title: {
|
||||||
xAxes: [{
|
text: 'Player Join PunchCard'
|
||||||
showXLabels: 1,
|
|
||||||
ticks: {
|
|
||||||
callback: function(value, index, values) {
|
|
||||||
return hour(value);
|
|
||||||
},
|
},
|
||||||
suggestedMax: 25,
|
xAxis: {
|
||||||
suggestedMin: - 1
|
type: 'datetime',
|
||||||
}
|
dateTimeLabelFormats: {
|
||||||
}],
|
hour: '%I %P'
|
||||||
yAxes: [{
|
|
||||||
ticks: {
|
|
||||||
callback: function(value, index, values) {
|
|
||||||
return day(value);
|
|
||||||
},
|
},
|
||||||
suggestedMax: 7,
|
tickInterval: 3600000
|
||||||
suggestedMin: - 1
|
},
|
||||||
}
|
yAxis: {
|
||||||
}]
|
categories: ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'],
|
||||||
}
|
},
|
||||||
}
|
tooltip: {
|
||||||
|
pointFormat: 'Activity: {point.z}'
|
||||||
|
},
|
||||||
|
series: [punchcardSeries]
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
// Session length distribution barchart
|
function sessionDistributionChart() {
|
||||||
var ctxDistribution = document.getElementById("sessiondistribution");
|
Highcharts.chart('sessionDistribution', {
|
||||||
var dataDistr = {
|
chart: {
|
||||||
labels: %labelssessiondistribution%,
|
type: 'column'
|
||||||
datasets: [
|
},
|
||||||
{
|
title: {
|
||||||
label: 'Session Length Distribution',
|
text: 'Session Length Distribution'
|
||||||
data: %datasessiondistribution% ,
|
},
|
||||||
backgroundColor: "#89c471",
|
xAxis: {
|
||||||
fill: true,
|
type: 'category',
|
||||||
borderColor: "#348e0f",
|
labels: {
|
||||||
borderCapStyle: 'butt',
|
rotation: -45
|
||||||
borderDash: [],
|
|
||||||
borderDashOffset: 0.0,
|
|
||||||
borderJoinStyle: 'miter',
|
|
||||||
pointBorderColor: "#348e0f",
|
|
||||||
pointBackgroundColor: "#fff",
|
|
||||||
pointBorderWidth: 1,
|
|
||||||
pointHoverRadius: 5,
|
|
||||||
pointHoverBackgroundColor: "#348e0f",
|
|
||||||
pointHoverBorderColor: "#348e0f",
|
|
||||||
pointHoverBorderWidth: 2,
|
|
||||||
pointRadius: 1,
|
|
||||||
pointHitRadius: 10,
|
|
||||||
spanGaps: false,
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
var sessionDistributions = new Chart(ctxDistribution, {
|
|
||||||
type: 'bar',
|
|
||||||
data: dataDistr,
|
|
||||||
options: {
|
|
||||||
tooltips: {
|
|
||||||
callbacks: {
|
|
||||||
label: function(tooltipItems, data) {
|
|
||||||
return tooltipItems.xLabel + 'utes: ' + tooltipItems.yLabel + ' sessions';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scales: {
|
yAxis: {
|
||||||
yAxes: [{
|
min: 0,
|
||||||
ticks: {
|
title: {
|
||||||
callback: function(value, index, values) {
|
text: 'Sessions'
|
||||||
return value + '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
plotOptions: {
|
||||||
|
series: {
|
||||||
|
groupPadding: 0
|
||||||
|
},
|
||||||
|
pointPadding: 0
|
||||||
|
},
|
||||||
|
series: [sessionLengthSeries]
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
function worldMap() {
|
function worldMap() {
|
||||||
@ -1173,7 +1108,10 @@
|
|||||||
playersChart2();
|
playersChart2();
|
||||||
tpsChart();
|
tpsChart();
|
||||||
resourceChart();
|
resourceChart();
|
||||||
|
worldChart();
|
||||||
worldMap();
|
worldMap();
|
||||||
|
sessionDistributionChart();
|
||||||
|
punchCard();
|
||||||
countUpTimer();
|
countUpTimer();
|
||||||
|
|
||||||
function openFunc(i) {
|
function openFunc(i) {
|
||||||
|
Loading…
Reference in New Issue
Block a user