mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-02-22 07:12:09 +01:00
Added session aggregates to query results
This commit is contained in:
parent
8ee28e07dd
commit
c0e253d56d
@ -17,6 +17,7 @@
|
||||
package com.djrapitops.plan.delivery.webserver.resolver.json;
|
||||
|
||||
import com.djrapitops.plan.delivery.domain.DateMap;
|
||||
import com.djrapitops.plan.delivery.formatting.Formatter;
|
||||
import com.djrapitops.plan.delivery.formatting.Formatters;
|
||||
import com.djrapitops.plan.delivery.rendering.json.PlayersTableJSONCreator;
|
||||
import com.djrapitops.plan.delivery.rendering.json.graphs.GraphJSONCreator;
|
||||
@ -37,6 +38,7 @@ import com.djrapitops.plan.storage.database.queries.filter.Filter;
|
||||
import com.djrapitops.plan.storage.database.queries.filter.FilterQuery;
|
||||
import com.djrapitops.plan.storage.database.queries.filter.QueryFilters;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.GeoInfoQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.SessionQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.playertable.QueryTablePlayersQuery;
|
||||
import com.djrapitops.plan.storage.json.JSONStorage;
|
||||
import com.djrapitops.plan.utilities.java.Maps;
|
||||
@ -146,15 +148,27 @@ public class QueryJSONResolver implements Resolver {
|
||||
long after = dateFormat.parse(viewJSON.afterDate + " " + viewJSON.afterTime).getTime();
|
||||
long before = dateFormat.parse(viewJSON.beforeDate + " " + viewJSON.beforeTime).getTime();
|
||||
|
||||
Database database = dbSystem.getDatabase();
|
||||
|
||||
return Maps.builder(String.class, Object.class)
|
||||
.put("players", getPlayersTableData(playerUUIDs, after, before))
|
||||
.put("activity", getActivityGraphData(playerUUIDs, after, before))
|
||||
.put("geolocation", getGeolocationData(playerUUIDs))
|
||||
.put("sessions", getSessionSummaryData(playerUUIDs, after, before))
|
||||
.build();
|
||||
}
|
||||
|
||||
private Map<String, String> getSessionSummaryData(Set<UUID> playerUUIDs, long after, long before) {
|
||||
Database database = dbSystem.getDatabase();
|
||||
Map<String, Long> summary = database.query(SessionQueries.summaryOfPlayers(playerUUIDs, after, before));
|
||||
Map<String, String> formattedSummary = new HashMap<>();
|
||||
Formatter<Long> timeAmount = formatters.timeAmount();
|
||||
for (Map.Entry<String, Long> entry : summary.entrySet()) {
|
||||
formattedSummary.put(entry.getKey(), timeAmount.apply(entry.getValue()));
|
||||
}
|
||||
formattedSummary.put("total_sessions", Long.toString(summary.get("total_sessions")));
|
||||
formattedSummary.put("average_sessions", Long.toString(summary.get("average_sessions")));
|
||||
return formattedSummary;
|
||||
}
|
||||
|
||||
private Map<String, Object> getGeolocationData(Set<UUID> playerUUIDs) {
|
||||
Database database = dbSystem.getDatabase();
|
||||
return graphJSONCreator.createGeolocationJSON(
|
||||
|
@ -31,6 +31,7 @@ import com.djrapitops.plan.storage.database.sql.building.Sql;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.*;
|
||||
import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator;
|
||||
import com.djrapitops.plan.utilities.java.Maps;
|
||||
import org.apache.commons.text.TextStringBuilder;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
@ -836,4 +837,55 @@ public class SessionQueries {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Query<Map<String, Long>> summaryOfPlayers(Set<UUID> playerUUIDs, long after, long before) {
|
||||
String selectAggregates = SELECT +
|
||||
SessionsTable.USER_UUID + ',' +
|
||||
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime," +
|
||||
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME + ") as active_playtime," +
|
||||
"COUNT(1) as session_count" +
|
||||
FROM + SessionsTable.TABLE_NAME +
|
||||
WHERE + SessionsTable.SESSION_START + ">?" +
|
||||
AND + SessionsTable.SESSION_END + "<?" +
|
||||
AND + SessionsTable.USER_UUID + " IN ('" +
|
||||
new TextStringBuilder().appendWithSeparators(playerUUIDs, "','").build() + "')" +
|
||||
GROUP_BY + SessionsTable.USER_UUID;
|
||||
|
||||
String sql = SELECT +
|
||||
"SUM(playtime) as total_playtime," +
|
||||
"AVG(playtime) as average_playtime," +
|
||||
"SUM(active_playtime) as total_active_playtime," +
|
||||
"AVG(active_playtime) as average_active_playtime," +
|
||||
"SUM(playtime-active_playtime) as total_afk_playtime," +
|
||||
"AVG(playtime-active_playtime) as average_afk_playtime," +
|
||||
"AVG(playtime) as average_playtime," +
|
||||
"SUM(session_count) as total_sessions," +
|
||||
"AVG(session_count) as average_sessions" +
|
||||
FROM + "(" + selectAggregates + ") s";
|
||||
|
||||
return new QueryStatement<Map<String, Long>>(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setLong(1, after);
|
||||
statement.setLong(2, before);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Long> processResults(ResultSet set) throws SQLException {
|
||||
long sessionCount = set.getLong("total_sessions");
|
||||
long playtime = set.getLong("total_playtime");
|
||||
return Maps.builder(String.class, Long.class)
|
||||
.put("total_playtime", playtime)
|
||||
.put("average_playtime", set.getLong("average_playtime"))
|
||||
.put("total_afk_playtime", set.getLong("total_afk_playtime"))
|
||||
.put("average_afk_playtime", set.getLong("average_afk_playtime"))
|
||||
.put("total_active_playtime", set.getLong("total_active_playtime"))
|
||||
.put("average_active_playtime", set.getLong("average_active_playtime"))
|
||||
.put("total_sessions", sessionCount)
|
||||
.put("average_sessions", set.getLong("average_sessions"))
|
||||
.put("average_session_length", sessionCount != 0 ? playtime / sessionCount : -1L)
|
||||
.build();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -286,15 +286,6 @@ function runQuery() {
|
||||
<p class="loader-text">Loading..</p>
|
||||
</div>`;
|
||||
|
||||
const navButton = document.querySelector('.navbar-nav .nav-item');
|
||||
const element = document.createElement('li');
|
||||
element.classList.add("nav-item", "nav-button")
|
||||
element.innerHTML = `<a class="nav-link" href="./query">
|
||||
<i class="fas fa-fw fa-undo"></i>
|
||||
<span>Make another query</span>
|
||||
</a>`
|
||||
navButton.insertAdjacentElement('beforebegin', element);
|
||||
|
||||
jsonRequest(getQueryAddress(), function (json, error) {
|
||||
if (!json.data) {
|
||||
window.history.replaceState({}, '', `${location.pathname}?error=${error ? error : 'Query result expired'}`);
|
||||
@ -348,7 +339,17 @@ function runQuery() {
|
||||
worldMap('worldMap', geolocation_data.colors.low, geolocation_data.colors.high, geolocationSeries);
|
||||
horizontalBarChart('countryBarChart', geolocationBarCategories, [geolocationBarSeries], 'Players');
|
||||
|
||||
const session_data = json.data.sessions;
|
||||
|
||||
document.querySelector("#data_total_playtime").innerHTML = session_data.total_playtime;
|
||||
document.querySelector("#data_average_playtime").innerHTML = session_data.average_playtime;
|
||||
document.querySelector("#data_total_afk_playtime").innerHTML = session_data.total_afk_playtime;
|
||||
document.querySelector("#data_average_afk_playtime").innerHTML = session_data.average_afk_playtime;
|
||||
document.querySelector("#data_total_active_playtime").innerHTML = session_data.total_active_playtime;
|
||||
document.querySelector("#data_average_active_playtime").innerHTML = session_data.average_active_playtime;
|
||||
document.querySelector("#data_total_sessions").innerHTML = session_data.total_sessions;
|
||||
document.querySelector("#data_average_sessions").innerHTML = session_data.average_sessions;
|
||||
document.querySelector("#data_average_session_length").innerHTML = session_data.average_session_length;
|
||||
});
|
||||
}
|
||||
|
||||
@ -408,7 +409,37 @@ function renderDataResultScreen(resultCount, view) {
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12 col-lg-12 col-sm-12">
|
||||
<div class="col-xl-3 col-lg-3 col-sm-12">
|
||||
<div class="card shadow mb-4">
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold col-black"><i class="col-teal far fa-calendar"></i> Sessions within view</h6>
|
||||
</div>
|
||||
<div class="card-body" id="data_players">
|
||||
<p><i class="col-teal far fa-fw fa-calendar-check"></i> Sessions<span
|
||||
class="float-right"><b id="data_total_sessions"></b></span></p>
|
||||
<p><i class="col-teal far fa-fw fa-calendar-check"></i> Average Sessions / Player<span
|
||||
class="float-right"><b id="data_average_sessions"></b></span></p>
|
||||
<p><i class="col-teal far fa-fw fa-clock"></i> Average Session Length<span
|
||||
class="float-right" id="data_average_session_length"></span></p>
|
||||
<hr>
|
||||
<p><i class="col-green far fa-fw fa-clock"></i> Playtime<span
|
||||
class="float-right" id="data_total_playtime"></span></p>
|
||||
<p><i class="col-green far fa-fw fa-clock"></i> Active Playtime<span
|
||||
class="float-right" id="data_total_active_playtime"></span></p>
|
||||
<p><i class="col-grey far fa-fw fa-clock"></i> AFK Playtime<span
|
||||
class="float-right" id="data_total_afk_playtime"></span></p>
|
||||
<hr>
|
||||
<p><i class="col-green far fa-fw fa-clock"></i> Average Playtime / Player<span
|
||||
class="float-right" id="data_average_playtime"></span></p>
|
||||
<p><i class="col-green far fa-fw fa-clock"></i> Average Active Playtime / Player<span
|
||||
class="float-right" id="data_average_active_playtime"></span></p>
|
||||
<p><i class="col-grey far fa-fw fa-clock"></i> Average AFK Playtime / Player<span
|
||||
class="float-right" id="data_average_afk_playtime"></span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-9 col-lg-9 col-sm-12">
|
||||
<div class="card shadow mb-4">
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold col-black"><i
|
||||
|
@ -39,6 +39,12 @@
|
||||
<hr class="sidebar-divider my-0">
|
||||
|
||||
<li class="nav-item nav-button active">
|
||||
<a class="nav-link" href="./query">
|
||||
<i class="fas fa-fw fa-undo"></i>
|
||||
<span>Make another query</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item nav-button">
|
||||
<a class="nav-link" href="/">
|
||||
<i class="far fa-fw fa-hand-point-left"></i>
|
||||
<span>to main page</span></a>
|
||||
|
Loading…
Reference in New Issue
Block a user