JSON end-point for Graphs

This commit is contained in:
Rsl1122 2019-06-09 18:20:40 +03:00
parent 252136fabf
commit 6ecad861da
9 changed files with 401 additions and 97 deletions

View File

@ -144,19 +144,22 @@ public class SessionQueries {
* @return Map: Player UUID - List of sessions on the server.
*/
public static Query<Map<UUID, List<Session>>> fetchSessionsOfServer(UUID serverUUID) {
return db -> SessionsMutator.sortByPlayers(db.query(fetchSessionsOfServerFlat(serverUUID)));
}
public static QueryStatement<List<Session>> fetchSessionsOfServerFlat(UUID serverUUID) {
String sql = SELECT_SESSIONS_STATEMENT +
WHERE + SessionsTable.TABLE_NAME + '.' + SessionsTable.SERVER_UUID + "=?" +
ORDER_BY_SESSION_START_DESC;
return new QueryStatement<Map<UUID, List<Session>>>(sql, 50000) {
return new QueryStatement<List<Session>>(sql, 50000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public Map<UUID, List<Session>> processResults(ResultSet set) throws SQLException {
List<Session> sessions = extractDataFromSessionSelectStatement(set);
return SessionsMutator.sortByPlayers(sessions);
public List<Session> processResults(ResultSet set) throws SQLException {
return extractDataFromSessionSelectStatement(set);
}
};
}

View File

@ -93,7 +93,7 @@ public class ResponseHandler extends TreePageHandler {
}
registerPage("info", infoRequestPageHandler);
registerPage("json", rootJSONHandler);
registerPage("v1", rootJSONHandler);
}
public Response getResponse(Request request) {

View File

@ -0,0 +1,115 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.system.webserver.pages.json;
import com.djrapitops.plan.api.exceptions.WebUserAuthException;
import com.djrapitops.plan.api.exceptions.connection.BadRequestException;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.data.store.mutators.MutatorFunctions;
import com.djrapitops.plan.data.store.mutators.PlayersMutator;
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
import com.djrapitops.plan.data.store.mutators.TPSMutator;
import com.djrapitops.plan.db.Database;
import com.djrapitops.plan.db.access.queries.containers.ServerPlayerContainersQuery;
import com.djrapitops.plan.db.access.queries.objects.SessionQueries;
import com.djrapitops.plan.db.access.queries.objects.TPSQueries;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import com.djrapitops.plan.system.webserver.Request;
import com.djrapitops.plan.system.webserver.RequestTarget;
import com.djrapitops.plan.system.webserver.auth.Authentication;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.response.data.JSONResponse;
import com.djrapitops.plan.utilities.html.graphs.Graphs;
import com.djrapitops.plan.utilities.html.graphs.line.LineGraphFactory;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.TimeZone;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* JSON handler for different graph data JSON requests.
*
* @author Rsl1122
*/
@Singleton
public class GraphsJSONHandler extends ServerParameterJSONHandler {
private final Graphs graphs;
private final TimeZone timeZone;
@Inject
public GraphsJSONHandler(
PlanConfig config,
DBSystem dbSystem,
Graphs graphs
) {
super(dbSystem);
this.graphs = graphs;
this.timeZone = config.get(TimeSettings.USE_SERVER_TIME) ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT");
}
@Override
public Response getResponse(Request request, RequestTarget target) throws WebException {
UUID serverUUID = getServerUUID(target); // Can throw BadRequestException
String type = target.getParameter("type")
.orElseThrow(() -> new BadRequestException("'type' parameter was not defined."));
String graphDataJSON = generateGraphDataJSONOfType(type, serverUUID);
return new JSONResponse(graphDataJSON);
}
private String generateGraphDataJSONOfType(String type, UUID serverUUID) throws BadRequestException {
Database db = dbSystem.getDatabase();
LineGraphFactory lineGraphs = graphs.line();
switch (type) {
case "performance":
TPSMutator tpsMutator = new TPSMutator(db.query(TPSQueries.fetchTPSDataOfServer(serverUUID)))
.filterDataBetween(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(180L), System.currentTimeMillis());
return '{' +
"\"playersOnline\":" + lineGraphs.playersOnlineGraph(tpsMutator).toHighChartsSeries() +
",\"tps\":" + lineGraphs.tpsGraph(tpsMutator).toHighChartsSeries() +
",\"cpu\":" + lineGraphs.cpuGraph(tpsMutator).toHighChartsSeries() +
",\"ram\":" + lineGraphs.ramGraph(tpsMutator).toHighChartsSeries() +
",\"entities\":" + lineGraphs.entityGraph(tpsMutator).toHighChartsSeries() +
",\"chunks\":" + lineGraphs.chunkGraph(tpsMutator).toHighChartsSeries() +
",\"disk\":" + lineGraphs.diskGraph(tpsMutator).toHighChartsSeries() +
'}';
case "uniqueAndNew":
SessionsMutator sessionsMutator = new SessionsMutator(db.query(SessionQueries.fetchSessionsOfServerFlat(serverUUID)))
.filterSessionsBetween(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(180L), System.currentTimeMillis());
PlayersMutator playersMutator = new PlayersMutator(db.query(new ServerPlayerContainersQuery(serverUUID)))
.filterRegisteredBetween(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(180L), System.currentTimeMillis());
return "{\"uniquePlayers\":" +
lineGraphs.lineGraph(MutatorFunctions.toPointsWithRemovedOffset(sessionsMutator.uniqueJoinsPerDay(timeZone), timeZone)).toHighChartsSeries() +
",\"newPlayers\":" +
lineGraphs.lineGraph(MutatorFunctions.toPointsWithRemovedOffset(playersMutator.newPerDay(timeZone), timeZone)).toHighChartsSeries() +
'}';
default:
throw new BadRequestException("unknown 'type' parameter: " + type);
}
}
@Override
public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException {
return auth.getWebUser().getPermLevel() <= 0;
}
}

View File

@ -17,21 +17,16 @@
package com.djrapitops.plan.system.webserver.pages.json;
import com.djrapitops.plan.api.exceptions.WebUserAuthException;
import com.djrapitops.plan.api.exceptions.connection.BadRequestException;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.db.access.queries.objects.ServerQueries;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.webserver.Request;
import com.djrapitops.plan.system.webserver.RequestTarget;
import com.djrapitops.plan.system.webserver.auth.Authentication;
import com.djrapitops.plan.system.webserver.pages.PageHandler;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.response.data.JSONResponse;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.Optional;
import java.util.UUID;
/**
@ -41,9 +36,8 @@ import java.util.UUID;
* @see com.djrapitops.plan.utilities.html.tables.PlayersTableJSONParser For JSON parsing of /server players table.
*/
@Singleton
public class PlayersTableJSONHandler implements PageHandler {
public class PlayersTableJSONHandler extends ServerParameterJSONHandler {
private final DBSystem dbSystem;
private final JSONFactory jsonFactory;
@Inject
@ -51,8 +45,8 @@ public class PlayersTableJSONHandler implements PageHandler {
DBSystem dbSystem,
JSONFactory jsonFactory
) {
super(dbSystem);
this.jsonFactory = jsonFactory;
this.dbSystem = dbSystem;
}
@Override
@ -61,31 +55,6 @@ public class PlayersTableJSONHandler implements PageHandler {
return new JSONResponse(jsonFactory.serverPlayersTableJSON(serverUUID));
}
private UUID getServerUUID(RequestTarget target) throws BadRequestException {
Optional<String> serverUUID = target.getParameter("serverUUID");
if (serverUUID.isPresent()) {
return getServerUUIDDirectly(serverUUID.get());
} else {
return getServerUUIDFromName(target); // Preferred
}
}
private UUID getServerUUIDFromName(RequestTarget target) throws BadRequestException {
String serverName = target.getParameter("serverName")
.orElseThrow(() -> new BadRequestException("'serverName' parameter was not defined."));
return dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverName))
.map(Server::getUuid)
.orElseThrow(() -> new BadRequestException("'serverName' was not found in the database.: '" + serverName + "'"));
}
private UUID getServerUUIDDirectly(String serverUUIDString) throws BadRequestException {
try {
return UUID.fromString(serverUUIDString);
} catch (IllegalArgumentException malformedUUIDException) {
throw new BadRequestException("'serverName' was not a valid UUID: " + malformedUUIDException.getMessage());
}
}
@Override
public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException {
return auth.getWebUser().getPermLevel() <= 0;

View File

@ -36,11 +36,13 @@ public class RootJSONHandler extends TreePageHandler {
@Inject
public RootJSONHandler(
ResponseFactory responseFactory,
GraphsJSONHandler graphsJSONHandler,
PlayersTableJSONHandler playersTableJSONHandler
) {
super(responseFactory);
registerPage("players", playersTableJSONHandler);
registerPage("graph", graphsJSONHandler);
}
@Override

View File

@ -0,0 +1,66 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.system.webserver.pages.json;
import com.djrapitops.plan.api.exceptions.connection.BadRequestException;
import com.djrapitops.plan.db.access.queries.objects.ServerQueries;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.webserver.RequestTarget;
import com.djrapitops.plan.system.webserver.pages.PageHandler;
import java.util.Optional;
import java.util.UUID;
/**
* JSON handler for different graph data JSON requests.
*
* @author Rsl1122
*/
public abstract class ServerParameterJSONHandler implements PageHandler {
protected final DBSystem dbSystem;
protected ServerParameterJSONHandler(DBSystem dbSystem) {
this.dbSystem = dbSystem;
}
protected UUID getServerUUID(RequestTarget target) throws BadRequestException {
Optional<String> serverUUID = target.getParameter("serverUUID");
if (serverUUID.isPresent()) {
return getServerUUIDDirectly(serverUUID.get());
} else {
return getServerUUIDFromName(target); // Preferred
}
}
protected UUID getServerUUIDFromName(RequestTarget target) throws BadRequestException {
String serverName = target.getParameter("serverName")
.orElseThrow(() -> new BadRequestException("'serverName' parameter was not defined."));
return dbSystem.getDatabase().query(ServerQueries.fetchServerMatchingIdentifier(serverName))
.map(Server::getUuid)
.orElseThrow(() -> new BadRequestException("'serverName' was not found in the database.: '" + serverName + "'"));
}
protected UUID getServerUUIDDirectly(String serverUUIDString) throws BadRequestException {
try {
return UUID.fromString(serverUUIDString);
} catch (IllegalArgumentException malformedUUIDException) {
throw new BadRequestException("'serverName' was not a valid UUID: " + malformedUUIDException.getMessage());
}
}
}

View File

@ -12086,6 +12086,8 @@ a:focus {
position: relative;
height: 12rem;
width: 100%;
padding: 0.5rem;
text-align: center;
}
@media (min-width: 768px) {

View File

@ -4,27 +4,25 @@
* @param callback function with (json, error) parameters to call after the request.
*/
function jsonRequest(address, callback) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState === 4) {
try {
if (this.status === 200) {
var json = JSON.parse(this.responseText);
callback(json, null)
} else if (this.status === 404 || this.status === 403 || this.status === 500) {
callback(null, this.status)
}
} catch (e) {
callback(null, e.message)
}
}
};
xhttp.open("GET", address, true);
xhttp.send();
}
function asyncJsonRequest(address, callback) {
setTimeout(function () {
jsonRequest(address, callback)
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState === 4) {
try {
if (this.status === 200) {
var json = JSON.parse(this.responseText);
setTimeout(function () {
callback(json, null)
}, 0);
} else if (this.status === 404 || this.status === 403 || this.status === 500) {
callback(null, this.status)
}
} catch (e) {
callback(null, e.message)
}
}
};
xhttp.open("GET", address, true);
xhttp.send();
}, 0);
}

View File

@ -31,7 +31,7 @@
</script>
<div class="page-loader">
<span class="loader"></span>
<span class="loader-text">Please wait..</span>
<p class="loader-text">Please wait..</p>
</div>
<!-- Page Wrapper -->
@ -175,7 +175,7 @@
class="fas fa-fw fa-chart-area col-blue"></i>
Online Activity</h6>
</div>
<div class="chart-area" id="playerChartWeek"></div>
<div class="chart-area" id="playersOnlineChart"><span class="loader"></span></div>
</div>
</div>
@ -352,9 +352,7 @@
class="fas fa-fw fa-chart-area col-blue"></i>
New & Unique Players</h6>
</div>
<div class="chart-area">
<canvas id="myAreaChart2"></canvas>
</div>
<div class="chart-area" id="uniqueChart"><span class="loader"></span></div>
</div>
</div>
@ -368,7 +366,7 @@
Calendar</h6>
</div>
<div class="chart-area">
<canvas id="myAreaChart2"></canvas>
<span class="loader"></span>
</div>
</div>
</div>
@ -823,9 +821,7 @@
class="fas fa-fw fa-chart-line col-amber"></i>
Playerbase development</h6>
</div>
<div class="chart-area">
<canvas id="myAreaChart2"></canvas>
</div>
<div class="chart-area" id="playerBaseDevelopmentChart"></div>
</div>
</div>
@ -980,7 +976,11 @@
Player List</h6>
</div>
<div class="table-responsive">
<table class="table table-bordered table-striped table-hover player-table dataTable"></table>
<table class="table table-bordered table-striped table-hover player-table dataTable">
<tr>
<td>Loading..</td>
</tr>
</table>
</div>
</div>
</div>
@ -1014,7 +1014,7 @@
Geolocations</h6>
</div>
<div class="chart-area">
<canvas id="myAreaChart"></canvas>
<span class="loader"></span>
</div>
</div>
</div>
@ -1075,49 +1075,66 @@
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a aria-controls="home" aria-selected="true" class="nav-link active col-black"
data-toggle="tab" href="#all" id="home-tab" role="tab"><i
data-toggle="tab" href="#all" id="performance-all-tab" role="tab"><i
class="fa fa-fw fa-cogs col-blue-grey"></i> All</a>
</li>
<li class="nav-item">
<a aria-controls="profile" aria-selected="false" class="nav-link col-black"
data-toggle="tab"
href="#tps" id="profile-tab" role="tab"><i
href="#tps" id="performance-tps-tab" role="tab"><i
class="fa fa-fw fa-tachometer-alt col-blue-grey"></i> TPS</a>
</li>
<li class="nav-item">
<a aria-controls="contact" aria-selected="false" class="nav-link col-black"
data-toggle="tab" href="#cpuram" id="contact-tab"
data-toggle="tab" href="#cpuram" id="performance-hardware-tab"
role="tab"><i
class="fa fa-fw fa-microchip col-blue-grey"></i> CPU
& RAM</a>
</li>
<li class="nav-item">
<a aria-controls="contact" aria-selected="false" class="nav-link col-black"
data-toggle="tab" href="#worldload" id="contact-tab"
data-toggle="tab" href="#worldload" id="performance-minecraft-tab"
role="tab"><i class="fa fa-fw fa-map col-blue-grey"></i>
World
Load</a>
</li>
<li class="nav-item">
<a aria-controls="contact" aria-selected="false" class="nav-link col-black"
data-toggle="tab" href="#ping" id="contact-tab" role="tab"><i
data-toggle="tab" href="#ping" id="performance-ping-tab" role="tab"><i
class="fa fa-fw fa-signal col-blue-grey"></i> Ping</a>
</li>
<li class="nav-item">
<a aria-controls="contact" aria-selected="false" class="nav-link col-black"
data-toggle="tab" href="#ping" id="contact-tab" role="tab"><i
data-toggle="tab" href="#disk" id="performance-disk-tab" role="tab"><i
class="fa fa-fw fa-hdd col-blue-grey"></i> Disk Space</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div aria-labelledby="home-tab" class="tab-pane fade show active" id="all"
role="tabpanel">...
<div aria-labelledby="performance-all-tab" class="tab-pane fade show active"
id="all"
role="tabpanel">
<div class="chart-area" id="performanceGraph"><span class="loader"></span></div>
</div>
<div aria-labelledby="profile-tab" class="tab-pane fade" id="tps"
role="tabpanel">...
<div aria-labelledby="performance-tps-tab" class="tab-pane fade" id="tps"
role="tabpanel">
<div class="chart-area" id="tpsGraph"><span class="loader"></span></div>
</div>
<div aria-labelledby="contact-tab" class="tab-pane fade" id="cpuram"
role="tabpanel">...
<div aria-labelledby="performance-hardware-tab" class="tab-pane fade" id="cpuram"
role="tabpanel">
<div class="chart-area" id="resourceGraph"><span class="loader"></span></div>
</div>
<div aria-labelledby="performance-minecraft-tab" class="tab-pane fade"
id="worldload"
role="tabpanel">
<div class="chart-area" id="worldGraph"><span class="loader"></span></div>
</div>
<div aria-labelledby="performance-ping-tab" class="tab-pane fade" id="ping"
role="tabpanel">
<div class="chart-area" id="pingGraph"><span class="loader"></span></div>
</div>
<div aria-labelledby="performance-disk-tab" class="tab-pane fade" id="disk"
role="tabpanel">
<div class="chart-area" id="diskGraph"><span class="loader"></span></div>
</div>
</div>
</div>
@ -1494,6 +1511,20 @@
<!-- Page level custom scripts -->
<script src="js/server-values.js"></script>
<script src="js/charts/playerGraph.js"></script>
<script src="js/charts/punchCard.js"></script>
<script src="js/charts/healthGauge.js"></script>
<script src="js/charts/activityPie.js"></script>
<script src="js/charts/lineGraph.js"></script>
<script src="js/charts/stackGraph.js"></script>
<script src="js/charts/worldPie.js"></script>
<script src="js/charts/performanceGraph.js"></script>
<script src="js/charts/tpsGraph.js"></script>
<script src="js/charts/resourceGraph.js"></script>
<script src="js/charts/diskGraph.js"></script>
<script src="js/charts/worldGraph.js"></script>
<script src="js/charts/worldMap.js"></script>
<script src="js/charts/onlineActivityCalendar.js"></script>
<script src="js/charts/horizontalBarGraph.js"></script>
<script>
setLoadingText('Calculating values..');
@ -1831,9 +1862,6 @@
firstDay: ${firstDay}
},
data: {
playersOnline: ${playersOnlineSeries},
uniquePlayers: ${uniquePlayersSeries},
newPlayers: ${newPlayersSeries},
tps: ${tpsSeries},
cpu: ${cpuSeries},
ram: ${ramSeries},
@ -1908,20 +1936,141 @@
}]
}
};
var series = {
playersOnline: {
name: s.name.playersOnline,
type: s.type.areaSpline,
tooltip: s.tooltip.zeroDecimals,
data: v.data.playersOnline,
color: v.colors.playersOnline,
yAxis: 0
}
};
playersChart('playerChartWeek', series.playersOnline, 3);
jsonRequest("../v1/graph?type=performance&serverName=${serverName}", function (data, error) {
if (data) {
var series = {
playersOnline: {
name: s.name.playersOnline,
type: s.type.areaSpline,
tooltip: s.tooltip.zeroDecimals,
data: data.playersOnline,
color: v.colors.playersOnline,
yAxis: 0
},
tps: {
name: s.name.tps,
type: s.type.spline,
color: v.colors.tpsHigh,
zones: s.zones.tps,
tooltip: s.tooltip.twoDecimals,
data: data.tps,
yAxis: 1
},
cpu: {
name: s.name.cpu,
type: s.type.spline,
tooltip: s.tooltip.twoDecimals,
data: data.cpu,
color: v.colors.cpu,
yAxis: 2
},
cpu_alt: {
name: s.name.cpu,
type: s.type.spline,
tooltip: s.tooltip.twoDecimals,
data: data.cpu,
color: v.colors.cpu,
yAxis: 1
},
ram: {
name: s.name.ram,
type: s.type.spline,
tooltip: s.tooltip.zeroDecimals,
data: data.ram,
color: v.colors.ram,
yAxis: 3
},
ram_alt: {
name: s.name.ram,
type: s.type.spline,
tooltip: s.tooltip.zeroDecimals,
data: data.ram,
color: v.colors.ram,
yAxis: 2
},
entities: {
name: s.name.entities,
type: s.type.spline,
tooltip: s.tooltip.zeroDecimals,
data: data.entities,
color: v.colors.entities,
yAxis: 4
},
entities_alt: {
name: s.name.entities,
type: s.type.spline,
tooltip: s.tooltip.zeroDecimals,
data: data.entities,
color: v.colors.entities,
yAxis: 1
},
chunks: {
name: s.name.chunks,
type: s.type.spline,
tooltip: s.tooltip.zeroDecimals,
data: data.chunks,
color: v.colors.chunks,
yAxis: 5
},
chunks_alt: {
name: s.name.chunks,
type: s.type.spline,
tooltip: s.tooltip.zeroDecimals,
data: data.chunks,
color: v.colors.chunks,
yAxis: 2
},
disk: {
name: s.name.disk,
type: s.type.spline,
color: v.colors.tpsHigh,
zones: s.zones.disk,
tooltip: s.tooltip.zeroDecimals,
data: data.disk
}
};
playersChart('playersOnlineChart', series.playersOnline, 2);
performanceChart('performanceGraph', series.playersOnline, series.tps, series.cpu, series.ram, series.entities, series.chunks);
tpsChart('tpsGraph', series.tps, series.playersOnline);
resourceChart('resourceGraph', series.cpu_alt, series.ram_alt, series.playersOnline);
worldChart('worldGraph', series.entities_alt, series.chunks_alt, series.playersOnline);
diskChart('diskGraph', [series.disk]);
} else if (error) {
$('#playersOnlineChart').text("Failed to load graph data: " + error);
$('#performanceGraph').text("Failed to load graph data: " + error);
$('#tpsGraph').text("Failed to load graph data: " + error);
$('#resourceGraph').text("Failed to load graph data: " + error);
$('#worldGraph').text("Failed to load graph data: " + error);
$('#diskGraph').text("Failed to load graph data: " + error);
}
});
jsonRequest("../v1/graph?type=uniqueAndNew&serverName=${serverName}", function (data, error) {
if (data) {
var uniquePlayers = {
name: s.name.uniquePlayers,
type: s.type.spline,
tooltip: s.tooltip.zeroDecimals,
data: data.uniquePlayers,
color: v.colors.playersOnline
};
var newPlayers = {
name: s.name.newPlayers,
type: s.type.spline,
tooltip: s.tooltip.zeroDecimals,
data: data.newPlayers,
color: v.colors.newPlayers
};
lineChart('uniqueChart', [uniquePlayers, newPlayers]);
} else if (error) {
$('#uniqueChart').text("Failed to load graph data: " + error)
}
});
setLoadingText('Sorting players table..');
jsonRequest("../json/players?serverName=${serverName}", function (playersTableJson, error) {
jsonRequest("../v1/players?serverName=${serverName}", function (playersTableJson, error) {
if (playersTableJson) {
$('.player-table').DataTable({
responsive: true,