Rewrote Activity Pie & Wrote Activity Stack Graph - moved some graphcreators to better packages

This commit is contained in:
Rsl1122 2017-11-29 20:57:24 +02:00
parent d0eb8a53f3
commit 0e4c0b4d88
25 changed files with 293 additions and 88 deletions

View File

@ -15,7 +15,12 @@ import main.java.com.djrapitops.plan.utilities.analysis.MathUtils;
import main.java.com.djrapitops.plan.utilities.comparators.SessionStartComparator;
import main.java.com.djrapitops.plan.utilities.html.Html;
import main.java.com.djrapitops.plan.utilities.html.HtmlUtils;
import main.java.com.djrapitops.plan.utilities.html.graphs.*;
import main.java.com.djrapitops.plan.utilities.html.graphs.ActivityStackGraphCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.PunchCardGraphCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.WorldMapCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.line.*;
import main.java.com.djrapitops.plan.utilities.html.graphs.pie.ActivityPieCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.pie.WorldPieCreator;
import main.java.com.djrapitops.plan.utilities.html.structure.AnalysisPluginsTabContentCreator;
import main.java.com.djrapitops.plan.utilities.html.structure.SessionTabStructureCreator;
import main.java.com.djrapitops.plan.utilities.html.tables.CommandUseTableCreator;
@ -135,7 +140,7 @@ public class AnalysisData extends RawData {
if (!players.isEmpty()) {
for (PlayerProfile player : players) {
for (long date = now; date >= now - TimeAmount.MONTH.ms() * 2L; date -= TimeAmount.WEEK.ms() * 2L) {
for (long date = now; date >= now - TimeAmount.MONTH.ms() * 2L; date -= TimeAmount.WEEK.ms()) {
double activityIndex = player.getActivityIndex(date);
String index = FormatUtils.readableActivityIndex(activityIndex)[1];
@ -151,6 +156,13 @@ public class AnalysisData extends RawData {
Map<String, Set<UUID>> activityNow = activityData.getOrDefault(now, new HashMap<>());
Map<String, Set<UUID>> activityFourWAgo = activityData.getOrDefault(fourWeeksAgo, new HashMap<>());
String[] activityStackSeries = ActivityStackGraphCreator.createSeries(activityData);
String activityPieSeries = ActivityPieCreator.createSeriesData(activityNow);
addValue("activityStackCategories", activityStackSeries[0]);
addValue("activityStackSeries", activityStackSeries[1]);
addValue("activityPieSeries", activityPieSeries);
Set<UUID> veryActiveNow = activityNow.getOrDefault("Very Active", new HashSet<>());
Set<UUID> activeNow = activityNow.getOrDefault("Active", new HashSet<>());
Set<UUID> regularNow = activityNow.getOrDefault("Regular", new HashSet<>());

View File

@ -25,8 +25,8 @@ import main.java.com.djrapitops.plan.utilities.file.FileUtil;
import main.java.com.djrapitops.plan.utilities.html.HtmlStructure;
import main.java.com.djrapitops.plan.utilities.html.HtmlUtils;
import main.java.com.djrapitops.plan.utilities.html.graphs.PunchCardGraphCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.ServerPreferencePieCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.WorldPieCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.line.ServerPreferencePieCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.pie.WorldPieCreator;
import main.java.com.djrapitops.plan.utilities.html.structure.ServerAccordionCreator;
import main.java.com.djrapitops.plan.utilities.html.tables.ActionsTableCreator;
import main.java.com.djrapitops.plan.utilities.html.tables.IpTableCreator;

View File

@ -19,7 +19,7 @@ import main.java.com.djrapitops.plan.utilities.analysis.AnalysisUtils;
import main.java.com.djrapitops.plan.utilities.file.FileUtil;
import main.java.com.djrapitops.plan.utilities.html.HtmlStructure;
import main.java.com.djrapitops.plan.utilities.html.HtmlUtils;
import main.java.com.djrapitops.plan.utilities.html.graphs.PlayerActivityGraphCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.line.PlayerActivityGraphCreator;
import java.sql.SQLException;
import java.util.List;

View File

@ -0,0 +1,20 @@
/*
* 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 main.java.com.djrapitops.plan.utilities.comparators;
import main.java.com.djrapitops.plan.utilities.html.graphs.pie.PieSlice;
import java.util.Comparator;
/**
* Compares PieSlices to descending Percentage order.
*/
public class PieSliceComparator implements Comparator<PieSlice> {
@Override
public int compare(PieSlice o1, PieSlice o2) {
return -Long.compare(o1.getY(), o2.getY());
}
}

View File

@ -13,7 +13,7 @@ import main.java.com.djrapitops.plan.data.Session;
import main.java.com.djrapitops.plan.database.Database;
import main.java.com.djrapitops.plan.systems.info.BukkitInformationManager;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.html.graphs.PlayerActivityGraphCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.line.PlayerActivityGraphCreator;
import main.java.com.djrapitops.plan.utilities.html.structure.SessionTabStructureCreator;
import main.java.com.djrapitops.plan.utilities.html.tables.SessionsTableCreator;

View File

@ -0,0 +1,73 @@
/*
* 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 main.java.com.djrapitops.plan.utilities.html.graphs;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.html.graphs.pie.ActivityPieCreator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public class ActivityStackGraphCreator {
private ActivityStackGraphCreator() {
throw new IllegalStateException("Utility Class");
}
public static String[] createSeries(TreeMap<Long, Map<String, Set<UUID>>> activityData) {
String[] sliceNames = ActivityPieCreator.getSliceNames();
String[] colors = Settings.THEME_GRAPH_ACTIVITY_PIE.toString().split(", ");
int maxCol = colors.length;
StringBuilder[] series = new StringBuilder[sliceNames.length + 1];
for (int i = 0; i <= sliceNames.length; i++) {
series[i] = new StringBuilder();
}
for (int i = 1; i <= sliceNames.length; i++) {
series[i] = new StringBuilder("{name: '")
.append(sliceNames[i - 1])
.append("',color:").append(colors[(i - 1) % maxCol])
.append(",data: [");
}
int size = activityData.size();
int i = 0;
for (Long date : activityData.navigableKeySet()) {
Map<String, Set<UUID>> data = activityData.get(date);
series[0].append("'").append(FormatUtils.formatTimeStamp(date)).append("'");
for (int j = 1; j <= sliceNames.length; j++) {
Set<UUID> players = data.get(sliceNames[j - 1]);
series[j].append(players != null ? players.size() : 0);
}
if (i < size - 1) {
for (int j = 0; j <= sliceNames.length; j++) {
series[j].append(",");
}
}
i++;
}
StringBuilder seriesBuilder = new StringBuilder("[");
for (int j = 1; j <= sliceNames.length; j++) {
seriesBuilder.append(series[j].append("]}").toString());
if (j < sliceNames.length) {
seriesBuilder.append(",");
}
}
return new String[]{series[0].toString(), seriesBuilder.append("]").toString()};
}
}

View File

@ -1,4 +1,4 @@
package main.java.com.djrapitops.plan.utilities.html.graphs;
package main.java.com.djrapitops.plan.utilities.html.graphs.line;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.utilities.analysis.Point;

View File

@ -1,4 +1,4 @@
package main.java.com.djrapitops.plan.utilities.html.graphs;
package main.java.com.djrapitops.plan.utilities.html.graphs.line;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.utilities.analysis.Point;

View File

@ -1,4 +1,4 @@
package main.java.com.djrapitops.plan.utilities.html.graphs;
package main.java.com.djrapitops.plan.utilities.html.graphs.line;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.systems.tasks.TPSCountTimer;

View File

@ -3,7 +3,7 @@
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package main.java.com.djrapitops.plan.utilities.html.graphs;
package main.java.com.djrapitops.plan.utilities.html.graphs.line;
import main.java.com.djrapitops.plan.utilities.analysis.Point;

View File

@ -1,4 +1,4 @@
package main.java.com.djrapitops.plan.utilities.html.graphs;
package main.java.com.djrapitops.plan.utilities.html.graphs.line;
import main.java.com.djrapitops.plan.data.time.WorldTimes;

View File

@ -1,4 +1,4 @@
package main.java.com.djrapitops.plan.utilities.html.graphs;
package main.java.com.djrapitops.plan.utilities.html.graphs.line;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.utilities.analysis.Point;

View File

@ -1,4 +1,4 @@
package main.java.com.djrapitops.plan.utilities.html.graphs;
package main.java.com.djrapitops.plan.utilities.html.graphs.line;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.systems.tasks.TPSCountTimer;

View File

@ -0,0 +1,42 @@
/*
* 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 main.java.com.djrapitops.plan.utilities.html.graphs.pie;
import main.java.com.djrapitops.plan.Settings;
import java.util.*;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public class ActivityPieCreator {
private ActivityPieCreator() {
throw new IllegalStateException("Utility Class");
}
public static String[] getSliceNames() {
return new String[]{"Very Active", "Active", "Regular", "Irregular", "Inactive"};
}
public static String createSeriesData(Map<String, Set<UUID>> activityData) {
String[] colors = Settings.THEME_GRAPH_ACTIVITY_PIE.toString().split(", ");
int maxCol = colors.length;
List<PieSlice> slices = new ArrayList<>();
int i = 0;
for (String slice : getSliceNames()) {
Set<UUID> players = activityData.getOrDefault(slice, new HashSet<>());
int num = players.size();
slices.add(new PieSlice(slice, num, colors[i % maxCol], false));
i++;
}
return PieSeriesCreator.createSeriesData(slices);
}
}

View File

@ -0,0 +1,34 @@
/*
* 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 main.java.com.djrapitops.plan.utilities.html.graphs.pie;
import java.util.List;
/**
* PieSeries data creation utility class.
*
* @author Rsl1122
*/
public class PieSeriesCreator {
private PieSeriesCreator() {
throw new IllegalStateException("Utility Class");
}
public static String createSeriesData(List<PieSlice> slices) {
StringBuilder seriesBuilder = new StringBuilder("[");
int i = 0;
int size = slices.size();
for (PieSlice slice : slices) {
seriesBuilder.append(slice.toString());
if (i < size - 1) {
seriesBuilder.append(",");
}
i++;
}
seriesBuilder.append("]");
return seriesBuilder.toString();
}
}

View File

@ -0,0 +1,37 @@
/*
* 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 main.java.com.djrapitops.plan.utilities.html.graphs.pie;
/**
* Represents a slice of a pie.
*
* @author Rsl1122
*/
public class PieSlice {
private final String name;
private final long y;
private final String color;
private final boolean drilldown;
public PieSlice(String name, long y, String color, boolean drilldown) {
this.name = name;
this.y = y;
this.color = color;
this.drilldown = drilldown;
}
@Override
public String toString() {
return "{name:'" + name + "'," +
"y:" + y + "," +
"color:" + color
+ (drilldown ? "," + "drilldown: '" + name + "'" : "")
+ "}";
}
public long getY() {
return y;
}
}

View File

@ -1,10 +1,11 @@
package main.java.com.djrapitops.plan.utilities.html.graphs;
package main.java.com.djrapitops.plan.utilities.html.graphs.pie;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.WorldAliasSettings;
import main.java.com.djrapitops.plan.data.time.GMTimes;
import main.java.com.djrapitops.plan.data.time.WorldTimes;
import main.java.com.djrapitops.plan.utilities.comparators.PieSliceComparator;
import java.util.*;
import java.util.stream.Collectors;
@ -28,7 +29,7 @@ public class WorldPieCreator {
slices.sort(new PieSliceComparator());
}
String seriesData = buildSeries(slices);
String seriesData = PieSeriesCreator.createSeriesData(slices);
String drilldownData = createDrilldownData(worldTimes);
@ -53,29 +54,13 @@ public class WorldPieCreator {
for (String alias : worlds) {
Long value = playtimePerAlias.getOrDefault(alias, 0L);
if (value != 0L) {
slices.add(new PieSlice(alias, value, colors[i % colLenght]));
slices.add(new PieSlice(alias, value, colors[i % colLenght], true));
}
i++;
}
return slices;
}
private static String buildSeries(List<PieSlice> slices) {
StringBuilder seriesBuilder = new StringBuilder("[");
int i = 0;
int size = slices.size();
for (PieSlice slice : slices) {
seriesBuilder.append(slice.toString());
if (i < size - 1) {
seriesBuilder.append(",");
}
i++;
}
seriesBuilder.append("]");
return seriesBuilder.toString();
}
private static Map<String, Long> transformToAliases(Map<String, Long> playtimePerWorld) {
WorldAliasSettings aliasSettings = new WorldAliasSettings(Plan.getInstance());
Map<String, String> aliases = aliasSettings.getAliases();
@ -181,34 +166,3 @@ public class WorldPieCreator {
drilldownBuilder.append("]}");
}
}
class PieSlice {
private final String name;
final long y;
private final String color;
public PieSlice(String name, long y, String color) {
this.name = name;
this.y = y;
this.color = color;
}
@Override
public String toString() {
return "{name:'" + name + "'," +
"y:" + y + "," +
"color:" + color + "," +
"drilldown: '" + name + "'}";
}
}
/**
* Compares PieSlices to descending Percentage order.
*/
class PieSliceComparator implements Comparator<PieSlice> {
@Override
public int compare(PieSlice o1, PieSlice o2) {
return -Long.compare(o1.y, o2.y);
}
}

View File

@ -10,7 +10,7 @@ import main.java.com.djrapitops.plan.data.time.WorldTimes;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.analysis.AnalysisUtils;
import main.java.com.djrapitops.plan.utilities.analysis.MathUtils;
import main.java.com.djrapitops.plan.utilities.html.graphs.WorldPieCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.pie.WorldPieCreator;
import java.util.List;
import java.util.Map;

View File

@ -13,7 +13,7 @@ import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.analysis.AnalysisUtils;
import main.java.com.djrapitops.plan.utilities.html.Html;
import main.java.com.djrapitops.plan.utilities.html.HtmlStructure;
import main.java.com.djrapitops.plan.utilities.html.graphs.WorldPieCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.pie.WorldPieCreator;
import main.java.com.djrapitops.plan.utilities.html.tables.KillsTableCreator;
import main.java.com.djrapitops.plan.utilities.html.tables.SessionsTableCreator;

View File

@ -14,7 +14,7 @@ import main.java.com.djrapitops.plan.systems.cache.SessionCache;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.comparators.SessionStartComparator;
import main.java.com.djrapitops.plan.utilities.html.Html;
import main.java.com.djrapitops.plan.utilities.html.graphs.WorldPieCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.pie.WorldPieCreator;
import java.util.*;
import java.util.stream.Collectors;

View File

@ -130,7 +130,7 @@ Theme:
Entities: Base
WorldPie: '"#0099C6", "#66AA00", "#316395", "#994499", "#22AA99", "#AAAA11", "#6633CC", "#E67300", "#329262", "#5574A6"'
GMDrilldown: '"#438c99", "#639A67", "#D8EBB5", "#D9BF77"'
ActivityPie: '"#228B22", "#A9A9A9", "#808080", "#951800"'
ActivityPie: '"#4CAF50", "#8BC34A", "#CDDC39", "#FFC107", "#607D8B"'
ServerPreferencePie: '"#0099C6", "#66AA00", "#316395", "#994499", "#22AA99", "#AAAA11", "#6633CC", "#E67300", "#329262", "#5574A6"'
# -----------------------------------------------------
Plugins:

View File

@ -1,4 +1,4 @@
function activityPie(id, activitySeries, activityTotal, activityColors) {
function activityPie(id, activitySeries) {
Highcharts.chart(id, {
chart: {
plotBackgroundColor: null,
@ -17,7 +17,6 @@ function activityPie(id, activitySeries, activityTotal, activityColors) {
dataLabels: {
enabled: false
},
// colors: activityColors,
showInLegend: true
}
},

View File

@ -0,0 +1,44 @@
function activityStackChart(id, categories, activitySeries) {
Highcharts.chart(id, {
chart: {
type: 'area'
},
title: {
text: ''
},
xAxis: {
categories: categories,
tickmarkPlacement: 'on',
title: {
enabled: false
}
},
yAxis: {
title: {
text: 'Players'
},
labels: {
formatter: function () {
return this.value;
}
}
},
tooltip: {
split: true,
valueSuffix: ' Players'
},
plotOptions: {
area: {
stacking: 'normal',
// lineColor: '#666666',
lineWidth: 1
// ,
// marker: {
// lineWidth: 1,
// lineColor: '#666666'
// }
}
},
series: activitySeries
});
}

View File

@ -603,7 +603,7 @@
</div>
</div>
<div class="body">
<div id="activityGraph" class="dashboard-flot-chart"></div>
<div id="activityStackGraph" class="dashboard-flot-chart"></div>
</div>
</div>
</div>
@ -943,6 +943,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/activityStackGraph.js"></script>
<script src="js/charts/worldPie.js"></script>
<script src="js/charts/performanceGraph.js"></script>
<script src="js/charts/tpsGraph.js"></script>
@ -1026,22 +1027,7 @@
var activitySeries = {
name: 'Players',
colorByPoint: true,
colors: [${activityPieColors}],
data: [{
name: 'Active',
y: ${active}
}, {
name: 'Inactive',
y: ${inactive},
sliced: true,
selected: true
}, {
name: 'Single Join',
y: ${joinLeaver}
}, {
name: 'Banned',
y: ${banned}
}]
data: ${activityPieSeries}
};
var worldSeries = {
name: 'World Playtime',
@ -1062,6 +1048,8 @@
color: '#222',
data: ${punchCardSeries}
};
var activityStackSeries = ${activityStackSeries};
var activityCategories = [${activityStackCategories}]
</script>
<!-- Plan load script -->
@ -1089,7 +1077,8 @@
openFunc(slideIndex)();
// Chart draw scripts
activityPie('activityPie', activitySeries, ${playersTotal}, [${activityPieColors}]);
activityPie('activityPie', activitySeries);
activityStackChart('activityStackGraph', activityCategories, activityStackSeries);
worldPie('worldPie', worldSeries, gmSeries);
playersChart('playerChartDay', playersOnlineSeries, 3);
playersChart('playerChartMonth', playersOnlineSeries, 2);

View File

@ -8,7 +8,8 @@ import main.java.com.djrapitops.plan.data.Session;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.data.time.WorldTimes;
import main.java.com.djrapitops.plan.utilities.analysis.Point;
import main.java.com.djrapitops.plan.utilities.html.graphs.*;
import main.java.com.djrapitops.plan.utilities.html.graphs.PunchCardGraphCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.line.*;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.plugin.java.JavaPlugin;
import org.junit.Assert;