Removed Charts4j, added Chart.js

Removed Charts4j from the plugin, and moved to Chart.js javascript graph
rendering library - this almost halved the jar size, and analysis might
have gotten a tiny performance boost (Graph rendering delegated to
browsers).
- The new graphs are more accurate, and you can hover over the graphs to
view more in-depth detail about the data.
- This update allows possible multiple lines in one graph in future
updates.
Updated Phrase & Html to include every message that was not yet
available. Updated locale files will be uploaded to github As soon as
possible.
Before they are uploaded using the config locale setting will
malfunction.
This commit is contained in:
Rsl1122 2017-02-24 21:23:39 +02:00
parent de1a4570b1
commit dc05286f19
14 changed files with 329 additions and 404 deletions

View File

@ -56,12 +56,6 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- --> <!-- -->
<dependency>
<groupId>com.googlecode.charts4j</groupId>
<artifactId>charts4j</artifactId>
<version>1.3</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
<defaultGoal>clean package install</defaultGoal> <defaultGoal>clean package install</defaultGoal>

View File

@ -44,16 +44,6 @@ public enum Phrase {
COLOR_MAIN(ChatColor.getByChar(getPlugin(Plan.class).getConfig().getString("Customization.Colors.Commands.Main").charAt(1))), COLOR_MAIN(ChatColor.getByChar(getPlugin(Plan.class).getConfig().getString("Customization.Colors.Commands.Main").charAt(1))),
COLOR_SEC(ChatColor.getByChar(getPlugin(Plan.class).getConfig().getString("Customization.Colors.Commands.Secondary").charAt(1))), COLOR_SEC(ChatColor.getByChar(getPlugin(Plan.class).getConfig().getString("Customization.Colors.Commands.Secondary").charAt(1))),
COLOR_TER(ChatColor.getByChar(getPlugin(Plan.class).getConfig().getString("Customization.Colors.Commands.Highlight").charAt(1))), COLOR_TER(ChatColor.getByChar(getPlugin(Plan.class).getConfig().getString("Customization.Colors.Commands.Highlight").charAt(1))),
HCOLOR_ACT_ONL(getPlugin(Plan.class).getConfig().getString("Customization.Colors.HTML.ActivityGraph.OnlinePlayers")),
HCOLOR_ACT_NEW(getPlugin(Plan.class).getConfig().getString("Customization.Colors.HTML.ActivityGraph.NewPlayers")),
HCOLOR_GMP_0(getPlugin(Plan.class).getConfig().getString("Customization.Colors.HTML.GamemodePie.Survival")),
HCOLOR_GMP_1(getPlugin(Plan.class).getConfig().getString("Customization.Colors.HTML.GamemodePie.Creative")),
HCOLOR_GMP_2(getPlugin(Plan.class).getConfig().getString("Customization.Colors.HTML.GamemodePie.Adventure")),
HCOLOR_GMP_3(getPlugin(Plan.class).getConfig().getString("Customization.Colors.HTML.GamemodePie.Spectator")),
HCOLOR_ACTP_ACT(getPlugin(Plan.class).getConfig().getString("Customization.Colors.HTML.ActivityPie.Active")),
HCOLOR_ACTP_BAN(getPlugin(Plan.class).getConfig().getString("Customization.Colors.HTML.ActivityPie.Banned")),
HCOLOR_ACTP_INA(getPlugin(Plan.class).getConfig().getString("Customization.Colors.HTML.ActivityPie.Inactive")),
HCOLOR_ACTP_JON(getPlugin(Plan.class).getConfig().getString("Customization.Colors.HTML.ActivityPie.JoinedOnce")),
// //
ARROWS_RIGHT("»"), ARROWS_RIGHT("»"),
BALL(""), BALL(""),

View File

@ -30,7 +30,18 @@ public enum Settings {
DEM_MALE("Customization.DemographicsTriggers.Male"), DEM_MALE("Customization.DemographicsTriggers.Male"),
DEM_IGNORE("Customization.DemographicsTriggers.IgnoreWhen"), DEM_IGNORE("Customization.DemographicsTriggers.IgnoreWhen"),
LOCALE("Settings.Locale"), LOCALE("Settings.Locale"),
SECURITY_CODE("Settings.WebServer.Security.AddressSecurityCode"); SECURITY_CODE("Settings.WebServer.Security.AddressSecurityCode"),
//
HCOLOR_ACT_ONL("Customization.Colors.HTML.ActivityGraph.OnlinePlayers"),
HCOLOR_ACT_ONL_FILL("Customization.Colors.HTML.ActivityGraph.OnlinePlayersFill"),
HCOLOR_ACTP_ACT("Customization.Colors.HTML.ActivityPie.Active"),
HCOLOR_ACTP_BAN("Customization.Colors.HTML.ActivityPie.Banned"),
HCOLOR_ACTP_INA("Customization.Colors.HTML.ActivityPie.Inactive"),
HCOLOR_ACTP_JON("Customization.Colors.HTML.ActivityPie.JoinedOnce"),
HCOLOR_GMP_0("Customization.Colors.HTML.GamemodePie.Survival"),
HCOLOR_GMP_1("Customization.Colors.HTML.GamemodePie.Creative"),
HCOLOR_GMP_2("Customization.Colors.HTML.GamemodePie.Adventure"),
HCOLOR_GMP_3("Customization.Colors.HTML.GamemodePie.Spectator");
private final String configPath; private final String configPath;

View File

@ -13,15 +13,11 @@ public class AnalysisData {
private long averagePlayTime; private long averagePlayTime;
private long totalPlayTime; private long totalPlayTime;
private double averageAge; private double averageAge;
private String gmTimesChartImgHtml;
private String playersChartImgHtmlMonth;
private String playersChartImgHtmlWeek;
private String playersChartImgHtmlDay;
private String activityChartImgHtml;
private String top50CommandsListHtml; private String top50CommandsListHtml;
private String top20ActivePlayers; private String top20ActivePlayers;
private String recentPlayers; private String recentPlayers;
private String sortablePlayersTable; private String sortablePlayersTable;
private String[] playersDataArray;
private int newPlayersMonth; private int newPlayersMonth;
private int newPlayersWeek; private int newPlayersWeek;
@ -53,14 +49,10 @@ public class AnalysisData {
*/ */
public AnalysisData() { public AnalysisData() {
sortablePlayersTable = Html.ERROR_NOT_SET+""; sortablePlayersTable = Html.ERROR_NOT_SET+"";
gmTimesChartImgHtml = Html.ERROR_NOT_SET+"";
playersChartImgHtmlMonth = Html.ERROR_NOT_SET+"";
playersChartImgHtmlWeek = Html.ERROR_NOT_SET+"";
playersChartImgHtmlDay = Html.ERROR_NOT_SET+"";
activityChartImgHtml = Html.ERROR_NOT_SET+"";
top50CommandsListHtml = Html.ERROR_NOT_SET+""; top50CommandsListHtml = Html.ERROR_NOT_SET+"";
top20ActivePlayers = Html.ERROR_NOT_SET+""; top20ActivePlayers = Html.ERROR_NOT_SET+"";
recentPlayers = Html.ERROR_NOT_SET+""; recentPlayers = Html.ERROR_NOT_SET+"";
playersDataArray = new String[]{"[0]","[\"No data\"]","[0]","[\"No data\"]","[0]","[\"No data\"]"};
} }
// Getters and setters v---------------------------------v // Getters and setters v---------------------------------v
@ -85,49 +77,7 @@ public class AnalysisData {
public void setJoinleaver(int joinleaver) { public void setJoinleaver(int joinleaver) {
this.joinleaver = joinleaver; this.joinleaver = joinleaver;
} }
/**
* @return HTML String of the Month Activity graph
*/
public String getPlayersChartImgHtmlMonth() {
return playersChartImgHtmlMonth;
}
/**
* @param playersChartImgHtmlMonth HTML String of the Month Activity graph
*/
public void setPlayersChartImgHtmlMonth(String playersChartImgHtmlMonth) {
this.playersChartImgHtmlMonth = playersChartImgHtmlMonth;
}
/**
* @return HTML String of the Week Activity graph
*/
public String getPlayersChartImgHtmlWeek() {
return playersChartImgHtmlWeek;
}
/**
* @param playersChartImgHtmlWeek HTML String of the Week Activity graph
*/
public void setPlayersChartImgHtmlWeek(String playersChartImgHtmlWeek) {
this.playersChartImgHtmlWeek = playersChartImgHtmlWeek;
}
/**
* @return HTML String of the Day Activity graph
*/
public String getPlayersChartImgHtmlDay() {
return playersChartImgHtmlDay;
}
/**
* @param playersChartImgHtmlDay HTML String of the Day Activity graph
*/
public void setPlayersChartImgHtmlDay(String playersChartImgHtmlDay) {
this.playersChartImgHtmlDay = playersChartImgHtmlDay;
}
/** /**
* @return HTML String of the Top50CommandsList * @return HTML String of the Top50CommandsList
*/ */
@ -311,20 +261,6 @@ public class AnalysisData {
return averageAge; return averageAge;
} }
/**
* @return HTML String of the GMTimes Piechart
*/
public String getGmTimesChartImgHtml() {
return gmTimesChartImgHtml;
}
/**
* @return HTML String of the Activity Piechart
*/
public String getActivityChartImgHtml() {
return activityChartImgHtml;
}
/** /**
* @return How many times players have joined. * @return How many times players have joined.
*/ */
@ -360,20 +296,6 @@ public class AnalysisData {
this.averageAge = averageAge; this.averageAge = averageAge;
} }
/**
* @param gmTimesChartImgHtml HTML String of the GMTimes Piechart
*/
public void setGmTimesChartImgHtml(String gmTimesChartImgHtml) {
this.gmTimesChartImgHtml = gmTimesChartImgHtml;
}
/**
* @param activityChartImgHtml HTML String of the Activity Piechart
*/
public void setActivityChartImgHtml(String activityChartImgHtml) {
this.activityChartImgHtml = activityChartImgHtml;
}
/** /**
* @param totalLoginTimes How many times playes have logged in * @param totalLoginTimes How many times playes have logged in
*/ */
@ -451,4 +373,12 @@ public class AnalysisData {
public void setTotaldeaths(long totaldeaths) { public void setTotaldeaths(long totaldeaths) {
this.totaldeaths = totaldeaths; this.totaldeaths = totaldeaths;
} }
public String[] getPlayersDataArray() {
return playersDataArray;
}
public void setPlayersDataArray(String[] playersDataArray) {
this.playersDataArray = playersDataArray;
}
} }

View File

@ -1,55 +0,0 @@
package main.java.com.djrapitops.plan.ui.graphs;
import com.googlecode.charts4j.Color;
import com.googlecode.charts4j.GCharts;
import com.googlecode.charts4j.PieChart;
import com.googlecode.charts4j.Slice;
import main.java.com.djrapitops.plan.Phrase;
import main.java.com.djrapitops.plan.ui.Html;
/**
*
* @author Rsl1122
*/
public class ActivityPieChartCreator {
/**
* Creates a image link to Activity Chart.
*
* @param totalBanned Number of Banned Players
* @param active Number of Active Players
* @param inactive Number of Inactive Players
* @param joinleaver Number of players who have joined only once
* @return Url to Image link.
*/
public static String createChart(int totalBanned, int active, int inactive, int joinleaver) {
int total = totalBanned + active + inactive + joinleaver;
int banPerc = (int) ((totalBanned * 1.0 / total) * 100);
int inacPerc = (int) ((inactive * 1.0 / total) * 100);
int actPerc = (int) ((active * 1.0 / total) * 100);
int joinlPerc = (int) ((joinleaver * 1.0 / total) * 100);
while (banPerc + inacPerc + actPerc + joinlPerc < 100) {
actPerc++;
}
while (banPerc + inacPerc + actPerc + joinlPerc > 100) {
actPerc--;
}
String labelBanned = Html.GRAPH_BANNED.parse();
String labelUnknown = Html.GRAPH_UNKNOWN.parse();
String labelInactive = Html.GRAPH_INACTIVE.parse();
String labelActive = Html.GRAPH_ACTIVE.parse();
Slice bannedSlice = Slice.newSlice((int) (banPerc), Color.newColor(Phrase.HCOLOR_ACTP_BAN + ""), labelBanned, labelBanned);
Slice joinLeaverSlice = Slice.newSlice((int) (joinlPerc), Color.newColor(Phrase.HCOLOR_ACTP_JON + ""), labelUnknown, labelUnknown);
Slice inactiveSlice = Slice.newSlice((int) (inacPerc), Color.newColor(Phrase.HCOLOR_ACTP_INA + ""), labelInactive, labelInactive);
Slice activeSlice = Slice.newSlice((int) (actPerc), Color.newColor(Phrase.HCOLOR_ACTP_ACT + ""), labelActive, labelActive);
PieChart refChart = GCharts.newPieChart(activeSlice, bannedSlice, inactiveSlice, joinLeaverSlice);
refChart.setSize(400, 150);
refChart.setThreeD(true);
String refURL = refChart.toURLString();
return refURL;
}
}

View File

@ -1,86 +0,0 @@
package main.java.com.djrapitops.plan.ui.graphs;
import com.googlecode.charts4j.Color;
import com.googlecode.charts4j.GCharts;
import com.googlecode.charts4j.PieChart;
import com.googlecode.charts4j.Slice;
import java.util.HashMap;
import main.java.com.djrapitops.plan.Phrase;
import org.bukkit.GameMode;
/**
*
* @author Rsl1122
*/
public class GMTimesPieChartCreator {
/**
* Creates a link to New image of the Gamemode usage chart without total.
*
* Calculated total is not required.
*
* @param gmTimes Map with all 4 Gamemodes and responding times spent in
* them
* @return Url of charts4j image link.
*/
public static String createChart(HashMap<GameMode, Long> gmTimes) {
Long gm3;
try {
gm3 = gmTimes.get(GameMode.SPECTATOR);
if (gm3 == null) {
gm3 = (long) 0;
}
} catch (NoSuchFieldError e) {
gm3 = (long) 0;
}
long total = gmTimes.get(GameMode.SURVIVAL) + gmTimes.get(GameMode.CREATIVE)
+ gmTimes.get(GameMode.ADVENTURE) + gm3;
return createChart(gmTimes, total);
}
/**
* Creates a link to New image of the Gamemode usage chart.
*
* @param gmTimes Map with all 4 Gamemodes and responding times spent in
* them
* @param total Time spent in all 4 gamemodes.
* @return Url of charts4j image link.
*/
public static String createChart(HashMap<GameMode, Long> gmTimes, long total) {
long gmZero = gmTimes.get(GameMode.SURVIVAL);
long gmOne = gmTimes.get(GameMode.CREATIVE);
long gmTwo = gmTimes.get(GameMode.ADVENTURE);
Long gmThree;
try {
gmThree = gmTimes.get(GameMode.SPECTATOR);
if (gmThree == null) {
gmThree = (long) 0;
}
} catch (NoSuchFieldError e) {
gmThree = (long) 0;
}
int zero = (int) ((gmZero * 1.0 / total) * 100);
int one = (int) ((gmOne * 1.0 / total) * 100);
int two = (int) ((gmTwo * 1.0 / total) * 100);
int three = (int) ((gmThree * 1.0 / total) * 100);
while (zero + one + two + three < 100) {
one++;
}
while (zero + one + two + three > 100) {
one--;
}
Slice s1 = Slice.newSlice(zero, Color.newColor(Phrase.HCOLOR_GMP_0 + ""), "Survival", "Survival");
Slice s2 = Slice.newSlice(one, Color.newColor(Phrase.HCOLOR_GMP_1 + ""), "Creative", "Creative");
Slice s3 = Slice.newSlice(two, Color.newColor(Phrase.HCOLOR_GMP_2 + ""), "Adventure", "Adventure");
Slice s4 = Slice.newSlice(three, Color.newColor(Phrase.HCOLOR_GMP_3 + ""), "Spectator", "Spectator");
PieChart refChart = GCharts.newPieChart(s1, s2, s3, s4);
refChart.setSize(400, 150);
refChart.setThreeD(true);
String refURL = refChart.toURLString();
return refURL;
}
}

View File

@ -1,21 +1,11 @@
package main.java.com.djrapitops.plan.ui.graphs; package main.java.com.djrapitops.plan.ui.graphs;
import com.googlecode.charts4j.AxisLabels;
import com.googlecode.charts4j.AxisLabelsFactory;
import com.googlecode.charts4j.Color;
import com.googlecode.charts4j.Data;
import com.googlecode.charts4j.GCharts;
import com.googlecode.charts4j.LineChart;
import com.googlecode.charts4j.Plots;
import com.googlecode.charts4j.XYLine;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import main.java.com.djrapitops.plan.Phrase;
import main.java.com.djrapitops.plan.Plan; import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.SessionData; import main.java.com.djrapitops.plan.data.SessionData;
import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.utilities.FormatUtils; import main.java.com.djrapitops.plan.utilities.FormatUtils;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin; import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
@ -25,15 +15,9 @@ import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
*/ */
public class PlayerActivityGraphCreator { public class PlayerActivityGraphCreator {
/** public static String[] generateDataArray(List<SessionData> sessionData, long scale) {
* Creates a new url for a PlayerActivity graph. Plan plugin = getPlugin(Plan.class);
* int maxPlayers = plugin.getHandler().getMaxPlayers();
* @param sessionData SessionData of Players in scale.
* @param scale Long in ms, time the graph will be limited to.
* @return Url of charts4j image link.
*/
public static String createChart(List<SessionData> sessionData, long scale) {
long now = new Date().toInstant().getEpochSecond() * (long) 1000; long now = new Date().toInstant().getEpochSecond() * (long) 1000;
long nowMinusScale = now - scale; long nowMinusScale = now - scale;
CopyOnWriteArrayList<Long> sessionStarts = new CopyOnWriteArrayList<>(); CopyOnWriteArrayList<Long> sessionStarts = new CopyOnWriteArrayList<>();
@ -45,14 +29,8 @@ public class PlayerActivityGraphCreator {
sessionEnds.add(session.getSessionEnd()); sessionEnds.add(session.getSessionEnd());
sessionStarts.add(session.getSessionStart()); sessionStarts.add(session.getSessionStart());
}); });
List<Double> xListDate = new ArrayList<>(); List<Integer> playersOnline = new ArrayList<>();
List<Double> pYList = new ArrayList<>(); List<String> labels = new ArrayList<>();
List<String> xDateAxisLabels = new ArrayList<>();
List<Double> xDateAxisLabelsLocations = new ArrayList<>();
Plan plugin = getPlugin(Plan.class);
int maxPlayers = plugin.getHandler().getMaxPlayers();
int lastPValue = 0; int lastPValue = 0;
int lastSavedPValue = -1; int lastSavedPValue = -1;
@ -75,45 +53,17 @@ public class PlayerActivityGraphCreator {
.reduce(amount, Integer::sum); .reduce(amount, Integer::sum);
lastPValue -= amount; lastPValue -= amount;
} }
Double scaledDateValue = ((i - nowMinusScale) * 1.0 / scale) * 100;
Double scaledPlayerValue = (lastPValue * 1.0 / maxPlayers) * 100;
if (lastSavedPValue != lastPValue || i - lastSaveI > (scale / (long) 100)) { if (lastSavedPValue != lastPValue || i - lastSaveI > (scale / (long) 75)) {
lastSaveI = i; lastSaveI = i;
xListDate.add(scaledDateValue); labels.add("\""+FormatUtils.formatTimeStamp(i+"")+"\"");
pYList.add((lastSavedPValue * 1.0 / maxPlayers) * 100);
lastSavedPValue = lastPValue; lastSavedPValue = lastPValue;
xListDate.add(scaledDateValue); playersOnline.add(lastPValue);
pYList.add(scaledPlayerValue);
} }
} }
playersOnline.add(0);
// Date labels playersOnline.add(maxPlayers);
for (long j = 0; j <= 8; j++) { return new String[]{playersOnline.toString(), labels.toString()};
long scaleAddition = j * (scale / 8);
xDateAxisLabels.add(FormatUtils.formatTimeStamp("" + (nowMinusScale + scaleAddition)));
xDateAxisLabelsLocations.add((scaleAddition * 1.0 / scale) * 100);
}
// Player labels
List<String> yAxisLabels = new ArrayList<>();
for (int k = 0; k <= maxPlayers; k++) {
if (k % 5 == 0) {
yAxisLabels.add("" + k);
}
}
AxisLabels xAxisLabels = AxisLabelsFactory.newAxisLabels(xDateAxisLabels, xDateAxisLabelsLocations);
Data xData = Data.newData(xListDate);
Data pYData = Data.newData(pYList);
XYLine playerLine = Plots.newXYLine(xData, pYData, Color.newColor(Phrase.HCOLOR_ACT_ONL + ""), Html.GRAPH_ONLINE.parse());
LineChart chart = GCharts.newLineChart(playerLine);
chart.addXAxisLabels(xAxisLabels);
chart.addTopAxisLabels(AxisLabelsFactory.newAxisLabels(Html.GRAPH_PLAYERS.parse(), 1));
chart.addYAxisLabels(AxisLabelsFactory.newAxisLabels(yAxisLabels));
chart.addRightAxisLabels(AxisLabelsFactory.newAxisLabels(Html.GRAPH_DATE.parse(), 4));
chart.setSize(1000, 250);
return chart.toURLString();
} }
} }

