mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-28 20:17:42 +01:00
Refactored Graphs to be Objects. Sensible after "Creator" name removal.
This commit is contained in:
parent
34198543ff
commit
a22aa95c22
@ -1,97 +0,0 @@
|
|||||||
package com.djrapitops.plan;
|
|
||||||
|
|
||||||
import com.djrapitops.plan.system.settings.Settings;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import org.bukkit.Server;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class responsible for holding server variable values that do not change
|
|
||||||
* without a reload.
|
|
||||||
*
|
|
||||||
* @author Rsl1122
|
|
||||||
* @since 3.4.1
|
|
||||||
*/
|
|
||||||
public class ServerVariableHolder {
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
private final int port;
|
|
||||||
private final String version;
|
|
||||||
private final String implVersion;
|
|
||||||
private final String ip;
|
|
||||||
private final int maxPlayers;
|
|
||||||
private final boolean usingPaper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor, grabs the variables.
|
|
||||||
*
|
|
||||||
* @param server instance the plugin is running on.
|
|
||||||
*/
|
|
||||||
public ServerVariableHolder(Server server) {
|
|
||||||
ip = server.getIp();
|
|
||||||
name = server.getName();
|
|
||||||
port = server.getPort();
|
|
||||||
version = server.getVersion();
|
|
||||||
implVersion = server.getBukkitVersion();
|
|
||||||
|
|
||||||
maxPlayers = server.getMaxPlayers();
|
|
||||||
|
|
||||||
usingPaper = name.equals("Paper")
|
|
||||||
|| name.equals("TacoSpigot"); //Fork of Paper
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor, grabs the variables.
|
|
||||||
*
|
|
||||||
* @param server instance the plugin is running on.
|
|
||||||
*/
|
|
||||||
public ServerVariableHolder(ProxyServer server) {
|
|
||||||
ip = Settings.BUNGEE_IP.toString();
|
|
||||||
name = "BungeeCord";
|
|
||||||
port = -1;
|
|
||||||
version = server.getVersion();
|
|
||||||
implVersion = server.getVersion();
|
|
||||||
|
|
||||||
maxPlayers = server.getConfig().getPlayerLimit();
|
|
||||||
|
|
||||||
usingPaper = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ip string in server.properties.
|
|
||||||
*
|
|
||||||
* @return the ip.
|
|
||||||
*/
|
|
||||||
public String getIp() {
|
|
||||||
return ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if the server is using PaperSpigot.
|
|
||||||
*
|
|
||||||
* @return if the server is using PaperSpigot.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public boolean isUsingPaper() {
|
|
||||||
return usingPaper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPort() {
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVersion() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getImplVersion() {
|
|
||||||
return implVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaxPlayers() {
|
|
||||||
return maxPlayers;
|
|
||||||
}
|
|
||||||
}
|
|
@ -144,11 +144,11 @@ public class AnalysisData extends RawData {
|
|||||||
|
|
||||||
Map<String, Set<UUID>> activityNow = activityData.getOrDefault(now, new HashMap<>());
|
Map<String, Set<UUID>> activityNow = activityData.getOrDefault(now, new HashMap<>());
|
||||||
|
|
||||||
String[] activityStackSeries = ActivityStackGraph.createSeries(activityData);
|
ActivityStackGraph activityStackGraph = new ActivityStackGraph(activityData);
|
||||||
String activityPieSeries = ActivityPie.createSeries(activityNow);
|
String activityPieSeries = new ActivityPie(activityNow).toHighChartsSeries();
|
||||||
|
|
||||||
addValue("activityStackCategories", activityStackSeries[0]);
|
addValue("activityStackCategories", activityStackGraph.toHighChartsLabels());
|
||||||
addValue("activityStackSeries", activityStackSeries[1]);
|
addValue("activityStackSeries", activityStackGraph.toHighChartsSeries());
|
||||||
addValue("activityPieSeries", activityPieSeries);
|
addValue("activityPieSeries", activityPieSeries);
|
||||||
|
|
||||||
Set<UUID> veryActiveNow = activityNow.getOrDefault("Very Active", new HashSet<>());
|
Set<UUID> veryActiveNow = activityNow.getOrDefault("Very Active", new HashSet<>());
|
||||||
@ -171,7 +171,7 @@ public class AnalysisData extends RawData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void geolocationsTab(List<String> geoLocations) {
|
private void geolocationsTab(List<String> geoLocations) {
|
||||||
addValue("geoMapSeries", WorldMap.createSeries(geoLocations));
|
addValue("geoMapSeries", new WorldMap(geoLocations).toHighChartsSeries());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onlineActivityNumbers(ServerProfile profile, Map<UUID, List<Session>> sessions, List<PlayerProfile> players) {
|
private void onlineActivityNumbers(ServerProfile profile, Map<UUID, List<Session>> sessions, List<PlayerProfile> players) {
|
||||||
@ -286,7 +286,7 @@ public class AnalysisData extends RawData {
|
|||||||
addValue("tableBodySessions", tables[0]);
|
addValue("tableBodySessions", tables[0]);
|
||||||
addValue("listRecentLogins", tables[1]);
|
addValue("listRecentLogins", tables[1]);
|
||||||
addValue("sessionAverage", FormatUtils.formatTimeAmount(MathUtils.averageLong(allSessions.stream().map(Session::getLength))));
|
addValue("sessionAverage", FormatUtils.formatTimeAmount(MathUtils.averageLong(allSessions.stream().map(Session::getLength))));
|
||||||
addValue("punchCardSeries", PunchCardGraph.createSeries(sessionsMonth));
|
addValue("punchCardSeries", new PunchCardGraph(sessionsMonth).toHighChartsSeries());
|
||||||
|
|
||||||
addValue("deaths", ServerProfile.getDeathCount(allSessions));
|
addValue("deaths", ServerProfile.getDeathCount(allSessions));
|
||||||
addValue("mobKillCount", ServerProfile.getMobKillCount(allSessions));
|
addValue("mobKillCount", ServerProfile.getMobKillCount(allSessions));
|
||||||
@ -303,9 +303,9 @@ public class AnalysisData extends RawData {
|
|||||||
Html.TABLE_PLAYERS_FOOTER.parse(playersTableBody)
|
Html.TABLE_PLAYERS_FOOTER.parse(playersTableBody)
|
||||||
: Html.TABLE_PLAYERS.parse(playersTableBody));
|
: Html.TABLE_PLAYERS.parse(playersTableBody));
|
||||||
addValue("worldTotal", FormatUtils.formatTimeAmount(worldTimes.getTotal()));
|
addValue("worldTotal", FormatUtils.formatTimeAmount(worldTimes.getTotal()));
|
||||||
String[] seriesData = WorldPie.createSeries(worldTimes);
|
WorldPie worldPie = new WorldPie(worldTimes);
|
||||||
addValue("worldSeries", seriesData[0]);
|
addValue("worldSeries", worldPie.toHighChartsSeries());
|
||||||
addValue("gmSeries", seriesData[1]);
|
addValue("gmSeries", worldPie.toHighChartsDrilldown());
|
||||||
addValue("lastPeakTime", lastPeak != -1 ? FormatUtils.formatTimeStampYear(lastPeak) : "No Data");
|
addValue("lastPeakTime", lastPeak != -1 ? FormatUtils.formatTimeStampYear(lastPeak) : "No Data");
|
||||||
addValue("playersLastPeak", lastPeak != -1 ? profile.getLastPeakPlayers() : "-");
|
addValue("playersLastPeak", lastPeak != -1 ? profile.getLastPeakPlayers() : "-");
|
||||||
addValue("bestPeakTime", allTimePeak != -1 ? FormatUtils.formatTimeStampYear(allTimePeak) : "No Data");
|
addValue("bestPeakTime", allTimePeak != -1 ? FormatUtils.formatTimeStampYear(allTimePeak) : "No Data");
|
||||||
@ -320,12 +320,12 @@ public class AnalysisData extends RawData {
|
|||||||
addValue("tpsSpikeWeek", value("tpsSpikeWeek"));
|
addValue("tpsSpikeWeek", value("tpsSpikeWeek"));
|
||||||
addValue("tpsSpikeDay", value("tpsSpikeDay"));
|
addValue("tpsSpikeDay", value("tpsSpikeDay"));
|
||||||
|
|
||||||
addValue("playersOnlineSeries", PlayerActivityGraph.createSeries(tpsData));
|
addValue("playersOnlineSeries", new OnlineActivityGraph(tpsData).toHighChartsSeries());
|
||||||
addValue("tpsSeries", TPSGraph.createSeries(tpsData));
|
addValue("tpsSeries", new TPSGraph(tpsData).toHighChartsSeries());
|
||||||
addValue("cpuSeries", CPUGraph.createSeries(tpsData));
|
addValue("cpuSeries", new CPUGraph(tpsData).toHighChartsSeries());
|
||||||
addValue("ramSeries", RamGraph.createSeries(tpsData));
|
addValue("ramSeries", new RamGraph(tpsData).toHighChartsSeries());
|
||||||
addValue("entitySeries", WorldLoadGraph.createSeriesEntities(tpsData));
|
addValue("entitySeries", new EntityGraph(tpsData).toHighChartsSeries());
|
||||||
addValue("chunkSeries", WorldLoadGraph.createSeriesChunks(tpsData));
|
addValue("chunkSeries", new ChunkGraph(tpsData).toHighChartsSeries());
|
||||||
|
|
||||||
double averageCPUMonth = MathUtils.averageDouble(tpsDataMonth.stream().map(TPS::getCPUUsage).filter(i -> i != 0));
|
double averageCPUMonth = MathUtils.averageDouble(tpsDataMonth.stream().map(TPS::getCPUUsage).filter(i -> i != 0));
|
||||||
double averageCPUWeek = MathUtils.averageDouble(tpsDataWeek.stream().map(TPS::getCPUUsage).filter(i -> i != 0));
|
double averageCPUWeek = MathUtils.averageDouble(tpsDataWeek.stream().map(TPS::getCPUUsage).filter(i -> i != 0));
|
||||||
|
@ -21,6 +21,10 @@ public class ActivityIndex {
|
|||||||
return value < 0 ? 1 : value;
|
return value < 0 ? 1 : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String[] getGroups() {
|
||||||
|
return new String[]{"Very Active", "Active", "Regular", "Irregular", "Inactive"};
|
||||||
|
}
|
||||||
|
|
||||||
private double calculate(PlayerProfile player, long date) {
|
private double calculate(PlayerProfile player, long date) {
|
||||||
long week = TimeAmount.WEEK.ms();
|
long week = TimeAmount.WEEK.ms();
|
||||||
long weekAgo = date - week;
|
long weekAgo = date - week;
|
||||||
|
@ -27,7 +27,7 @@ import com.djrapitops.plan.utilities.file.FileUtil;
|
|||||||
import com.djrapitops.plan.utilities.html.HtmlStructure;
|
import com.djrapitops.plan.utilities.html.HtmlStructure;
|
||||||
import com.djrapitops.plan.utilities.html.HtmlUtils;
|
import com.djrapitops.plan.utilities.html.HtmlUtils;
|
||||||
import com.djrapitops.plan.utilities.html.graphs.PunchCardGraph;
|
import com.djrapitops.plan.utilities.html.graphs.PunchCardGraph;
|
||||||
import com.djrapitops.plan.utilities.html.graphs.line.ServerPreferencePie;
|
import com.djrapitops.plan.utilities.html.graphs.pie.ServerPreferencePie;
|
||||||
import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie;
|
import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie;
|
||||||
import com.djrapitops.plan.utilities.html.structure.ServerAccordionCreator;
|
import com.djrapitops.plan.utilities.html.structure.ServerAccordionCreator;
|
||||||
import com.djrapitops.plan.utilities.html.tables.ActionsTableCreator;
|
import com.djrapitops.plan.utilities.html.tables.ActionsTableCreator;
|
||||||
@ -110,7 +110,7 @@ public class InspectPage extends Page {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Map<UUID, WorldTimes> worldTimesPerServer = profile.getWorldTimesPerServer();
|
Map<UUID, WorldTimes> worldTimesPerServer = profile.getWorldTimesPerServer();
|
||||||
addValue("serverPieSeries", ServerPreferencePie.createSeries(serverNames, worldTimesPerServer));
|
addValue("serverPieSeries", new ServerPreferencePie(serverNames, worldTimesPerServer).toHighChartsSeries());
|
||||||
addValue("worldPieColors", Theme.getValue(ThemeVal.GRAPH_WORLD_PIE));
|
addValue("worldPieColors", Theme.getValue(ThemeVal.GRAPH_WORLD_PIE));
|
||||||
addValue("gmPieColors", Theme.getValue(ThemeVal.GRAPH_GM_PIE));
|
addValue("gmPieColors", Theme.getValue(ThemeVal.GRAPH_GM_PIE));
|
||||||
addValue("serverPieColors", Theme.getValue(ThemeVal.GRAPH_SERVER_PREF_PIE));
|
addValue("serverPieColors", Theme.getValue(ThemeVal.GRAPH_SERVER_PREF_PIE));
|
||||||
@ -197,14 +197,14 @@ public class InspectPage extends Page {
|
|||||||
List<Action> actions = profile.getAllActions();
|
List<Action> actions = profile.getAllActions();
|
||||||
addValue("tableBodyActions", ActionsTableCreator.createTable(actions));
|
addValue("tableBodyActions", ActionsTableCreator.createTable(actions));
|
||||||
|
|
||||||
String punchCardData = PunchCardGraph.createSeries(allSessions);
|
String punchCardData = new PunchCardGraph(allSessions).toHighChartsSeries();
|
||||||
WorldTimes worldTimes = profile.getWorldTimes();
|
WorldTimes worldTimes = profile.getWorldTimes();
|
||||||
AnalysisUtils.addMissingWorlds(worldTimes);
|
AnalysisUtils.addMissingWorlds(worldTimes);
|
||||||
|
|
||||||
String[] worldPieData = WorldPie.createSeries(worldTimes);
|
WorldPie worldPie = new WorldPie(worldTimes);
|
||||||
|
|
||||||
addValue("worldPieSeries", worldPieData[0]);
|
addValue("worldPieSeries", worldPie.toHighChartsSeries());
|
||||||
addValue("gmSeries", worldPieData[1]);
|
addValue("gmSeries", worldPie.toHighChartsDrilldown());
|
||||||
|
|
||||||
addValue("punchCardSeries", punchCardData);
|
addValue("punchCardSeries", punchCardData);
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ import com.djrapitops.plan.utilities.analysis.AnalysisUtils;
|
|||||||
import com.djrapitops.plan.utilities.file.FileUtil;
|
import com.djrapitops.plan.utilities.file.FileUtil;
|
||||||
import com.djrapitops.plan.utilities.html.HtmlStructure;
|
import com.djrapitops.plan.utilities.html.HtmlStructure;
|
||||||
import com.djrapitops.plan.utilities.html.HtmlUtils;
|
import com.djrapitops.plan.utilities.html.HtmlUtils;
|
||||||
import com.djrapitops.plan.utilities.html.graphs.line.PlayerActivityGraph;
|
import com.djrapitops.plan.utilities.html.graphs.line.OnlineActivityGraph;
|
||||||
import com.djrapitops.plugin.api.TimeAmount;
|
import com.djrapitops.plugin.api.TimeAmount;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -56,7 +56,7 @@ public class NetworkPage extends Page {
|
|||||||
addValue("timeZone", MiscUtils.getTimeZoneOffsetHours());
|
addValue("timeZone", MiscUtils.getTimeZoneOffsetHours());
|
||||||
addValue("networkName", Settings.BUNGEE_NETWORK_NAME.toString());
|
addValue("networkName", Settings.BUNGEE_NETWORK_NAME.toString());
|
||||||
addValue("version", plugin.getVersion());
|
addValue("version", plugin.getVersion());
|
||||||
addValue("playersOnlineSeries", PlayerActivityGraph.createSeries(networkOnlineData));
|
addValue("playersOnlineSeries", new OnlineActivityGraph(networkOnlineData).toHighChartsSeries());
|
||||||
addValue("playersGraphColor", Theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE));
|
addValue("playersGraphColor", Theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE));
|
||||||
addValue("playersOnline", plugin.getProxy().getOnlineCount());
|
addValue("playersOnline", plugin.getProxy().getOnlineCount());
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import com.djrapitops.plan.system.info.server.ServerProperties;
|
|||||||
import com.djrapitops.plan.system.settings.Settings;
|
import com.djrapitops.plan.system.settings.Settings;
|
||||||
import com.djrapitops.plan.systems.info.BukkitInformationManager;
|
import com.djrapitops.plan.systems.info.BukkitInformationManager;
|
||||||
import com.djrapitops.plan.utilities.FormatUtils;
|
import com.djrapitops.plan.utilities.FormatUtils;
|
||||||
import com.djrapitops.plan.utilities.html.graphs.line.PlayerActivityGraph;
|
import com.djrapitops.plan.utilities.html.graphs.line.OnlineActivityGraph;
|
||||||
import com.djrapitops.plan.utilities.html.structure.SessionTabStructureCreator;
|
import com.djrapitops.plan.utilities.html.structure.SessionTabStructureCreator;
|
||||||
import com.djrapitops.plan.utilities.html.tables.SessionsTableCreator;
|
import com.djrapitops.plan.utilities.html.tables.SessionsTableCreator;
|
||||||
import com.djrapitops.plugin.api.utility.log.Log;
|
import com.djrapitops.plugin.api.utility.log.Log;
|
||||||
@ -108,7 +108,7 @@ public class HtmlStructure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String createServerContainer(Plan plugin) {
|
public static String createServerContainer(Plan plugin) {
|
||||||
ServerProperties variable = plugin.getVariable();
|
ServerProperties variable = ServerInfo.getServerProperties();
|
||||||
int maxPlayers = variable.getMaxPlayers();
|
int maxPlayers = variable.getMaxPlayers();
|
||||||
int online = plugin.getServer().getOnlinePlayers().size();
|
int online = plugin.getServer().getOnlinePlayers().size();
|
||||||
Optional<Long> analysisRefreshDate = ((BukkitInformationManager) plugin.getInfoManager()).getAnalysisRefreshDate();
|
Optional<Long> analysisRefreshDate = ((BukkitInformationManager) plugin.getInfoManager()).getAnalysisRefreshDate();
|
||||||
@ -127,7 +127,7 @@ public class HtmlStructure {
|
|||||||
String playerData = "[]";
|
String playerData = "[]";
|
||||||
try {
|
try {
|
||||||
playerCount = db.count().getServerPlayerCount(serverUUID);
|
playerCount = db.count().getServerPlayerCount(serverUUID);
|
||||||
playerData = PlayerActivityGraph.createSeries(db.fetch().getTPSData(serverUUID));
|
playerData = new OnlineActivityGraph(db.fetch().getTPSData(serverUUID)).toHighChartsSeries();
|
||||||
} catch (DBException e) {
|
} catch (DBException e) {
|
||||||
Log.toLog(HtmlStructure.class.getClass().getName(), e);
|
Log.toLog(HtmlStructure.class.getClass().getName(), e);
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.djrapitops.plan.utilities.html.graphs;
|
package com.djrapitops.plan.utilities.html.graphs;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.data.element.ActivityIndex;
|
||||||
import com.djrapitops.plan.settings.theme.Theme;
|
import com.djrapitops.plan.settings.theme.Theme;
|
||||||
import com.djrapitops.plan.settings.theme.ThemeVal;
|
import com.djrapitops.plan.settings.theme.ThemeVal;
|
||||||
import com.djrapitops.plan.utilities.FormatUtils;
|
import com.djrapitops.plan.utilities.FormatUtils;
|
||||||
import com.djrapitops.plan.utilities.html.graphs.pie.ActivityPie;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -15,30 +15,46 @@ import java.util.TreeMap;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Graph creation utility for Activity Stack graph.
|
* Stack Graph that represents evolution of the PlayerBase in terms of ActivityIndex Groups.
|
||||||
*
|
|
||||||
* This graph represents evolution of the playerbase.
|
|
||||||
*
|
*
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
|
* @see ActivityIndex
|
||||||
|
* @since 4.2.0
|
||||||
*/
|
*/
|
||||||
public class ActivityStackGraph {
|
public class ActivityStackGraph implements HighChart {
|
||||||
|
|
||||||
|
private final String[] builtSeries;
|
||||||
|
|
||||||
|
public ActivityStackGraph(TreeMap<Long, Map<String, Set<UUID>>> activityData) {
|
||||||
|
this.builtSeries = createSeries(activityData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toHighChartsLabels() {
|
||||||
|
return builtSeries[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toHighChartsSeries() {
|
||||||
|
return builtSeries[1];
|
||||||
|
}
|
||||||
|
|
||||||
private ActivityStackGraph() {
|
private ActivityStackGraph() {
|
||||||
throw new IllegalStateException("Utility Class");
|
throw new IllegalStateException("Utility Class");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] createSeries(TreeMap<Long, Map<String, Set<UUID>>> activityData) {
|
private String[] createSeries(TreeMap<Long, Map<String, Set<UUID>>> activityData) {
|
||||||
String[] sliceNames = ActivityPie.getSliceNames();
|
String[] groups = ActivityIndex.getGroups();
|
||||||
String[] colors = Theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE).split(", ");
|
String[] colors = Theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE).split(", ");
|
||||||
int maxCol = colors.length;
|
int maxCol = colors.length;
|
||||||
|
|
||||||
StringBuilder[] series = new StringBuilder[sliceNames.length + 1];
|
// Series 0 is Labels for Graph x-axis, others are data for each group.
|
||||||
for (int i = 0; i <= sliceNames.length; i++) {
|
StringBuilder[] series = new StringBuilder[groups.length + 1];
|
||||||
|
for (int i = 0; i <= groups.length; i++) {
|
||||||
series[i] = new StringBuilder();
|
series[i] = new StringBuilder();
|
||||||
}
|
}
|
||||||
for (int i = 1; i <= sliceNames.length; i++) {
|
for (int i = 1; i <= groups.length; i++) {
|
||||||
series[i] = new StringBuilder("{name: '")
|
series[i] = new StringBuilder("{name: '")
|
||||||
.append(sliceNames[i - 1])
|
.append(groups[i - 1])
|
||||||
.append("',color:").append(colors[(i - 1) % maxCol])
|
.append("',color:").append(colors[(i - 1) % maxCol])
|
||||||
.append(",data: [");
|
.append(",data: [");
|
||||||
}
|
}
|
||||||
@ -49,13 +65,13 @@ public class ActivityStackGraph {
|
|||||||
Map<String, Set<UUID>> data = activityData.get(date);
|
Map<String, Set<UUID>> data = activityData.get(date);
|
||||||
|
|
||||||
series[0].append("'").append(FormatUtils.formatTimeStamp(date)).append("'");
|
series[0].append("'").append(FormatUtils.formatTimeStamp(date)).append("'");
|
||||||
for (int j = 1; j <= sliceNames.length; j++) {
|
for (int j = 1; j <= groups.length; j++) {
|
||||||
Set<UUID> players = data.get(sliceNames[j - 1]);
|
Set<UUID> players = data.get(groups[j - 1]);
|
||||||
series[j].append(players != null ? players.size() : 0);
|
series[j].append(players != null ? players.size() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < size - 1) {
|
if (i < size - 1) {
|
||||||
for (int j = 0; j <= sliceNames.length; j++) {
|
for (int j = 0; j <= groups.length; j++) {
|
||||||
series[j].append(",");
|
series[j].append(",");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,9 +80,9 @@ public class ActivityStackGraph {
|
|||||||
|
|
||||||
StringBuilder seriesBuilder = new StringBuilder("[");
|
StringBuilder seriesBuilder = new StringBuilder("[");
|
||||||
|
|
||||||
for (int j = 1; j <= sliceNames.length; j++) {
|
for (int j = 1; j <= groups.length; j++) {
|
||||||
seriesBuilder.append(series[j].append("]}").toString());
|
seriesBuilder.append(series[j].append("]}").toString());
|
||||||
if (j < sliceNames.length) {
|
if (j < groups.length) {
|
||||||
seriesBuilder.append(",");
|
seriesBuilder.append(",");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for Graphs with HighCharts data support.
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
*/
|
||||||
|
public interface HighChart {
|
||||||
|
|
||||||
|
String toHighChartsSeries();
|
||||||
|
|
||||||
|
}
|
@ -14,27 +14,26 @@ import java.util.Objects;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class for creating Punch Card Data Array for the JavaScripts.
|
* Bubble Chart that represents login "punches" of players.
|
||||||
*
|
*
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
* @since 3.6.0
|
* @since 4.2.0
|
||||||
*/
|
*/
|
||||||
public class PunchCardGraph {
|
public class PunchCardGraph implements HighChart {
|
||||||
|
|
||||||
|
private final Collection<Session> sessions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor used to hide the public constructor
|
* Constuctor for the graph.
|
||||||
|
*
|
||||||
|
* @param sessions All sessions of All users this PunchCard represents.
|
||||||
*/
|
*/
|
||||||
private PunchCardGraph() {
|
public PunchCardGraph(Collection<Session> sessions) {
|
||||||
throw new IllegalStateException("Utility class");
|
this.sessions = sessions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Creates a PunchCard series data Array for HighCharts
|
public String toHighChartsSeries() {
|
||||||
*
|
|
||||||
* @param sessions Sessions (Unique/Player) to be placed into the PunchCard.
|
|
||||||
* @return Data array as a string.
|
|
||||||
*/
|
|
||||||
public static String createSeries(Collection<Session> sessions) {
|
|
||||||
List<Long> sessionStarts = getSessionStarts(sessions);
|
List<Long> sessionStarts = getSessionStarts(sessions);
|
||||||
List<int[]> daysAndHours = AnalysisUtils.getDaysAndHours(sessionStarts);
|
List<int[]> daysAndHours = AnalysisUtils.getDaysAndHours(sessionStarts);
|
||||||
int[][] dataArray = turnIntoArray(daysAndHours);
|
int[][] dataArray = turnIntoArray(daysAndHours);
|
||||||
|
@ -4,57 +4,24 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class WorldMap {
|
/**
|
||||||
|
* World Map that uses iso-a3 specification of Country codes.
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
* @since 4.2.0
|
||||||
|
*/
|
||||||
|
public class WorldMap implements HighChart {
|
||||||
|
|
||||||
/**
|
private final List<String> geoLocations;
|
||||||
* Constructor used to hide the public constructor
|
|
||||||
*/
|
|
||||||
private WorldMap() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public WorldMap(List<String> geoLocations) {
|
||||||
* Creates a data series with iso-a3 specification of Country codes.
|
this.geoLocations = geoLocations;
|
||||||
*
|
|
||||||
* @param geoLocations The country names of players
|
|
||||||
* @return The created data series
|
|
||||||
*/
|
|
||||||
public static String createSeries(List<String> geoLocations) {
|
|
||||||
|
|
||||||
Map<String, Integer> geoCodeCounts = new HashMap<>();
|
|
||||||
Map<String, String> geoCodes = getGeoCodes(geoCodeCounts);
|
|
||||||
|
|
||||||
for (String geoLocation : geoLocations) {
|
|
||||||
String countryCode = geoCodes.get(geoLocation);
|
|
||||||
if (countryCode != null) {
|
|
||||||
geoCodeCounts.computeIfPresent(countryCode, (computedCountry, amount) -> amount + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder arrayBuilder = new StringBuilder("[");
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
int size = geoCodeCounts.size();
|
|
||||||
for (Map.Entry<String, Integer> entry : geoCodeCounts.entrySet()) {
|
|
||||||
String geoCode = entry.getKey();
|
|
||||||
Integer players = entry.getValue();
|
|
||||||
|
|
||||||
if (players != 0) {
|
|
||||||
arrayBuilder.append("{'code':'").append(geoCode).append("','value':").append(players).append("}");
|
|
||||||
if (i < size - 1) {
|
|
||||||
arrayBuilder.append(",");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
arrayBuilder.append("]");
|
|
||||||
return arrayBuilder.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, String> getGeoCodes(Map<String, Integer> geoCodeCounts) {
|
private static Map<String, String> getGeoCodes(Map<String, Integer> geoCodeCounts) {
|
||||||
Map<String, String> geoCodes = new HashMap<>();
|
Map<String, String> geoCodes = new HashMap<>();
|
||||||
|
// Countries & Codes have been copied from a iso-a3 specification file.
|
||||||
|
// Each index corresponds to each code.
|
||||||
String[] countries = new String[]{"Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", "Angola", "Anguilla", "Antigua and Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas, The", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana", "Brazil", "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burma", "Burundi", "Cabo Verde", "Cambodia", "Cameroon", "Canada", "Cayman Islands", "Central African Republic", "Chad", "Chile", "China", "Colombia", "Comoros", "Congo, Democratic Republic of the", "Congo, Republic of the", "Cook Islands", "Costa Rica", "Cote d'Ivoire", "Croatia", "Cuba", "Curacao", "Cyprus", "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia", "Falkland Islands (Islas Malvinas)", "Faroe Islands", "Fiji", "Finland", "France", "French Polynesia", "Gabon", "Gambia, The", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada", "Guam", "Guatemala", "Guernsey", "Guinea-Bissau", "Guinea", "Guyana", "Haiti", "Honduras", "Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Isle of Man", "Israel", "Italy", "Jamaica", "Japan", "Jersey", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Korea, North", "Korea, South", "Kosovo", "Kuwait", "Kyrgyzstan", "Laos", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg", "Macau", "Macedonia", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Mauritania", "Mauritius", "Mexico", "Micronesia, Federated States of", "Moldova", "Monaco", "Mongolia", "Montenegro", "Morocco", "Mozambique", "Namibia", "Nepal", "Netherlands", "New Caledonia", "New Zealand", "Nicaragua", "Nigeria", "Niger", "Niue", "Northern Mariana Islands", "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Poland", "Portugal", "Puerto Rico", "Qatar", "Romania", "Russia", "Rwanda", "Saint Kitts and Nevis", "Saint Lucia", "Saint Martin", "Saint Pierre and Miquelon", "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Sao Tome and Principe", "Saudi Arabia", "Senegal", "Serbia", "Seychelles", "Sierra Leone", "Singapore", "Sint Maarten", "Slovakia", "Slovenia", "Solomon Islands", "Somalia", "South Africa", "South Sudan", "Spain", "Sri Lanka", "Sudan", "Suriname", "Swaziland", "Sweden", "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "Timor-Leste", "Togo", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan", "Tuvalu", "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", "United States", "Uruguay", "Uzbekistan", "Vanuatu", "Venezuela", "Vietnam", "Virgin Islands", "West Bank", "Yemen", "Zambia", "Zimbabwe"};
|
String[] countries = new String[]{"Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", "Angola", "Anguilla", "Antigua and Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas, The", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana", "Brazil", "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burma", "Burundi", "Cabo Verde", "Cambodia", "Cameroon", "Canada", "Cayman Islands", "Central African Republic", "Chad", "Chile", "China", "Colombia", "Comoros", "Congo, Democratic Republic of the", "Congo, Republic of the", "Cook Islands", "Costa Rica", "Cote d'Ivoire", "Croatia", "Cuba", "Curacao", "Cyprus", "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia", "Falkland Islands (Islas Malvinas)", "Faroe Islands", "Fiji", "Finland", "France", "French Polynesia", "Gabon", "Gambia, The", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada", "Guam", "Guatemala", "Guernsey", "Guinea-Bissau", "Guinea", "Guyana", "Haiti", "Honduras", "Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Isle of Man", "Israel", "Italy", "Jamaica", "Japan", "Jersey", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Korea, North", "Korea, South", "Kosovo", "Kuwait", "Kyrgyzstan", "Laos", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg", "Macau", "Macedonia", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Mauritania", "Mauritius", "Mexico", "Micronesia, Federated States of", "Moldova", "Monaco", "Mongolia", "Montenegro", "Morocco", "Mozambique", "Namibia", "Nepal", "Netherlands", "New Caledonia", "New Zealand", "Nicaragua", "Nigeria", "Niger", "Niue", "Northern Mariana Islands", "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Poland", "Portugal", "Puerto Rico", "Qatar", "Romania", "Russia", "Rwanda", "Saint Kitts and Nevis", "Saint Lucia", "Saint Martin", "Saint Pierre and Miquelon", "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Sao Tome and Principe", "Saudi Arabia", "Senegal", "Serbia", "Seychelles", "Sierra Leone", "Singapore", "Sint Maarten", "Slovakia", "Slovenia", "Solomon Islands", "Somalia", "South Africa", "South Sudan", "Spain", "Sri Lanka", "Sudan", "Suriname", "Swaziland", "Sweden", "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "Timor-Leste", "Togo", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan", "Tuvalu", "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", "United States", "Uruguay", "Uzbekistan", "Vanuatu", "Venezuela", "Vietnam", "Virgin Islands", "West Bank", "Yemen", "Zambia", "Zimbabwe"};
|
||||||
String[] codes = new String[]{"AFG", "ALB", "DZA", "ASM", "AND", "AGO", "AIA", "ATG", "ARG", "ARM", "ABW", "AUS", "AUT", "AZE", "BHM", "BHR", "BGD", "BRB", "BLR", "BEL", "BLZ", "BEN", "BMU", "BTN", "BOL", "BIH", "BWA", "BRA", "VGB", "BRN", "BGR", "BFA", "MMR", "BDI", "CPV", "KHM", "CMR", "CAN", "CYM", "CAF", "TCD", "CHL", "CHN", "COL", "COM", "COD", "COG", "COK", "CRI", "CIV", "HRV", "CUB", "CUW", "CYP", "CZE", "DNK", "DJI", "DMA", "DOM", "ECU", "EGY", "SLV", "GNQ", "ERI", "EST", "ETH", "FLK", "FRO", "FJI", "FIN", "FRA", "PYF", "GAB", "GMB", "GEO", "DEU", "GHA", "GIB", "GRC", "GRL", "GRD", "GUM", "GTM", "GGY", "GNB", "GIN", "GUY", "HTI", "HND", "HKG", "HUN", "ISL", "IND", "IDN", "IRN", "IRQ", "IRL", "IMN", "ISR", "ITA", "JAM", "JPN", "JEY", "JOR", "KAZ", "KEN", "KIR", "KOR", "PRK", "KSV", "KWT", "KGZ", "LAO", "LVA", "LBN", "LSO", "LBR", "LBY", "LIE", "LTU", "LUX", "MAC", "MKD", "MDG", "MWI", "MYS", "MDV", "MLI", "MLT", "MHL", "MRT", "MUS", "MEX", "FSM", "MDA", "MCO", "MNG", "MNE", "MAR", "MOZ", "NAM", "NPL", "NLD", "NCL", "NZL", "NIC", "NGA", "NER", "NIU", "MNP", "NOR", "OMN", "PAK", "PLW", "PAN", "PNG", "PRY", "PER", "PHL", "POL", "PRT", "PRI", "QAT", "ROU", "RUS", "RWA", "KNA", "LCA", "MAF", "SPM", "VCT", "WSM", "SMR", "STP", "SAU", "SEN", "SRB", "SYC", "SLE", "SGP", "SXM", "SVK", "SVN", "SLB", "SOM", "ZAF", "SSD", "ESP", "LKA", "SDN", "SUR", "SWZ", "SWE", "CHE", "SYR", "TWN", "TJK", "TZA", "THA", "TLS", "TGO", "TON", "TTO", "TUN", "TUR", "TKM", "TUV", "UGA", "UKR", "ARE", "GBR", "USA", "URY", "UZB", "VUT", "VEN", "VNM", "VGB", "WBG", "YEM", "ZMB", "ZWE"};
|
String[] codes = new String[]{"AFG", "ALB", "DZA", "ASM", "AND", "AGO", "AIA", "ATG", "ARG", "ARM", "ABW", "AUS", "AUT", "AZE", "BHM", "BHR", "BGD", "BRB", "BLR", "BEL", "BLZ", "BEN", "BMU", "BTN", "BOL", "BIH", "BWA", "BRA", "VGB", "BRN", "BGR", "BFA", "MMR", "BDI", "CPV", "KHM", "CMR", "CAN", "CYM", "CAF", "TCD", "CHL", "CHN", "COL", "COM", "COD", "COG", "COK", "CRI", "CIV", "HRV", "CUB", "CUW", "CYP", "CZE", "DNK", "DJI", "DMA", "DOM", "ECU", "EGY", "SLV", "GNQ", "ERI", "EST", "ETH", "FLK", "FRO", "FJI", "FIN", "FRA", "PYF", "GAB", "GMB", "GEO", "DEU", "GHA", "GIB", "GRC", "GRL", "GRD", "GUM", "GTM", "GGY", "GNB", "GIN", "GUY", "HTI", "HND", "HKG", "HUN", "ISL", "IND", "IDN", "IRN", "IRQ", "IRL", "IMN", "ISR", "ITA", "JAM", "JPN", "JEY", "JOR", "KAZ", "KEN", "KIR", "KOR", "PRK", "KSV", "KWT", "KGZ", "LAO", "LVA", "LBN", "LSO", "LBR", "LBY", "LIE", "LTU", "LUX", "MAC", "MKD", "MDG", "MWI", "MYS", "MDV", "MLI", "MLT", "MHL", "MRT", "MUS", "MEX", "FSM", "MDA", "MCO", "MNG", "MNE", "MAR", "MOZ", "NAM", "NPL", "NLD", "NCL", "NZL", "NIC", "NGA", "NER", "NIU", "MNP", "NOR", "OMN", "PAK", "PLW", "PAN", "PNG", "PRY", "PER", "PHL", "POL", "PRT", "PRI", "QAT", "ROU", "RUS", "RWA", "KNA", "LCA", "MAF", "SPM", "VCT", "WSM", "SMR", "STP", "SAU", "SEN", "SRB", "SYC", "SLE", "SGP", "SXM", "SVK", "SVN", "SLB", "SOM", "ZAF", "SSD", "ESP", "LKA", "SDN", "SUR", "SWZ", "SWE", "CHE", "SYR", "TWN", "TJK", "TZA", "THA", "TLS", "TGO", "TON", "TTO", "TUN", "TUR", "TKM", "TUV", "UGA", "UKR", "ARE", "GBR", "USA", "URY", "UZB", "VUT", "VEN", "VNM", "VGB", "WBG", "YEM", "ZMB", "ZWE"};
|
||||||
for (int i = 0; i < countries.length; i++) {
|
for (int i = 0; i < countries.length; i++) {
|
||||||
@ -66,4 +33,38 @@ public class WorldMap {
|
|||||||
}
|
}
|
||||||
return geoCodes;
|
return geoCodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toHighChartsSeries() {
|
||||||
|
Map<String, Integer> geoCodeCounts = new HashMap<>();
|
||||||
|
Map<String, String> geoCodes = getGeoCodes(geoCodeCounts);
|
||||||
|
|
||||||
|
for (String geoLocation : geoLocations) {
|
||||||
|
String countryCode = geoCodes.get(geoLocation);
|
||||||
|
if (countryCode != null) {
|
||||||
|
geoCodeCounts.computeIfPresent(countryCode, (computedCountry, amount) -> amount + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder dataBuilder = new StringBuilder("[");
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int size = geoCodeCounts.size();
|
||||||
|
for (Map.Entry<String, Integer> entry : geoCodeCounts.entrySet()) {
|
||||||
|
String geoCode = entry.getKey();
|
||||||
|
Integer players = entry.getValue();
|
||||||
|
|
||||||
|
if (players != 0) {
|
||||||
|
dataBuilder.append("{'code':'").append(geoCode).append("','value':").append(players).append("}");
|
||||||
|
if (i < size - 1) {
|
||||||
|
dataBuilder.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataBuilder.append("]");
|
||||||
|
return dataBuilder.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.djrapitops.plan.utilities.html.graphs.line;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.utilities.analysis.DouglasPeuckerAlgorithm;
|
||||||
|
import com.djrapitops.plan.utilities.analysis.Point;
|
||||||
|
import com.djrapitops.plan.utilities.analysis.ReduceGapTriangles;
|
||||||
|
import com.djrapitops.plan.utilities.html.graphs.HighChart;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a LineGraph for any set of Points, thus it is Abstract.
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
* @since 4.2.0
|
||||||
|
*/
|
||||||
|
public class AbstractLineGraph implements HighChart {
|
||||||
|
|
||||||
|
protected List<Point> points;
|
||||||
|
protected boolean reduceGapTriangles = false;
|
||||||
|
protected boolean reducePoints = false;
|
||||||
|
|
||||||
|
public AbstractLineGraph() {
|
||||||
|
points = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractLineGraph(List<Point> points) {
|
||||||
|
this.points = points;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toHighChartsSeries() {
|
||||||
|
StringBuilder arrayBuilder = new StringBuilder("[");
|
||||||
|
|
||||||
|
if (reducePoints) {
|
||||||
|
points = DouglasPeuckerAlgorithm.reducePoints(points, 0);
|
||||||
|
}
|
||||||
|
if (reduceGapTriangles) {
|
||||||
|
points = ReduceGapTriangles.reduce(points);
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = points.size();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
Point point = points.get(i);
|
||||||
|
double y = point.getY();
|
||||||
|
long date = (long) point.getX();
|
||||||
|
arrayBuilder.append("[").append(date).append(",").append(y).append("]");
|
||||||
|
if (i < size - 1) {
|
||||||
|
arrayBuilder.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
arrayBuilder.append("]");
|
||||||
|
return arrayBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reduceGapTriangles() {
|
||||||
|
this.reduceGapTriangles = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reducePoints() {
|
||||||
|
this.reducePoints = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPoints(List<Point> points) {
|
||||||
|
this.points = points;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPoints(Collection<Point> points) {
|
||||||
|
this.points.addAll(points);
|
||||||
|
}
|
||||||
|
}
|
@ -6,19 +6,22 @@ import com.djrapitops.plan.utilities.analysis.Point;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class CPUGraph {
|
/**
|
||||||
|
* Graph about CPU Usage gathered by TPSCountTimer.
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
* @see com.djrapitops.plan.system.tasks.TPSCountTimer
|
||||||
|
* @since 4.2.0
|
||||||
|
*/
|
||||||
|
public class CPUGraph extends AbstractLineGraph {
|
||||||
|
|
||||||
/**
|
public CPUGraph(List<TPS> tpsData) {
|
||||||
* Constructor used to hide the public constructor
|
super(transformToPoints(tpsData));
|
||||||
*/
|
|
||||||
private CPUGraph() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String createSeries(List<TPS> tpsData) {
|
private static List<Point> transformToPoints(List<TPS> tpsData) {
|
||||||
List<Point> points = tpsData.stream()
|
return tpsData.stream()
|
||||||
.map(tps -> new Point(tps.getDate(), tps.getCPUUsage()))
|
.map(tps -> new Point(tps.getDate(), tps.getCPUUsage()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
return LineSeries.createSeries(points, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.djrapitops.plan.utilities.html.graphs.line;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.data.container.TPS;
|
||||||
|
import com.djrapitops.plan.utilities.analysis.Point;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Graph about Chunk Counts gathered by TPSCountTimer.
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
* @see com.djrapitops.plan.system.tasks.TPSCountTimer
|
||||||
|
* @since 4.2.0
|
||||||
|
*/
|
||||||
|
public class ChunkGraph extends AbstractLineGraph {
|
||||||
|
|
||||||
|
public ChunkGraph(List<TPS> tpsData) {
|
||||||
|
super(turnToPoints(tpsData));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Point> turnToPoints(List<TPS> tpsData) {
|
||||||
|
return tpsData.stream()
|
||||||
|
.map(tps -> new Point(tps.getDate(), tps.getChunksLoaded()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.djrapitops.plan.utilities.html.graphs.line;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.data.container.TPS;
|
||||||
|
import com.djrapitops.plan.utilities.analysis.Point;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Graph about Entity Counts gathered by TPSCountTimer.
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
* @see com.djrapitops.plan.system.tasks.TPSCountTimer
|
||||||
|
* @since 4.2.0
|
||||||
|
*/
|
||||||
|
public class EntityGraph extends AbstractLineGraph {
|
||||||
|
|
||||||
|
public EntityGraph(List<TPS> tpsData) {
|
||||||
|
super(turnToPoints(tpsData));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Point> turnToPoints(List<TPS> tpsData) {
|
||||||
|
return tpsData.stream()
|
||||||
|
.map(tps -> new Point(tps.getDate(), tps.getEntityCount()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package com.djrapitops.plan.utilities.html.graphs.line;
|
|
||||||
|
|
||||||
import com.djrapitops.plan.utilities.analysis.Point;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract scatter graph creator used by other graph creators.
|
|
||||||
*
|
|
||||||
* @author Rsl1122
|
|
||||||
* @since 3.5.2
|
|
||||||
*/
|
|
||||||
public class LineSeries {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor used to hide the public constructor
|
|
||||||
*/
|
|
||||||
private LineSeries() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String createSeries(List<Point> points, boolean reduceGapTriangles) {
|
|
||||||
return createSeries(points, reduceGapTriangles, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String createSeries(List<Point> points, boolean reduceGapTriangles, boolean reducePoints) {
|
|
||||||
StringBuilder arrayBuilder = new StringBuilder("[");
|
|
||||||
|
|
||||||
// if (reducePoints) {
|
|
||||||
// points = DouglasPeuckerAlgorithm.reducePoints(points, 0);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (reduceGapTriangles) {
|
|
||||||
// points = ReduceGapTriangles.reduce(points);
|
|
||||||
// }
|
|
||||||
|
|
||||||
int size = points.size();
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
Point point = points.get(i);
|
|
||||||
double y = point.getY();
|
|
||||||
long date = (long) point.getX();
|
|
||||||
arrayBuilder.append("[").append(date).append(",").append(y).append("]");
|
|
||||||
if (i < size - 1) {
|
|
||||||
arrayBuilder.append(",");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
arrayBuilder.append("]");
|
|
||||||
return arrayBuilder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,21 +7,21 @@ import java.util.List;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Graph about Player Counts gathered by TPSCountTimer.
|
||||||
|
*
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
|
* @see com.djrapitops.plan.system.tasks.TPSCountTimer
|
||||||
|
* @since 4.2.0
|
||||||
*/
|
*/
|
||||||
public class PlayerActivityGraph {
|
public class OnlineActivityGraph extends AbstractLineGraph {
|
||||||
|
|
||||||
/**
|
public OnlineActivityGraph(List<TPS> tpsData) {
|
||||||
* Constructor used to hide the public constructor
|
super(turnToPoints(tpsData));
|
||||||
*/
|
|
||||||
private PlayerActivityGraph() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String createSeries(List<TPS> tpsData) {
|
private static List<Point> turnToPoints(List<TPS> tpsData) {
|
||||||
List<Point> points = tpsData.stream()
|
return tpsData.stream()
|
||||||
.map(tps -> new Point(tps.getDate(), tps.getPlayers()))
|
.map(tps -> new Point(tps.getDate(), tps.getPlayers()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
return LineSeries.createSeries(points, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,38 +1,27 @@
|
|||||||
package com.djrapitops.plan.utilities.html.graphs.line;
|
package com.djrapitops.plan.utilities.html.graphs.line;
|
||||||
|
|
||||||
import com.djrapitops.plan.data.container.TPS;
|
import com.djrapitops.plan.data.container.TPS;
|
||||||
import com.djrapitops.plan.system.tasks.TPSCountTimer;
|
|
||||||
import com.djrapitops.plan.utilities.analysis.Point;
|
import com.djrapitops.plan.utilities.analysis.Point;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for creating scatter graph data from RAM Usage snapshots with TPS task.
|
* Graph about RAM Usage gathered by TPSCountTimer.
|
||||||
*
|
*
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
* @see TPSCountTimer
|
* @see com.djrapitops.plan.system.tasks.TPSCountTimer
|
||||||
* @since 3.6.0
|
* @since 4.2.0
|
||||||
*/
|
*/
|
||||||
public class RamGraph {
|
public class RamGraph extends AbstractLineGraph {
|
||||||
|
|
||||||
/**
|
public RamGraph(List<TPS> tpsData) {
|
||||||
* Constructor used to hide the public constructor
|
super(turnToPoints(tpsData));
|
||||||
*/
|
|
||||||
private RamGraph() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static List<Point> turnToPoints(List<TPS> tpsData) {
|
||||||
* Creates a series data string from given data.
|
return tpsData.stream()
|
||||||
*
|
|
||||||
* @param tpsData TPS Data collected by TPSCountTimer, one data point for each minute.
|
|
||||||
* @return Series data for HighCharts
|
|
||||||
*/
|
|
||||||
public static String createSeries(List<TPS> tpsData) {
|
|
||||||
List<Point> points = tpsData.stream()
|
|
||||||
.map(tps -> new Point(tps.getDate(), tps.getUsedMemory()))
|
.map(tps -> new Point(tps.getDate(), tps.getUsedMemory()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
return LineSeries.createSeries(points, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
package com.djrapitops.plan.utilities.html.graphs.line;
|
|
||||||
|
|
||||||
import com.djrapitops.plan.data.time.WorldTimes;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class ServerPreferencePie {
|
|
||||||
|
|
||||||
private ServerPreferencePie() {
|
|
||||||
throw new IllegalStateException("Utility Class");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String createSeries(Map<UUID, String> serverNames, Map<UUID, WorldTimes> serverWorldTimes) {
|
|
||||||
StringBuilder seriesBuilder = new StringBuilder("[");
|
|
||||||
int i = 0;
|
|
||||||
int size = serverWorldTimes.size();
|
|
||||||
for (Map.Entry<UUID, WorldTimes> server : serverWorldTimes.entrySet()) {
|
|
||||||
String serverName = serverNames.getOrDefault(server.getKey(), "Unknown");
|
|
||||||
seriesBuilder.append("{name:'").append(serverName)
|
|
||||||
.append("',y:").append(server.getValue().getTotal());
|
|
||||||
|
|
||||||
seriesBuilder.append("}");
|
|
||||||
if (i < size - 1) {
|
|
||||||
seriesBuilder.append(",");
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
seriesBuilder.append("]");
|
|
||||||
|
|
||||||
return seriesBuilder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,23 +7,21 @@ import java.util.List;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Graph about TPS gathered by TPSCountTimer.
|
||||||
|
*
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
* @since 3.5.0
|
* @see com.djrapitops.plan.system.tasks.TPSCountTimer
|
||||||
|
* @since 4.2.0
|
||||||
*/
|
*/
|
||||||
public class TPSGraph {
|
public class TPSGraph extends AbstractLineGraph {
|
||||||
|
|
||||||
/**
|
public TPSGraph(List<TPS> tpsData) {
|
||||||
* Constructor used to hide the public constructor
|
super(turnToPoints(tpsData));
|
||||||
*/
|
|
||||||
private TPSGraph() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String createSeries(List<TPS> tpsData) {
|
private static List<Point> turnToPoints(List<TPS> tpsData) {
|
||||||
List<Point> points = tpsData.stream()
|
return tpsData.stream()
|
||||||
.map(tps -> new Point(tps.getDate(), tps.getTicksPerSecond()))
|
.map(tps -> new Point(tps.getDate(), tps.getTicksPerSecond()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
return LineSeries.createSeries(points, true);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
package com.djrapitops.plan.utilities.html.graphs.line;
|
|
||||||
|
|
||||||
import com.djrapitops.plan.data.container.TPS;
|
|
||||||
import com.djrapitops.plan.system.tasks.TPSCountTimer;
|
|
||||||
import com.djrapitops.plan.utilities.analysis.Point;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for creating scatter graph data from Chunk and Entity load snapshots with TPS task.
|
|
||||||
*
|
|
||||||
* @author Rsl1122
|
|
||||||
* @see TPSCountTimer
|
|
||||||
* @since 3.6.0
|
|
||||||
*/
|
|
||||||
public class WorldLoadGraph {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor used to hide the public constructor
|
|
||||||
*/
|
|
||||||
private WorldLoadGraph() {
|
|
||||||
throw new IllegalStateException("Utility class");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates series graph data of entity load.
|
|
||||||
*
|
|
||||||
* @param tpsData TPS Data collected by TPSCountTimer, one data point for each minute.
|
|
||||||
* @return Series data for HighCharts
|
|
||||||
*/
|
|
||||||
public static String createSeriesEntities(List<TPS> tpsData) {
|
|
||||||
List<Point> points = tpsData.stream()
|
|
||||||
.map(tps -> new Point(tps.getDate(), tps.getEntityCount()))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
return LineSeries.createSeries(points, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates series data of chunk load.
|
|
||||||
*
|
|
||||||
* @param tpsData TPS Data collected by TPSCountTimer, one data point for each minute.
|
|
||||||
* @return Series data for HighCharts
|
|
||||||
*/
|
|
||||||
public static String createSeriesChunks(List<TPS> tpsData) {
|
|
||||||
List<Point> points = tpsData.stream()
|
|
||||||
.map(tps -> new Point(tps.getDate(), tps.getChunksLoaded()))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
return LineSeries.createSeries(points, true);
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,19 +4,36 @@
|
|||||||
*/
|
*/
|
||||||
package com.djrapitops.plan.utilities.html.graphs.pie;
|
package com.djrapitops.plan.utilities.html.graphs.pie;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.utilities.html.graphs.HighChart;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PieSeries data creation utility class.
|
* This is a PieChart for any set of PieSlices, thus it is Abstract.
|
||||||
*
|
*
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
|
* @since 4.2.0
|
||||||
*/
|
*/
|
||||||
public class PieSeries {
|
public class AbstractPieChart implements HighChart {
|
||||||
private PieSeries() {
|
|
||||||
throw new IllegalStateException("Utility Class");
|
protected List<PieSlice> slices;
|
||||||
|
|
||||||
|
public AbstractPieChart() {
|
||||||
|
slices = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AbstractPieChart(List<PieSlice> slices) {
|
||||||
|
this.slices = slices;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static String createSeries(List<PieSlice> slices) {
|
public static String createSeries(List<PieSlice> slices) {
|
||||||
|
return new AbstractPieChart(slices).toHighChartsSeries();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toHighChartsSeries() {
|
||||||
StringBuilder seriesBuilder = new StringBuilder("[");
|
StringBuilder seriesBuilder = new StringBuilder("[");
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int size = slices.size();
|
int size = slices.size();
|
||||||
@ -31,4 +48,12 @@ public class PieSeries {
|
|||||||
|
|
||||||
return seriesBuilder.toString();
|
return seriesBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSlices(List<PieSlice> slices) {
|
||||||
|
this.slices = slices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSlices(List<PieSlice> slices) {
|
||||||
|
this.slices.addAll(slices);
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* 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.pie;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PieChart with a Pie about each slice as well.
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
*/
|
||||||
|
public abstract class AbstractPieChartWithDrilldown extends AbstractPieChart {
|
||||||
|
|
||||||
|
public AbstractPieChartWithDrilldown() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractPieChartWithDrilldown(List<PieSlice> slices) {
|
||||||
|
super(slices);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String toHighChartsDrilldown();
|
||||||
|
|
||||||
|
}
|
@ -4,40 +4,39 @@
|
|||||||
*/
|
*/
|
||||||
package com.djrapitops.plan.utilities.html.graphs.pie;
|
package com.djrapitops.plan.utilities.html.graphs.pie;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.data.element.ActivityIndex;
|
||||||
import com.djrapitops.plan.settings.theme.Theme;
|
import com.djrapitops.plan.settings.theme.Theme;
|
||||||
import com.djrapitops.plan.settings.theme.ThemeVal;
|
import com.djrapitops.plan.settings.theme.ThemeVal;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class for creating Activity Pie data.
|
* Pie about different Activity Groups defined by ActivityIndex.
|
||||||
*
|
*
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
|
* @see ActivityIndex
|
||||||
|
* @since 4.2.0
|
||||||
*/
|
*/
|
||||||
public class ActivityPie {
|
public class ActivityPie extends AbstractPieChart {
|
||||||
|
|
||||||
private ActivityPie() {
|
public ActivityPie(Map<String, Set<UUID>> activityData) {
|
||||||
throw new IllegalStateException("Utility Class");
|
super(turnToSlices(activityData));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] getSliceNames() {
|
private static List<PieSlice> turnToSlices(Map<String, Set<UUID>> activityData) {
|
||||||
return new String[]{"Very Active", "Active", "Regular", "Irregular", "Inactive"};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String createSeries(Map<String, Set<UUID>> activityData) {
|
|
||||||
String[] colors = Theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE).split(", ");
|
String[] colors = Theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE).split(", ");
|
||||||
int maxCol = colors.length;
|
int maxCol = colors.length;
|
||||||
|
|
||||||
List<PieSlice> slices = new ArrayList<>();
|
List<PieSlice> slices = new ArrayList<>();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (String slice : getSliceNames()) {
|
for (String group : ActivityIndex.getGroups()) {
|
||||||
Set<UUID> players = activityData.getOrDefault(slice, new HashSet<>());
|
Set<UUID> players = activityData.getOrDefault(group, new HashSet<>());
|
||||||
int num = players.size();
|
int num = players.size();
|
||||||
|
|
||||||
slices.add(new PieSlice(slice, num, colors[i % maxCol], false));
|
slices.add(new PieSlice(group, num, colors[i % maxCol], false));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PieSeries.createSeries(slices);
|
return slices;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,6 +15,18 @@ public class PieSlice {
|
|||||||
private final String color;
|
private final String color;
|
||||||
private final boolean drilldown;
|
private final boolean drilldown;
|
||||||
|
|
||||||
|
public PieSlice(String name, long y) {
|
||||||
|
this(name, y, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PieSlice(String name, long y, String color) {
|
||||||
|
this(name, y, color, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PieSlice(String name, long y, boolean drilldown) {
|
||||||
|
this(name, y, null, drilldown);
|
||||||
|
}
|
||||||
|
|
||||||
public PieSlice(String name, long y, String color, boolean drilldown) {
|
public PieSlice(String name, long y, String color, boolean drilldown) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
@ -25,8 +37,8 @@ public class PieSlice {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "{name:'" + name + "'," +
|
return "{name:'" + name + "'," +
|
||||||
"y:" + y + "," +
|
"y:" + y
|
||||||
"color:" + color
|
+ (color != null ? "," + "color:" + color : "")
|
||||||
+ (drilldown ? "," + "drilldown: '" + name + "'" : "")
|
+ (drilldown ? "," + "drilldown: '" + name + "'" : "")
|
||||||
+ "}";
|
+ "}";
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.djrapitops.plan.utilities.html.graphs.pie;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.data.time.WorldTimes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ServerPreferencePie extends AbstractPieChart {
|
||||||
|
|
||||||
|
public ServerPreferencePie(Map<UUID, String> serverNames, Map<UUID, WorldTimes> serverWorldTimes) {
|
||||||
|
super(turnToSlices(serverNames, serverWorldTimes));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<PieSlice> turnToSlices(Map<UUID, String> serverNames, Map<UUID, WorldTimes> serverWorldTimes) {
|
||||||
|
List<PieSlice> slices = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Map.Entry<UUID, WorldTimes> server : serverWorldTimes.entrySet()) {
|
||||||
|
UUID serverUUID = server.getKey();
|
||||||
|
WorldTimes worldTimes = server.getValue();
|
||||||
|
|
||||||
|
String serverName = serverNames.getOrDefault(serverUUID, "Unknown");
|
||||||
|
long num = worldTimes.getTotal();
|
||||||
|
|
||||||
|
slices.add(new PieSlice(serverName, num));
|
||||||
|
}
|
||||||
|
|
||||||
|
return slices;
|
||||||
|
}
|
||||||
|
}
|
@ -11,30 +11,18 @@ import com.djrapitops.plan.utilities.comparators.PieSliceComparator;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class WorldPie {
|
public class WorldPie extends AbstractPieChartWithDrilldown {
|
||||||
|
|
||||||
private WorldPie() {
|
private WorldTimes worldTimes;
|
||||||
throw new IllegalStateException("Utility Class");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public WorldPie(WorldTimes worldTimes) {
|
||||||
* Used to create HighCharts series string for series and drilldown.
|
super(turnIntoSlices(worldTimes));
|
||||||
*
|
|
||||||
* @param worldTimes WorldTimes object.
|
this.worldTimes = worldTimes;
|
||||||
* @return String array, index 0: Series data, 1: drilldown data
|
|
||||||
*/
|
|
||||||
public static String[] createSeries(WorldTimes worldTimes) {
|
|
||||||
List<PieSlice> slices = turnIntoSlices(worldTimes);
|
|
||||||
|
|
||||||
if (Settings.ORDER_WORLD_PIE_BY_PERC.isTrue()) {
|
if (Settings.ORDER_WORLD_PIE_BY_PERC.isTrue()) {
|
||||||
slices.sort(new PieSliceComparator());
|
slices.sort(new PieSliceComparator());
|
||||||
}
|
}
|
||||||
|
|
||||||
String seriesData = PieSeries.createSeries(slices);
|
|
||||||
|
|
||||||
String drilldownData = createDrilldown(worldTimes);
|
|
||||||
|
|
||||||
return new String[]{seriesData, drilldownData};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<PieSlice> turnIntoSlices(WorldTimes worldTimes) {
|
private static List<PieSlice> turnIntoSlices(WorldTimes worldTimes) {
|
||||||
@ -59,6 +47,7 @@ public class WorldPie {
|
|||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return slices;
|
return slices;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,8 +57,9 @@ public class WorldPie {
|
|||||||
return transformToAliases(playtimePerWorld, aliases);
|
return transformToAliases(playtimePerWorld, aliases);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Move to another class
|
||||||
public static Map<String, Long> transformToAliases(Map<String, Long> playtimePerWorld, Map<String, String> aliases) {
|
public static Map<String, Long> transformToAliases(Map<String, Long> playtimePerWorld, Map<String, String> aliases) {
|
||||||
// TODO Optimization is possible
|
// TODO Optimization is possible (WorldAliasSettings)
|
||||||
WorldAliasSettings aliasSettings = new WorldAliasSettings();
|
WorldAliasSettings aliasSettings = new WorldAliasSettings();
|
||||||
|
|
||||||
Map<String, Long> playtimePerAlias = new HashMap<>();
|
Map<String, Long> playtimePerAlias = new HashMap<>();
|
||||||
@ -89,7 +79,8 @@ public class WorldPie {
|
|||||||
return playtimePerAlias;
|
return playtimePerAlias;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String createDrilldown(WorldTimes worldTimes) {
|
@Override
|
||||||
|
public String toHighChartsDrilldown() {
|
||||||
StringBuilder drilldownBuilder = new StringBuilder();
|
StringBuilder drilldownBuilder = new StringBuilder();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
@ -118,8 +109,8 @@ public class WorldPie {
|
|||||||
return drilldownBuilder.toString();
|
return drilldownBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, GMTimes> transformToGMAliases(Map<String, GMTimes> gmTimesMap) {
|
private Map<String, GMTimes> transformToGMAliases(Map<String, GMTimes> gmTimesMap) {
|
||||||
// TODO Optimization is possible
|
// TODO Optimization is possible (WorldAliasSettings)
|
||||||
WorldAliasSettings aliasSettings = new WorldAliasSettings();
|
WorldAliasSettings aliasSettings = new WorldAliasSettings();
|
||||||
Map<String, String> aliases = aliasSettings.getAliases();
|
Map<String, String> aliases = aliasSettings.getAliases();
|
||||||
|
|
||||||
@ -138,16 +129,16 @@ public class WorldPie {
|
|||||||
|
|
||||||
String alias = aliases.get(worldName);
|
String alias = aliases.get(worldName);
|
||||||
|
|
||||||
GMTimes aliasGMtimes = gmTimesPerAlias.getOrDefault(alias, new GMTimes());
|
GMTimes aliasGMTimes = gmTimesPerAlias.getOrDefault(alias, new GMTimes());
|
||||||
for (String gm : gms) {
|
for (String gm : gms) {
|
||||||
aliasGMtimes.addTime(gm, gmTimes.getTime(gm));
|
aliasGMTimes.addTime(gm, gmTimes.getTime(gm));
|
||||||
}
|
}
|
||||||
gmTimesPerAlias.put(alias, aliasGMtimes);
|
gmTimesPerAlias.put(alias, aliasGMTimes);
|
||||||
}
|
}
|
||||||
return gmTimesPerAlias;
|
return gmTimesPerAlias;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void appendGMTimesForWorld(StringBuilder drilldownBuilder, Map.Entry<String, GMTimes> world) {
|
private void appendGMTimesForWorld(StringBuilder drilldownBuilder, Map.Entry<String, GMTimes> world) {
|
||||||
Map<String, Long> gmTimes = world.getValue().getTimes();
|
Map<String, Long> gmTimes = world.getValue().getTimes();
|
||||||
int smallSize = gmTimes.size();
|
int smallSize = gmTimes.size();
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
@ -68,7 +68,7 @@ public class ServerAccordionCreator {
|
|||||||
String worldId = "worldPieServer" + sanitizedServerName;
|
String worldId = "worldPieServer" + sanitizedServerName;
|
||||||
AnalysisUtils.addMissingWorlds(worldTimes);
|
AnalysisUtils.addMissingWorlds(worldTimes);
|
||||||
|
|
||||||
String[] worldData = WorldPie.createSeries(worldTimes);
|
WorldPie worldPie = new WorldPie(worldTimes);
|
||||||
|
|
||||||
// Accordion panel header
|
// Accordion panel header
|
||||||
html.append("<div class=\"panel panel-col-").append(Theme.getValue(ThemeVal.PARSED_SERVER_ACCORDION)).append("\">")
|
html.append("<div class=\"panel panel-col-").append(Theme.getValue(ThemeVal.PARSED_SERVER_ACCORDION)).append("\">")
|
||||||
@ -104,8 +104,8 @@ public class ServerAccordionCreator {
|
|||||||
.append("<div id=\"").append(worldId).append("\" class=\"dashboard-donut-chart\"></div>")
|
.append("<div id=\"").append(worldId).append("\" class=\"dashboard-donut-chart\"></div>")
|
||||||
// World Pie data script
|
// World Pie data script
|
||||||
.append("<script>")
|
.append("<script>")
|
||||||
.append("var ").append(worldId).append("series = {name:'World Playtime'," +/*colors: worldPieColors,*/"colorByPoint:true,data:").append(worldData[0]).append("};")
|
.append("var ").append(worldId).append("series = {name:'World Playtime',colorByPoint:true,data:").append(worldPie.toHighChartsSeries()).append("};")
|
||||||
.append("var ").append(worldId).append("gmseries = ").append(worldData[1]).append(";")
|
.append("var ").append(worldId).append("gmseries = ").append(worldPie.toHighChartsDrilldown()).append(";")
|
||||||
.append("</script>")
|
.append("</script>")
|
||||||
.append("</div>") // Right col-6
|
.append("</div>") // Right col-6
|
||||||
.append("</div>") // Closes row clearfix
|
.append("</div>") // Closes row clearfix
|
||||||
|
@ -87,7 +87,7 @@ public class SessionTabStructureCreator {
|
|||||||
WorldTimes worldTimes = session.getWorldTimes();
|
WorldTimes worldTimes = session.getWorldTimes();
|
||||||
AnalysisUtils.addMissingWorlds(worldTimes);
|
AnalysisUtils.addMissingWorlds(worldTimes);
|
||||||
|
|
||||||
String[] worldData = WorldPie.createSeries(worldTimes);
|
WorldPie worldPie = new WorldPie(worldTimes);
|
||||||
|
|
||||||
String killTable = KillsTableCreator.createTable(session.getPlayerKills());
|
String killTable = KillsTableCreator.createTable(session.getPlayerKills());
|
||||||
|
|
||||||
@ -131,8 +131,8 @@ public class SessionTabStructureCreator {
|
|||||||
.append("<div id=\"").append(worldId).append("\" class=\"dashboard-donut-chart\"></div>")
|
.append("<div id=\"").append(worldId).append("\" class=\"dashboard-donut-chart\"></div>")
|
||||||
// World Pie data script
|
// World Pie data script
|
||||||
.append("<script>")
|
.append("<script>")
|
||||||
.append("var ").append(worldId).append("series = {name:'World Playtime'," +/*colors: worldPieColors,*/"colorByPoint:true,data:").append(worldData[0]).append("};")
|
.append("var ").append(worldId).append("series = {name:'World Playtime',colorByPoint:true,data:").append(worldPie.toHighChartsSeries()).append("};")
|
||||||
.append("var ").append(worldId).append("gmseries = ").append(worldData[1]).append(";")
|
.append("var ").append(worldId).append("gmseries = ").append(worldPie.toHighChartsDrilldown()).append(";")
|
||||||
.append("</script>")
|
.append("</script>")
|
||||||
.append("</div>") // Right col-6
|
.append("</div>") // Right col-6
|
||||||
.append("</div>") // Closes row clearfix
|
.append("</div>") // Closes row clearfix
|
||||||
|
@ -8,12 +8,10 @@ import com.djrapitops.plan.data.container.Session;
|
|||||||
import com.djrapitops.plan.data.container.TPS;
|
import com.djrapitops.plan.data.container.TPS;
|
||||||
import com.djrapitops.plan.data.time.WorldTimes;
|
import com.djrapitops.plan.data.time.WorldTimes;
|
||||||
import com.djrapitops.plan.utilities.analysis.Point;
|
import com.djrapitops.plan.utilities.analysis.Point;
|
||||||
import com.djrapitops.plan.utilities.html.graphs.PunchCardGraph;
|
|
||||||
import com.djrapitops.plan.utilities.html.graphs.line.*;
|
import com.djrapitops.plan.utilities.html.graphs.line.*;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
@ -21,9 +19,10 @@ import org.powermock.modules.junit4.PowerMockRunner;
|
|||||||
import test.utilities.RandomData;
|
import test.utilities.RandomData;
|
||||||
import test.utilities.TestInit;
|
import test.utilities.TestInit;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import static junit.framework.TestCase.assertEquals;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fuzzlemann
|
* @author Fuzzlemann
|
||||||
@ -52,69 +51,20 @@ public class GraphTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGraphCreators() {
|
@Ignore("Test should use Stack instead")
|
||||||
String expected = "[[0,0.0],[1,1.0],[2,2.0],[3,3.0],[4,4.0],[5,5.0],[6,6.0],[7,7.0],[8,8.0],[9,9.0]]";
|
public void testLineGraphsForBracketErrors() {
|
||||||
assertEquals(expected, CPUGraph.createSeries(tpsList));
|
AbstractLineGraph[] graphs = new AbstractLineGraph[]{
|
||||||
assertEquals(expected, PlayerActivityGraph.createSeries(tpsList));
|
new CPUGraph(tpsList),
|
||||||
// TODO Fix TimeZone Dependency of this test
|
new OnlineActivityGraph(tpsList),
|
||||||
// assertEquals("[{x:3600000, y:3, z:14, marker: { radius:14}},]", PunchCardGraph.createSeries(sessionList));
|
new RamGraph(tpsList),
|
||||||
|
new TPSGraph(tpsList),
|
||||||
assertEquals(expected, RamGraph.createSeries(tpsList));
|
new EntityGraph(tpsList),
|
||||||
assertEquals(expected, TPSGraph.createSeries(tpsList));
|
new ChunkGraph(tpsList)
|
||||||
assertEquals(expected, WorldLoadGraph.createSeriesChunks(tpsList));
|
|
||||||
assertEquals(expected, WorldLoadGraph.createSeriesEntities(tpsList));
|
|
||||||
// assertEquals("[{'code':'1','value':1},{'code':'2','value':2},{'code':'3','value':3},{'code':'4','value':4},{'code':'5','value':5},{'code':'6','value':6},{'code':'7','value':7},{'code':'8','value':8},{'code':'9','value':9}]", WorldMap.createSeries(geoList));
|
|
||||||
// TODO fix config mock dependency
|
|
||||||
// assertEquals("[[{name:'WORLD',y:0,drilldown: 'WORLD'}], [{name:'WORLD', id:'WORLD',colors: gmPieColors,data: [['SURVIVAL',0],['SPECTATOR',0],['CREATIVE',0],['ADVENTURE',0]]}]]",
|
|
||||||
// Arrays.toString(WorldPie.createSeries(worldTimes)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGraphCreatorsForBracketMistakes() {
|
|
||||||
String[] series = new String[]{
|
|
||||||
CPUGraph.createSeries(tpsList),
|
|
||||||
PlayerActivityGraph.createSeries(tpsList),
|
|
||||||
PunchCardGraph.createSeries(sessionList),
|
|
||||||
RamGraph.createSeries(tpsList),
|
|
||||||
TPSGraph.createSeries(tpsList),
|
|
||||||
WorldLoadGraph.createSeriesChunks(tpsList),
|
|
||||||
WorldLoadGraph.createSeriesEntities(tpsList),
|
|
||||||
// WorldMap.createSeries(geoList),
|
|
||||||
// TODO fix config mock dependency
|
|
||||||
// Arrays.toString(WorldPie.createSeries(worldTimes))
|
|
||||||
};
|
};
|
||||||
for (String test : series) {
|
|
||||||
int opened = StringUtils.countMatches(test, "{");
|
|
||||||
int closed = StringUtils.countMatches(test, "}");
|
|
||||||
Assert.assertEquals(opened, closed);
|
|
||||||
opened = StringUtils.countMatches(test, "[");
|
|
||||||
closed = StringUtils.countMatches(test, "]");
|
|
||||||
Assert.assertEquals(opened, closed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
for (AbstractLineGraph graph : graphs) {
|
||||||
public void testSeriesCreator() {
|
String series = graph.toHighChartsSeries();
|
||||||
String result = StringUtils.removeAll(LineSeries.createSeries(points, false, false), "[\\[\\]]");
|
// TODO Use Stack instead.
|
||||||
String[] splittedResult = result.split(",");
|
|
||||||
|
|
||||||
Map<String, String> expected = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
for (int i = 0; i < splittedResult.length; i++) {
|
|
||||||
expected.put(splittedResult[i++], splittedResult[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int i2 = 0;
|
|
||||||
for (Map.Entry<String, String> entry : expected.entrySet()) {
|
|
||||||
String expectedX = entry.getKey();
|
|
||||||
String expectedY = entry.getValue();
|
|
||||||
|
|
||||||
Point point = points.get(i2);
|
|
||||||
|
|
||||||
assertEquals("Given X does not match expected X", expectedX, String.valueOf((long) point.getX()));
|
|
||||||
assertEquals("Given Y does not match expected Y", expectedY, String.valueOf(point.getY()));
|
|
||||||
|
|
||||||
i2++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user