View File

@ -16,10 +16,12 @@ import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.AnalysisCacheHandler; import main.java.com.djrapitops.plan.data.cache.AnalysisCacheHandler;
import main.java.com.djrapitops.plan.data.cache.InspectCacheHandler; import main.java.com.djrapitops.plan.data.cache.InspectCacheHandler;
import main.java.com.djrapitops.plan.ui.Html; import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.ui.graphs.PlayerActivityGraphCreator;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import static org.bukkit.Bukkit.getOfflinePlayer; import static org.bukkit.Bukkit.getOfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
/** /**
* *
@ -175,8 +177,6 @@ public class Analysis {
} }
private void createActivityVisalization(int totalBanned, int active, int inactive, int joinleaver, AnalysisData data) { private void createActivityVisalization(int totalBanned, int active, int inactive, int joinleaver, AnalysisData data) {
String activityPieChartHtml = AnalysisUtils.createActivityPieChart(totalBanned, active, inactive, joinleaver);
data.setActivityChartImgHtml(activityPieChartHtml);
data.setActive(active); data.setActive(active);
data.setInactive(inactive); data.setInactive(inactive);
data.setBanned(totalBanned); data.setBanned(totalBanned);
@ -208,8 +208,6 @@ public class Analysis {
totalGmTimes.put(GameMode.SPECTATOR, gmThree); totalGmTimes.put(GameMode.SPECTATOR, gmThree);
} catch (NoSuchFieldError e) { } catch (NoSuchFieldError e) {
} }
String serverGMChartHtml = AnalysisUtils.createGMPieChart(totalGmTimes, gmTotal);
data.setGmTimesChartImgHtml(serverGMChartHtml);
data.setGm0Perc((gmZero * 1.0 / gmTotal)); data.setGm0Perc((gmZero * 1.0 / gmTotal));
data.setGm1Perc((gmOne * 1.0 / gmTotal)); data.setGm1Perc((gmOne * 1.0 / gmTotal));
data.setGm2Perc((gmTwo * 1.0 / gmTotal)); data.setGm2Perc((gmTwo * 1.0 / gmTotal));
@ -218,18 +216,20 @@ public class Analysis {
private void createPlayerActivityGraphs(AnalysisData data, List<SessionData> sData, List<Long> registered) { private void createPlayerActivityGraphs(AnalysisData data, List<SessionData> sData, List<Long> registered) {
long now = new Date().toInstant().getEpochSecond() * (long) 1000; long now = new Date().toInstant().getEpochSecond() * (long) 1000;
long scaleMonth = (long) 2592000 * (long) 1000;
String[] urlAndNumber = AnalysisUtils.analyzeSessionData(sData, registered, scaleMonth, now);
data.setPlayersChartImgHtmlMonth(urlAndNumber[0]);
data.setNewPlayersMonth(Integer.parseInt(urlAndNumber[1]));
long scaleWeek = 604800 * 1000;
urlAndNumber = AnalysisUtils.analyzeSessionData(sData, registered, scaleWeek, now);
data.setPlayersChartImgHtmlWeek(urlAndNumber[0]);
data.setNewPlayersWeek(Integer.parseInt(urlAndNumber[1]));
long scaleDay = 86400 * 1000; long scaleDay = 86400 * 1000;
urlAndNumber = AnalysisUtils.analyzeSessionData(sData, registered, scaleDay, now); long scaleWeek = 604800 * 1000;
data.setPlayersChartImgHtmlDay(urlAndNumber[0]); long scaleMonth = (long) 2592000 * (long) 1000;
data.setNewPlayersDay(Integer.parseInt(urlAndNumber[1]));
data.setNewPlayersDay(AnalysisUtils.getNewPlayers(registered, scaleDay, now));
data.setNewPlayersWeek(AnalysisUtils.getNewPlayers(registered, scaleWeek, now));
data.setNewPlayersMonth(AnalysisUtils.getNewPlayers(registered, scaleMonth, now));
String[] dayArray = PlayerActivityGraphCreator.generateDataArray(sData, scaleDay);
String[] weekArray = PlayerActivityGraphCreator.generateDataArray(sData, scaleWeek);
String[] monthArray = PlayerActivityGraphCreator.generateDataArray(sData, scaleMonth);
data.setPlayersDataArray(new String[]{dayArray[0], dayArray[1], weekArray[0], weekArray[1], monthArray[0], monthArray[1]});
} }
}).runTaskAsynchronously(plugin); }).runTaskAsynchronously(plugin);
} }

View File

@ -10,8 +10,6 @@ import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.SessionData; import main.java.com.djrapitops.plan.data.SessionData;
import main.java.com.djrapitops.plan.data.UserData; import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.ui.Html; import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.ui.graphs.ActivityPieChartCreator;
import main.java.com.djrapitops.plan.ui.graphs.GMTimesPieChartCreator;
import main.java.com.djrapitops.plan.ui.graphs.PlayerActivityGraphCreator; import main.java.com.djrapitops.plan.ui.graphs.PlayerActivityGraphCreator;
import main.java.com.djrapitops.plan.ui.tables.SortableCommandUseTableCreator; import main.java.com.djrapitops.plan.ui.tables.SortableCommandUseTableCreator;
import main.java.com.djrapitops.plan.ui.tables.SortablePlayersTableCreator; import main.java.com.djrapitops.plan.ui.tables.SortablePlayersTableCreator;
@ -24,36 +22,6 @@ import org.bukkit.GameMode;
*/ */
public class AnalysisUtils { public class AnalysisUtils {
/**
* Creates a GMTimesPieChart image HTML.
*
* @param gmTimes HashMap of gamemodes and time in ms how long has been
* played in them.
* @return Html img tag with url.
*/
public static String createGMPieChart(HashMap<GameMode, Long> gmTimes) {
String url = GMTimesPieChartCreator.createChart(gmTimes);
return Html.IMG.parse(url);
}
/**
* Creates a GMTimesPieChart image HTML.
*
* @param gmTimes HashMap of gamemodes and time in ms how long has been
* played in them.
* @param total Total time played in all gamemodes
* @return Html img tag with url.
*/
public static String createGMPieChart(HashMap<GameMode, Long> gmTimes, long total) {
String url = GMTimesPieChartCreator.createChart(gmTimes, total);
return Html.IMG.parse(url);
}
static String createPlayerActivityGraph(List<SessionData> sessionData, long scale) {
String url = PlayerActivityGraphCreator.createChart(sessionData, scale);
return Html.IMG.parse(url);
}
public static boolean isActive(long lastPlayed, long playTime, int loginTimes) { public static boolean isActive(long lastPlayed, long playTime, int loginTimes) {
int timeToActive = Settings.ANALYSIS_MINUTES_FOR_ACTIVE.getNumber(); int timeToActive = Settings.ANALYSIS_MINUTES_FOR_ACTIVE.getNumber();
if (timeToActive < 0) { if (timeToActive < 0) {
@ -70,11 +38,6 @@ public class AnalysisUtils {
return false; return false;
} }
static String createActivityPieChart(int totalBanned, int active, int inactive, int joinleaver) {
String url = ActivityPieChartCreator.createChart(totalBanned, active, inactive, joinleaver);
return Html.IMG.parse(url);
}
static String createTableOutOfHashMap(HashMap<String, Integer> commandUse) { static String createTableOutOfHashMap(HashMap<String, Integer> commandUse) {
return SortableCommandUseTableCreator.createSortedCommandUseTable(commandUse); return SortableCommandUseTableCreator.createSortedCommandUseTable(commandUse);
} }
@ -103,22 +66,12 @@ public class AnalysisUtils {
return html; return html;
} }
static String[] analyzeSessionData(List<SessionData> sessionData, List<Long> registered, long scale, long now) { static int getNewPlayers(List<Long> registered, long scale, long now) {
String[] returnA = new String[2];
List<SessionData> inScale = new ArrayList<>();
sessionData.stream()
.filter((s) -> (s.getSessionStart() > now - scale))
.forEach((s) -> {
inScale.add(s);
});
returnA[0] = createPlayerActivityGraph(inScale, scale);
int newPlayers = 0; int newPlayers = 0;
// Filters out register dates before scale // Filters out register dates before scale
newPlayers = registered.stream() newPlayers = registered.stream()
.filter((reg) -> (reg > now - scale)) .filter((reg) -> (reg > now - scale))
.map((_item) -> 1).reduce(newPlayers, Integer::sum); .map((_item) -> 1).reduce(newPlayers, Integer::sum);
returnA[1] = "" + newPlayers; return newPlayers;
return returnA;
} }
} }

View File

@ -1,6 +1,7 @@
package main.java.com.djrapitops.plan.utilities; package main.java.com.djrapitops.plan.utilities;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.UUID; import java.util.UUID;
@ -28,8 +29,6 @@ public class PlaceholderUtils {
*/ */
public static HashMap<String, String> getAnalysisReplaceRules(AnalysisData data) { public static HashMap<String, String> getAnalysisReplaceRules(AnalysisData data) {
HashMap<String, String> replaceMap = new HashMap<>(); HashMap<String, String> replaceMap = new HashMap<>();
replaceMap.put("%activitypiechart%", data.getActivityChartImgHtml());
replaceMap.put("%gmpiechart%", data.getGmTimesChartImgHtml());
replaceMap.put("%gm0%", (int) (data.getGm0Perc() * 100) + "%"); replaceMap.put("%gm0%", (int) (data.getGm0Perc() * 100) + "%");
replaceMap.put("%gm1%", (int) (data.getGm1Perc() * 100) + "%"); replaceMap.put("%gm1%", (int) (data.getGm1Perc() * 100) + "%");
replaceMap.put("%gm2%", (int) (data.getGm2Perc() * 100) + "%"); replaceMap.put("%gm2%", (int) (data.getGm2Perc() * 100) + "%");
@ -39,9 +38,6 @@ public class PlaceholderUtils {
replaceMap.put("%inactive%", "" + data.getInactive()); replaceMap.put("%inactive%", "" + data.getInactive());
replaceMap.put("%joinleaver%", "" + data.getJoinleaver()); replaceMap.put("%joinleaver%", "" + data.getJoinleaver());
replaceMap.put("%activitytotal%", "" + data.getTotal()); replaceMap.put("%activitytotal%", "" + data.getTotal());
replaceMap.put("%playerchartmonth%", data.getPlayersChartImgHtmlMonth());
replaceMap.put("%playerchartweek%", data.getPlayersChartImgHtmlWeek());
replaceMap.put("%playerchartday%", data.getPlayersChartImgHtmlDay());
replaceMap.put("%npday%", data.getNewPlayersDay() + ""); replaceMap.put("%npday%", data.getNewPlayersDay() + "");
replaceMap.put("%npweek%", data.getNewPlayersWeek() + ""); replaceMap.put("%npweek%", data.getNewPlayersWeek() + "");
replaceMap.put("%npmonth%", data.getNewPlayersMonth() + ""); replaceMap.put("%npmonth%", data.getNewPlayersMonth() + "");
@ -61,6 +57,35 @@ public class PlaceholderUtils {
replaceMap.put("%version%", plugin.getDescription().getVersion()); replaceMap.put("%version%", plugin.getDescription().getVersion());
replaceMap.put("%planlite%", ""); replaceMap.put("%planlite%", "");
replaceMap.put("%sortabletable%", data.getSortablePlayersTable()); replaceMap.put("%sortabletable%", data.getSortablePlayersTable());
replaceMap.put("%dataday%", data.getPlayersDataArray()[0]);
replaceMap.put("%labelsday%", data.getPlayersDataArray()[1]);
replaceMap.put("%dataweek%", data.getPlayersDataArray()[2]);
replaceMap.put("%labelsweek%", data.getPlayersDataArray()[3]);
replaceMap.put("%datamonth%", data.getPlayersDataArray()[4]);
replaceMap.put("%labelsmonth%", data.getPlayersDataArray()[5]);
replaceMap.put("%playersgraphcolor%", Settings.HCOLOR_ACT_ONL + "");
replaceMap.put("%playersgraphfill%", Settings.HCOLOR_ACT_ONL_FILL + "");
String[] activityLabels = new String[]{
"\"" + Html.GRAPH_ACTIVE.parse() + "\"",
"\"" + Html.GRAPH_INACTIVE.parse() + "\"",
"\"" + Html.GRAPH_UNKNOWN.parse() + "\"",
"\"" + Html.GRAPH_BANNED.parse() + "\""
};
replaceMap.put("%labelsactivity%", Arrays.toString(activityLabels));
String[] activityData = new String[]{data.getActive() + "", data.getInactive() + "", data.getJoinleaver()+ "", data.getBanned() + ""};
replaceMap.put("%activitydata%", Arrays.toString(activityData));
replaceMap.put("%activitycolors%", "\"#" + Settings.HCOLOR_ACTP_ACT
+ "\",\"#" + Settings.HCOLOR_ACTP_INA + "\",\"#" + Settings.HCOLOR_ACTP_JON + "\",\"#" + Settings.HCOLOR_ACTP_BAN + "\"");
String[] gmData = new String[]{
(data.getGm0Perc() * 100) + "",
(data.getGm1Perc() * 100) + "",
(data.getGm2Perc() * 100) + "",
(data.getGm3Perc() * 100) + ""
};
replaceMap.put("%gmdata%", Arrays.toString(gmData));
replaceMap.put("%gmlabels%", "[\"Survival\", \"Creative\", \"Adventure\", \"Spectator\"]");
replaceMap.put("%gmcolors%", "\"#" + Settings.HCOLOR_GMP_0 + "\",\"#" + Settings.HCOLOR_GMP_1
+ "\",\"#" + Settings.HCOLOR_GMP_2 + "\",\"#" + Settings.HCOLOR_GMP_3 + "\"");
replaceMap.putAll(plugin.getHookHandler().getAdditionalAnalysisReplaceRules()); replaceMap.putAll(plugin.getHookHandler().getAdditionalAnalysisReplaceRules());
return replaceMap; return replaceMap;
} }
@ -86,10 +111,6 @@ public class PlaceholderUtils {
replaceMap.put("%age%", (age != -1) ? "" + age : Phrase.DEM_UNKNOWN + ""); replaceMap.put("%age%", (age != -1) ? "" + age : Phrase.DEM_UNKNOWN + "");
replaceMap.put("%gender%", "" + data.getDemData().getGender().name().toLowerCase()); replaceMap.put("%gender%", "" + data.getDemData().getGender().name().toLowerCase());
HashMap<GameMode, Long> gmTimes = data.getGmTimes(); HashMap<GameMode, Long> gmTimes = data.getGmTimes();
replaceMap.put("%gmpiechart%", AnalysisUtils.createGMPieChart(gmTimes));
long gmZero = gmTimes.get(GameMode.SURVIVAL);
long gmOne = gmTimes.get(GameMode.CREATIVE);
long gmTwo = gmTimes.get(GameMode.ADVENTURE);
long gmThree; long gmThree;
try { try {
Long gm3 = gmTimes.get(GameMode.SPECTATOR); Long gm3 = gmTimes.get(GameMode.SPECTATOR);
@ -100,11 +121,21 @@ public class PlaceholderUtils {
} catch (NoSuchFieldError e) { } catch (NoSuchFieldError e) {
gmThree = 0; gmThree = 0;
} }
long total = gmZero + gmOne + gmTwo + gmThree; long[] gmData = new long[]{
replaceMap.put("%gm0%", FormatUtils.formatTimeAmount("" + gmZero)); gmTimes.get(GameMode.SURVIVAL),
replaceMap.put("%gm1%", FormatUtils.formatTimeAmount("" + gmOne)); gmTimes.get(GameMode.CREATIVE),
replaceMap.put("%gm2%", FormatUtils.formatTimeAmount("" + gmTwo)); gmTimes.get(GameMode.ADVENTURE),
replaceMap.put("%gm3%", FormatUtils.formatTimeAmount("" + gmThree)); gmThree
};
long total = gmData[0] + gmData[1] + gmData[2] + gmData[3];
replaceMap.put("%gm0%", FormatUtils.formatTimeAmount("" + gmData[0]));
replaceMap.put("%gm1%", FormatUtils.formatTimeAmount("" + gmData[1]));
replaceMap.put("%gm2%", FormatUtils.formatTimeAmount("" + gmData[2]));
replaceMap.put("%gm3%", FormatUtils.formatTimeAmount("" + gmData[3]));
replaceMap.put("%gmdata%", Arrays.toString(gmData));
replaceMap.put("%gmlabels%", "[\"Survival\", \"Creative\", \"Adventure\", \"Spectator\"]");
replaceMap.put("%gmcolors%", "\"#" + Settings.HCOLOR_GMP_0 + "\",\"#" + Settings.HCOLOR_GMP_1
+ "\",\"#" + Settings.HCOLOR_GMP_2 + "\",\"#" + Settings.HCOLOR_GMP_3 + "\"");
replaceMap.put("%gmtotal%", FormatUtils.formatTimeAmount("" + total)); replaceMap.put("%gmtotal%", FormatUtils.formatTimeAmount("" + total));
replaceMap.put("%ips%", (showIPandUUID ? data.getIps().toString() : Html.HIDDEN.parse())); replaceMap.put("%ips%", (showIPandUUID ? data.getIps().toString() : Html.HIDDEN.parse()));
replaceMap.put("%nicknames%", FormatUtils.swapColorsToSpan(data.getNicknames().toString())); replaceMap.put("%nicknames%", FormatUtils.swapColorsToSpan(data.getNicknames().toString()));

View File

@ -5,9 +5,7 @@
<title>Plan | Server Analysis</title> <title>Plan | Server Analysis</title>
<meta name="description" content="Player Analysis window"> <meta name="description" content="Player Analysis window">
<meta name="author" content="Rsl1122"> <meta name="author" content="Rsl1122">
<link rel="icon" href="https://puu.sh/tK0KL/6aa2ba141b.ico" type="image/x-icon" /> <link rel="icon" href="https://puu.sh/tK0KL/6aa2ba141b.ico" type="image/x-icon" />
<!--<script src="http://puu.sh/ubCTc/7e611ffe42.js"></script>-->
<script src="http://www.kryogenix.org/code/browser/sorttable/sorttable.js"></script>
<style> <style>
* { * {
box-sizing: border-box; box-sizing: border-box;
@ -84,6 +82,7 @@
font-weight: bold; font-weight: bold;
cursor: default; cursor: default;
width: 100%; width: 100%;
overflow: hidden;
} }
table.sortable th:not(.sorttable_sorted):not(.sorttable_sorted_reverse):not(.sorttable_nosort):after { table.sortable th:not(.sorttable_sorted):not(.sorttable_sorted_reverse):not(.sorttable_nosort):after {
content: " \25B4\25BE" content: " \25B4\25BE"
@ -159,7 +158,7 @@
<div class="content"> <div class="content">
<div class="column" style="width: 60%;"> <div class="column" style="width: 60%;">
<h4>Player Activity | Last 24h - New Players: %npday%</h4> <h4>Player Activity | Last 24h - New Players: %npday%</h4>
%playerchartday% <canvas id="playerChartDay" width="1000" height="350" style="width: 95%;"></canvas>
<div class="buttons"> <div class="buttons">
<p><b>Most recent logins</b>: %recentlogins%</p> <p><b>Most recent logins</b>: %recentlogins%</p>
</div> </div>
@ -176,24 +175,23 @@
The average of known player ages is %avgage%. The average of known player ages is %avgage%.
%essentialswarps%</p> %essentialswarps%</p>
<h4>Gamemode Usage</h4> <h4>Gamemode Usage</h4>
%gmpiechart% <canvas id="gmPie" width="1000" height="600" style="width: 95%;"></canvas>
<p>Survival: %gm0% | Creative: %gm1% | Adventure: %gm2% | Spectator: %gm3%</p> <p>Survival: %gm0% | Creative: %gm1% | Adventure: %gm2% | Spectator: %gm3%</p>
</div> </div>
</div> </div>
<div class="content"> <div class="content">
<div class="column" style="width: 60%;"> <div class="column" style="width: 60%;">
<h4>Player Activity | Last 24h - New Players: %npday%</h4> <h4>Player Activity | Last 24h - New Players: %npday%</h4>
%playerchartday% <canvas id="playerChartDay2" width="1000" height="350" style="width: 95%;"></canvas>
<h4>Player Activity | Last 7 days - New Players: %npweek%</h4> <h4>Player Activity | Last 7 days - New Players: %npweek%</h4>
%playerchartweek% <canvas id="playerChartWeek" width="1000" height="350" style="width: 95%;"></canvas>
<h4>Player Activity | Last 30 days - New Players: %npmonth%</h4> <h4>Player Activity | Last 30 days - New Players: %npmonth%</h4>
%playerchartmonth% <canvas id="playerChartMonth" width="1000" height="350" style="width: 95%;"></canvas>
</div> </div>
<div class="column" style="width: 40%;"> <div class="column" style="width: 40%;">
<h4>Playerbase composition</h4> <h4>Playerbase composition - Total: %activitytotal%</h4>
%activitypiechart% <p>Active %active% | Inactive %inactive% | Banned %banned% | Joined once %joinleaver%</p>
<p>Active %active% | Inactive %inactive% | Banned %banned% | Joined once %joinleaver% <br/> <canvas id="activityPie" width="1000" height="600" style="width: 95%;"></canvas>
Total: %activitytotal%</p>
<div class="buttons"> <div class="buttons">
<p><b>Most recent logins</b>: %recentlogins%</p> <p><b>Most recent logins</b>: %recentlogins%</p>
</div> </div>
@ -233,15 +231,193 @@
</div> </div>
</div></div> </div></div>
</body> </body>
<script src="http://www.kryogenix.org/code/browser/sorttable/sorttable.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.bundle.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.js"></script>
<script> <script>
// just querying the DOM...like a boss! // Script for All charts using Chart.js
var ctxday = document.getElementById("playerChartDay");
var ctxday2 = document.getElementById("playerChartDay2");
var ctxweek = document.getElementById("playerChartWeek");
var ctxmonth = document.getElementById("playerChartMonth");
var ctxactivitypie = document.getElementById("activityPie");
var ctxgmpie = document.getElementById("gmPie");
var dataday = {
labels: %labelsday%,
datasets: [
{
label: "Players Online",
fill: true,
lineTension: 0.1,
backgroundColor: "#%playersgraphfill%",
borderColor: "#%playersgraphcolor%",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: "#%playersgraphcolor%",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "#%playersgraphcolor%",
pointHoverBorderColor: "#8fabc6",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
spanGaps: false,
data: %dataday%,
}]
}
var dataweek = {
labels: %labelsweek%,
datasets: [
{
label: "Players Online",
fill: true,
lineTension: 0.1,
backgroundColor: "#%playersgraphfill%",
borderColor: "#%playersgraphcolor%",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: "#%playersgraphcolor%",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "#%playersgraphcolor%",
pointHoverBorderColor: "#8fabc6",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
spanGaps: false,
data: %dataweek%,
}]
}
var datamonth = {
labels: %labelsmonth%,
datasets: [
{
label: "Players Online",
fill: true,
lineTension: 0.1,
backgroundColor: "#%playersgraphfill%",
borderColor: "#%playersgraphcolor%",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderColor: "#%playersgraphcolor%",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "#%playersgraphcolor%",
pointHoverBorderColor: "#8fabc6",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
spanGaps: false,
data: %datamonth%,
}]
}
var dataActivityPie = {
labels: %labelsactivity%,
datasets: [
{
data: %activitydata%,
backgroundColor: [%activitycolors%],
hoverBackgroundColor: [%activitycolors%]
}
]
}
var ActivityPie = new Chart(ctxactivitypie, {
type: 'doughnut',
data: dataActivityPie,
options: {
legend: {
position: 'right',
labels: {
padding: 7
}
}
}
});
var dataGmPie = {
labels: %gmlabels%,
datasets: [
{
data: %gmdata%,
backgroundColor: [%gmcolors%],
hoverBackgroundColor: [%gmcolors%]
}
]
}
var GMPie = new Chart(ctxgmpie, {
type: 'doughnut',
data: dataGmPie,
options: {
legend: {
position: 'right',
labels: {
padding: 7
}
}
}
});
var playersChartDay = new Chart(ctxday, {
type: 'line',
data: dataday,
options: {
scales: {
xAxes: [{
display: false
}]
}
}
});
var playersChartDay2 = new Chart(ctxday2, {
type: 'line',
data: dataday,
options: {
scales: {
xAxes: [{
display: false
}]
}
}
});
var playersChartWeek = new Chart(ctxweek, {
type: 'line',
data: dataweek,
options: {
scales: {
xAxes: [{
display: false
}]
}
}
});
var playersChartMonth = new Chart(ctxmonth, {
type: 'line',
data: datamonth,
options: {
scales: {
xAxes: [{
display: false
}]
}
}
});
</script>
<script>
// Script for the page navigation buttons
var links = document.querySelectorAll(".itemLinks"); var links = document.querySelectorAll(".itemLinks");
var wrapper = document.querySelector("#wrapper"); var wrapper = document.querySelector("#wrapper");
// the activeLink provides a pointer to the currently displayed item // the activeLink provides a pointer to the currently displayed item
var activeLink = 0; var activeLink = 0;
// setup the event listeners // setup the event listeners
for (var i = 0; i < links.length; i++) { for (var i = 0; i < links.length; i++) {
var link = links[i]; var link = links[i];
link.addEventListener('click', setClickedItem, false); link.addEventListener('click', setClickedItem, false);
@ -250,7 +426,7 @@
link.itemID = i; link.itemID = i;
} }
// set first item as active // set first item as active
links[activeLink].classList.add("active"); links[activeLink].classList.add("active");
function setClickedItem(e) { function setClickedItem(e) {
@ -267,8 +443,8 @@
links[i].classList.remove("active"); links[i].classList.remove("active");
} }
} }
// Handle changing the slider position as well as ensure // Handle changing the slider position as well as ensure
// the correct link is highlighted as being active // the correct link is highlighted as being active
function changePosition(link) { function changePosition(link) {
var position = link.getAttribute("data-pos"); var position = link.getAttribute("data-pos");

View File

@ -33,6 +33,7 @@ Customization:
HTML: HTML:
ActivityGraph: ActivityGraph:
OnlinePlayers: '1E90FF' OnlinePlayers: '1E90FF'
OnlinePlayersFill: '75BBFF'
NewPlayers: '228B22' NewPlayers: '228B22'
GamemodePie: GamemodePie:
Survival: '951800' Survival: '951800'

View File

@ -6,7 +6,6 @@
<meta name="description" content="Player inspect window"> <meta name="description" content="Player inspect window">
<meta name="author" content="Rsl1122"> <meta name="author" content="Rsl1122">
<link rel="icon" href="https://puu.sh/tK0KL/6aa2ba141b.ico" type="image/x-icon" /> <link rel="icon" href="https://puu.sh/tK0KL/6aa2ba141b.ico" type="image/x-icon" />
<script src="http://www.kryogenix.org/code/browser/sorttable/sorttable.js"></script>
<style> <style>
* { * {
box-sizing: border-box; box-sizing: border-box;
@ -43,7 +42,10 @@
display: table; display: table;
} }
.info { .info {
width: 50%; width: 60%;
}
.graphs {
width: 40%;
} }
.table { .table {
border-collapse: collapse; border-collapse: collapse;
@ -139,13 +141,41 @@
%sessionstable% %sessionstable%
</div> </div>
<div class="column info"> <div class="column graphs">
<h4>Gamemode Usage</h4> <h4>Gamemode Usage - Total: %gmtotal%</h4>
%gmpiechart% <p>Survival: %gm0% | Creative: %gm1% | Adventure: %gm2% | Spectator: %gm3%</p>
<p>Survival: %gm0% | Creative: %gm1% | Adventure: %gm2% | Spectator: %gm3% <br/>Total: %gmtotal%</p> <canvas id="gmPie" width="1000" height="600" style="width: 95%;"></canvas>
</div> </div>
</div> </div>
<script src="http://www.kryogenix.org/code/browser/sorttable/sorttable.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.bundle.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.js"></script>
<script>
// Script for All charts using Chart.js
var ctxgmpie = document.getElementById("gmPie");
var dataGmPie = {
labels: %gmlabels%,
datasets: [
{
data: %gmdata%,
backgroundColor: [%gmcolors%],
hoverBackgroundColor: [%gmcolors%]
}
]
}
var GMPie = new Chart(ctxgmpie, {
type: 'doughnut',
data: dataGmPie,
options: {
legend: {
position: 'right',
labels: {
padding: 7
}
}
}
});
</script>
</body> </body>
</html> </html>

View File

@ -1,7 +1,7 @@
name: Plan name: Plan
author: Rsl1122 author: Rsl1122
main: main.java.com.djrapitops.plan.Plan main: main.java.com.djrapitops.plan.Plan
version: 2.6.3 version: 2.7.0
softdepend: softdepend:
- OnTime - OnTime